Commit cca41da1 authored by Gerd Hoffmann's avatar Gerd Hoffmann

drm/virtio: rework notification for better batching

Drop the virtio_gpu_{disable,enable}_notify().  Add a new
virtio_gpu_notify() call instead, which must be called whenever
the driver wants make sure the host is notified needed.

Drop automatic notification from command submission.  Add
virtio_gpu_notify() calls after each command query instead.
This allows more fine-grained control over host notification
and can move around the notify calls in subsequent patches to
batch command submissions. With this in place it is also
possible to make notification optional for userspace ioctls.

Page flip batching goes away (temporarely).

v3:
 - move batching to separate patches.
v2:
 - rebase to latest drm-misc-next.
 - use "if (!atomic_read())".
 - add review & test tags.
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Reviewed-by: default avatarGurchetan Singh <gurchetansingh@chromium.org>
Tested-by: default avatarGurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: default avatarChia-I Wu <olvaffe@gmail.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20200214125535.26349-2-kraxel@redhat.com
parent 28f2aff1
...@@ -179,8 +179,7 @@ struct virtio_gpu_device { ...@@ -179,8 +179,7 @@ struct virtio_gpu_device {
struct virtio_gpu_queue cursorq; struct virtio_gpu_queue cursorq;
struct kmem_cache *vbufs; struct kmem_cache *vbufs;
bool disable_notify; atomic_t pending_commands;
bool pending_notify;
struct ida resource_ida; struct ida resource_ida;
...@@ -335,8 +334,7 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); ...@@ -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_cursor_func(struct work_struct *work);
void virtio_gpu_dequeue_fence_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_notify(struct virtio_gpu_device *vgdev);
void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev);
/* virtio_gpu_display.c */ /* virtio_gpu_display.c */
void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
......
...@@ -154,8 +154,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, ...@@ -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)) if (!drm_atomic_helper_damage_merged(old_state, plane->state, &rect))
return; return;
virtio_gpu_disable_notify(vgdev);
bo = gem_to_virtio_gpu_obj(plane->state->fb->obj[0]); bo = gem_to_virtio_gpu_obj(plane->state->fb->obj[0]);
if (bo->dumb) if (bo->dumb)
virtio_gpu_update_dumb_bo(vgdev, plane->state, &rect); virtio_gpu_update_dumb_bo(vgdev, plane->state, &rect);
...@@ -186,8 +184,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, ...@@ -186,8 +184,6 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
rect.y1, rect.y1,
rect.x2 - rect.x1, rect.x2 - rect.x1,
rect.y2 - rect.y1); rect.y2 - rect.y1);
virtio_gpu_enable_notify(vgdev);
} }
static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
......
...@@ -329,7 +329,6 @@ static void virtio_gpu_queue_ctrl_sgs(struct virtio_gpu_device *vgdev, ...@@ -329,7 +329,6 @@ static void virtio_gpu_queue_ctrl_sgs(struct virtio_gpu_device *vgdev,
int incnt) int incnt)
{ {
struct virtqueue *vq = vgdev->ctrlq.vq; struct virtqueue *vq = vgdev->ctrlq.vq;
bool notify = false;
int ret, idx; int ret, idx;
if (!drm_dev_enter(vgdev->ddev, &idx)) { if (!drm_dev_enter(vgdev->ddev, &idx)) {
...@@ -368,16 +367,10 @@ static void virtio_gpu_queue_ctrl_sgs(struct virtio_gpu_device *vgdev, ...@@ -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)); 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); spin_unlock(&vgdev->ctrlq.qlock);
if (notify) {
if (vgdev->disable_notify)
vgdev->pending_notify = true;
else
virtqueue_notify(vq);
}
drm_dev_exit(idx); drm_dev_exit(idx);
} }
...@@ -434,18 +427,19 @@ static void virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev, ...@@ -434,18 +427,19 @@ static void virtio_gpu_queue_fenced_ctrl_buffer(struct virtio_gpu_device *vgdev,
} }
} }
void virtio_gpu_disable_notify(struct virtio_gpu_device *vgdev) void virtio_gpu_notify(struct virtio_gpu_device *vgdev)
{ {
vgdev->disable_notify = true; bool notify;
}
void virtio_gpu_enable_notify(struct virtio_gpu_device *vgdev)
{
vgdev->disable_notify = false;
if (!vgdev->pending_notify) if (!atomic_read(&vgdev->pending_commands))
return; return;
vgdev->pending_notify = false;
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); virtqueue_notify(vgdev->ctrlq.vq);
} }
...@@ -520,6 +514,7 @@ void virtio_gpu_cmd_create_resource(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); cmd_p->height = cpu_to_le32(params->height);
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
virtio_gpu_notify(vgdev);
bo->created = true; bo->created = true;
} }
...@@ -549,6 +544,7 @@ void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, ...@@ -549,6 +544,7 @@ void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
vbuf->resp_cb_data = bo; vbuf->resp_cb_data = bo;
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *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, ...@@ -571,6 +567,7 @@ void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev,
cmd_p->r.y = cpu_to_le32(y); cmd_p->r.y = cpu_to_le32(y);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *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, ...@@ -592,6 +589,7 @@ void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev,
cmd_p->r.y = cpu_to_le32(y); cmd_p->r.y = cpu_to_le32(y);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *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, ...@@ -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); cmd_p->r.y = cpu_to_le32(y);
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
virtio_gpu_notify(vgdev);
} }
static void static void
...@@ -647,6 +646,7 @@ virtio_gpu_cmd_resource_attach_backing(struct virtio_gpu_device *vgdev, ...@@ -647,6 +646,7 @@ virtio_gpu_cmd_resource_attach_backing(struct virtio_gpu_device *vgdev,
vbuf->data_size = sizeof(*ents) * nents; vbuf->data_size = sizeof(*ents) * nents;
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); 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, 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) ...@@ -779,6 +779,7 @@ int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev)
vgdev->display_info_pending = true; vgdev->display_info_pending = true;
cmd_p->type = cpu_to_le32(VIRTIO_GPU_CMD_GET_DISPLAY_INFO); cmd_p->type = cpu_to_le32(VIRTIO_GPU_CMD_GET_DISPLAY_INFO);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
return 0; return 0;
} }
...@@ -802,6 +803,7 @@ int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx) ...@@ -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->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_CAPSET_INFO);
cmd_p->capset_index = cpu_to_le32(idx); cmd_p->capset_index = cpu_to_le32(idx);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
return 0; return 0;
} }
...@@ -877,6 +879,7 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, ...@@ -877,6 +879,7 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev,
cmd_p->capset_version = cpu_to_le32(version); cmd_p->capset_version = cpu_to_le32(version);
*cache_p = cache_ent; *cache_p = cache_ent;
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
return 0; return 0;
} }
...@@ -904,6 +907,7 @@ int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev) ...@@ -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->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_GET_EDID);
cmd_p->scanout = cpu_to_le32(scanout); cmd_p->scanout = cpu_to_le32(scanout);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
return 0; return 0;
...@@ -924,6 +928,7 @@ void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, ...@@ -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); strncpy(cmd_p->debug_name, name, sizeof(cmd_p->debug_name) - 1);
cmd_p->debug_name[sizeof(cmd_p->debug_name) - 1] = 0; cmd_p->debug_name[sizeof(cmd_p->debug_name) - 1] = 0;
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *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, ...@@ -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.type = cpu_to_le32(VIRTIO_GPU_CMD_CTX_DESTROY);
cmd_p->hdr.ctx_id = cpu_to_le32(id); cmd_p->hdr.ctx_id = cpu_to_le32(id);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_context_attach_resource(struct virtio_gpu_device *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, ...@@ -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->hdr.ctx_id = cpu_to_le32(ctx_id);
cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *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, ...@@ -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->hdr.ctx_id = cpu_to_le32(ctx_id);
cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
virtio_gpu_notify(vgdev);
} }
void void
...@@ -1006,6 +1013,8 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, ...@@ -1006,6 +1013,8 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
cmd_p->flags = cpu_to_le32(params->flags); cmd_p->flags = cpu_to_le32(params->flags);
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
virtio_gpu_notify(vgdev);
bo->created = true; bo->created = true;
} }
...@@ -1039,6 +1048,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, ...@@ -1039,6 +1048,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
cmd_p->level = cpu_to_le32(level); cmd_p->level = cpu_to_le32(level);
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); 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, 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, ...@@ -1065,6 +1075,7 @@ void virtio_gpu_cmd_transfer_from_host_3d(struct virtio_gpu_device *vgdev,
cmd_p->level = cpu_to_le32(level); cmd_p->level = cpu_to_le32(level);
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
virtio_gpu_notify(vgdev);
} }
void virtio_gpu_cmd_submit(struct virtio_gpu_device *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, ...@@ -1088,6 +1099,7 @@ void virtio_gpu_cmd_submit(struct virtio_gpu_device *vgdev,
cmd_p->size = cpu_to_le32(data_size); cmd_p->size = cpu_to_le32(data_size);
virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence); virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, fence);
virtio_gpu_notify(vgdev);
} }
int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment