diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index af9403e1cf7884042cd3fe1f9266fe85d55236fd..2f6c4ccbfd14581508adfc338fe5bd12b8b2abcd 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -179,8 +179,7 @@ struct virtio_gpu_device { struct virtio_gpu_queue cursorq; struct kmem_cache *vbufs; - bool disable_notify; - bool pending_notify; + atomic_t pending_commands; struct ida resource_ida; @@ -335,8 +334,7 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); void virtio_gpu_dequeue_cursor_func(struct work_struct *work); void virtio_gpu_dequeue_fence_func(struct work_struct *work); -void virtio_gpu_disable_notify(struct virtio_gpu_device *vgdev); -void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev); +void virtio_gpu_notify(struct virtio_gpu_device *vgdev); /* virtio_gpu_display.c */ void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index d1c3f5fbfee4a65e6f33aa7f1f8ac8ef5ee0ed59..08b2e4127eb3f9d9227b1e17f82c9a93361e20c3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -154,8 +154,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, if (!drm_atomic_helper_damage_merged(old_state, plane->state, &rect)) return; - virtio_gpu_disable_notify(vgdev); - bo = gem_to_virtio_gpu_obj(plane->state->fb->obj[0]); if (bo->dumb) virtio_gpu_update_dumb_bo(vgdev, plane->state, &rect); @@ -186,8 +184,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1); - - virtio_gpu_enable_notify(vgdev); } static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 67caecde623eae981c5e10e267ae15a78d0297eb..6cc259cfa517a87c808e939d646fcd79c25b2696 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -329,7 +329,6 @@ static void virtio_gpu_queue_ctrl_sgs(struct virtio_gpu_device *vgdev, int incnt) { struct virtqueue *vq = vgdev->ctrlq.vq; - bool notify = false; int ret, idx; if (!drm_dev_enter(vgdev->ddev, &idx)) { @@ -368,16 +367,10 @@ static void virtio_gpu_queue_ctrl_sgs(struct virtio_gpu_device *vgdev, trace_virtio_gpu_cmd_queue(vq, virtio_gpu_vbuf_ctrl_hdr(vbuf)); - notify = virtqueue_kick_prepare(vq); + atomic_inc(&vgdev->pending_commands); spin_unlock(&vgdev->ctrlq.qlock); - if (notify) { - if (vgdev->disable_notify) - vgdev->pending_notify = true; - else - virtqueue_notify(vq); - } drm_dev_exit(idx); } @@ -434,19 +427,20 @@ static void virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, } } -void virtio_gpu_disable_notify(struct virtio_gpu_device *vgdev) -{ - vgdev->disable_notify = true; -} - -void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev) +void virtio_gpu_notify(struct virtio_gpu_device *vgdev) { - vgdev->disable_notify = false; + bool notify; - if (!vgdev->pending_notify) + if (!atomic_read(&vgdev->pending_commands)) return; - vgdev->pending_notify = false; - virtqueue_notify(vgdev->ctrlq.vq); + + spin_lock(&vgdev->ctrlq.qlock); + atomic_set(&vgdev->pending_commands, 0); + notify = virtqueue_kick_prepare(vgdev->ctrlq.vq); + spin_unlock(&vgdev->ctrlq.qlock); + + if (notify) + virtqueue_notify(vgdev->ctrlq.vq); } static void virtio_gpu_queue_ctrl_buffer(struct virtio_gpu_device *vgdev, @@ -520,6 +514,7 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, cmd_p->height = cpu_to_le32(params->height); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); bo->created = true; } @@ -549,6 +544,7 @@ void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, vbuf->resp_cb_data = bo; virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, @@ -571,6 +567,7 @@ void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, cmd_p->r.y = cpu_to_le32(y); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, @@ -592,6 +589,7 @@ void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, cmd_p->r.y = cpu_to_le32(y); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, @@ -624,6 +622,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, cmd_p->r.y = cpu_to_le32(y); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); } static void @@ -647,6 +646,7 @@ virtio_gpu_cmd_resource_attach_backing(struct virtio_gpu_device *vgdev, vbuf->data_size = sizeof(*ents) * nents; virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); } static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, @@ -779,6 +779,7 @@ int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) vgdev->display_info_pending = true; cmd_p->type = cpu_to_le32(VIRTIO_GPU_CMD_GET_DISPLAY_INFO); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); return 0; } @@ -802,6 +803,7 @@ int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx) cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_CAPSET_INFO); cmd_p->capset_index = cpu_to_le32(idx); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); return 0; } @@ -877,6 +879,7 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, cmd_p->capset_version = cpu_to_le32(version); *cache_p = cache_ent; virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); return 0; } @@ -904,6 +907,7 @@ int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev) cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_EDID); cmd_p->scanout = cpu_to_le32(scanout); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } return 0; @@ -924,6 +928,7 @@ void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, strncpy(cmd_p->debug_name, name, sizeof(cmd_p->debug_name) - 1); cmd_p->debug_name[sizeof(cmd_p->debug_name) - 1] = 0; virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev, @@ -938,6 +943,7 @@ void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev, cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_CTX_DESTROY); cmd_p->hdr.ctx_id = cpu_to_le32(id); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_context_attach_resource(struct virtio_gpu_device *vgdev, @@ -956,7 +962,7 @@ void virtio_gpu_cmd_context_attach_resource(struct virtio_gpu_device *vgdev, cmd_p->hdr.ctx_id = cpu_to_le32(ctx_id); cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); - + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, @@ -975,6 +981,7 @@ void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, cmd_p->hdr.ctx_id = cpu_to_le32(ctx_id); cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); + virtio_gpu_notify(vgdev); } void @@ -1006,6 +1013,8 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, cmd_p->flags = cpu_to_le32(params->flags); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); + bo->created = true; } @@ -1039,6 +1048,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, cmd_p->level = cpu_to_le32(level); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, @@ -1065,6 +1075,7 @@ void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev, cmd_p->level = cpu_to_le32(level); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); } void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev, @@ -1088,6 +1099,7 @@ void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev, cmd_p->size = cpu_to_le32(data_size); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); + virtio_gpu_notify(vgdev); } int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,