<div dir="ltr"><br><br>On Fri, Jun 28, 2019 at 5:14 AM Gerd Hoffmann <<a href="mailto:kraxel@redhat.com">kraxel@redhat.com</a>> wrote:<br>><br>> Use gem reservation helpers and direct reservation_object_* calls<br>> instead of ttm.<br>><br>> v5: fix fencing (Chia-I Wu).<br>> v3: Due to using the gem reservation object it is initialized and ready<br>> for use before calling ttm_bo_init, so we can also drop the tricky fence<br>> logic which checks whenever the command is in flight still.  We can<br>> simply fence our object before submitting the virtio command and be done<br>> with it.<br>><br>> Signed-off-by: Gerd Hoffmann <<a href="mailto:kraxel@redhat.com">kraxel@redhat.com</a>><br>> Acked-by: Daniel Vetter <<a href="mailto:daniel.vetter@ffwll.ch">daniel.vetter@ffwll.ch</a>><br>> ---<br>>  drivers/gpu/drm/virtio/virtgpu_drv.h    |  2 +<br>>  drivers/gpu/drm/virtio/virtgpu_object.c | 55 ++++++++++---------------<br>>  drivers/gpu/drm/virtio/virtgpu_vq.c     |  4 ++<br>>  3 files changed, 27 insertions(+), 34 deletions(-)<br>><br>> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h<br>> index 356d27132388..c4b266b6f731 100644<br>> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h<br>> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h<br>> @@ -267,6 +267,7 @@ void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);<br>>  void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,<br>>                                     struct virtio_gpu_object *bo,<br>>                                     struct virtio_gpu_object_params *params,<br>> +                                   struct virtio_gpu_object_array *objs,<br>>                                     struct virtio_gpu_fence *fence);<br>>  void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,<br>>                                    uint32_t resource_id);<br>> @@ -329,6 +330,7 @@ void<br>>  virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,<br>>                                   struct virtio_gpu_object *bo,<br>>                                   struct virtio_gpu_object_params *params,<br>> +                                 struct virtio_gpu_object_array *objs,<br>>                                   struct virtio_gpu_fence *fence);<br>>  void virtio_gpu_ctrl_ack(struct virtqueue *vq);<br>>  void virtio_gpu_cursor_ack(struct virtqueue *vq);<br>> diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c<br>> index 82bfbf983fd2..fa0ea22c68b0 100644<br>> --- a/drivers/gpu/drm/virtio/virtgpu_object.c<br>> +++ b/drivers/gpu/drm/virtio/virtgpu_object.c<br>> @@ -97,7 +97,9 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,<br>>                              struct virtio_gpu_object **bo_ptr,<br>>                              struct virtio_gpu_fence *fence)<br>>  {<br>> +       struct virtio_gpu_object_array *objs = NULL;<br>>         struct virtio_gpu_object *bo;<br>> +       struct ww_acquire_ctx ticket;<br>>         size_t acc_size;<br>>         int ret;<br>><br>> @@ -123,12 +125,29 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,<br>>         }<br>>         bo->dumb = params->dumb;<br>><br>> +       if (fence) {<br>> +               objs = virtio_gpu_array_alloc(1);<br>> +               objs->objs[0] = &bo->gem_base;<br>> +               drm_gem_object_get(objs->objs[0]);<br><br>So we take a reference every-time create/submit_cmd are fenced?  Why don't we take a reference during {virtio_gpu_cmd_transfer_from_host_3d, virtio_gpu_transfer_to_host_ioctl}?<br><br>Does the GEM common code wait on the reservation object before calling virtio_gpu_gem_object_close?  If not, would it make sense to wait on the reservation object with MAX_SCHEDULE_TIMEOUT in virtio_gpu_free_object?<br><br>> +<br>> +               ret = drm_gem_lock_reservations(objs->objs, objs->nents,<br>> +                                               &ticket);<br>> +               if (ret == 0)<br>> +                       reservation_object_add_excl_fence(objs->objs[0]->resv,<br>> +                                                         &fence->f);<br>> +       }<br>> +<br>>         if (params->virgl) {<br>> -               virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, fence);<br>> +               virtio_gpu_cmd_resource_create_3d(vgdev, bo, params,<br>> +                                                 objs, fence);<br>>         } else {<br>> -               virtio_gpu_cmd_create_resource(vgdev, bo, params, fence);<br>> +               virtio_gpu_cmd_create_resource(vgdev, bo, params,<br>> +                                              objs, fence);<br>>         }<br>><br>> +       if (fence)<br>> +               drm_gem_unlock_reservations(objs->objs, objs->nents, &ticket);<br>> +<br>>         virtio_gpu_init_ttm_placement(bo);<br>>         ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, params->size,<br>>                           ttm_bo_type_device, &bo->placement, 0,<br>> @@ -139,38 +158,6 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,<br>>         if (ret != 0)<br>>                 return ret;<br>><br>> -       if (fence) {<br>> -               struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv;<br>> -               struct list_head validate_list;<br>> -               struct ttm_validate_buffer mainbuf;<br>> -               struct ww_acquire_ctx ticket;<br>> -               unsigned long irq_flags;<br>> -               bool signaled;<br>> -<br>> -               INIT_LIST_HEAD(&validate_list);<br>> -               memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer));<br>> -<br>> -               /* use a gem reference since unref list undoes them */<br>> -               drm_gem_object_get(&bo->gem_base);<br>> -               <a href="http://mainbuf.bo">mainbuf.bo</a> = &bo->tbo;<br>> -               list_add(&mainbuf.head, &validate_list);<br>> -<br>> -               ret = virtio_gpu_object_list_validate(&ticket, &validate_list);<br>> -               if (ret == 0) {<br>> -                       spin_lock_irqsave(&drv->lock, irq_flags);<br>> -                       signaled = virtio_fence_signaled(&fence->f);<br>> -                       if (!signaled)<br>> -                               /* virtio create command still in flight */<br>> -                               ttm_eu_fence_buffer_objects(&ticket, &validate_list,<br>> -                                                           &fence->f);<br>> -                       spin_unlock_irqrestore(&drv->lock, irq_flags);<br>> -                       if (signaled)<br>> -                               /* virtio create command finished */<br>> -                               ttm_eu_backoff_reservation(&ticket, &validate_list);<br>> -               }<br>> -               virtio_gpu_unref_list(&validate_list);<br>> -       }<br>> -<br>>         *bo_ptr = bo;<br>>         return 0;<br>>  }<br>> diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c<br>> index 0c87c3e086f8..0a735e51a803 100644<br>> --- a/drivers/gpu/drm/virtio/virtgpu_vq.c<br>> +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c<br>> @@ -391,6 +391,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev,<br>>  void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,<br>>                                     struct virtio_gpu_object *bo,<br>>                                     struct virtio_gpu_object_params *params,<br>> +                                   struct virtio_gpu_object_array *objs,<br>>                                     struct virtio_gpu_fence *fence)<br>>  {<br>>         struct virtio_gpu_resource_create_2d *cmd_p;<br>> @@ -398,6 +399,7 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,<br>><br>>         cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));<br>>         memset(cmd_p, 0, sizeof(*cmd_p));<br>> +       vbuf->objs = objs;<br>><br>>         cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_2D);<br>>         cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);<br>> @@ -864,6 +866,7 @@ void<br>>  virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,<br>>                                   struct virtio_gpu_object *bo,<br>>                                   struct virtio_gpu_object_params *params,<br>> +                                 struct virtio_gpu_object_array *objs,<br>>                                   struct virtio_gpu_fence *fence)<br>>  {<br>>         struct virtio_gpu_resource_create_3d *cmd_p;<br>> @@ -871,6 +874,7 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,<br>><br>>         cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));<br>>         memset(cmd_p, 0, sizeof(*cmd_p));<br>> +       vbuf->objs = objs;<br>><br>>         cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_3D);<br>>         cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);<br>> --<br>> 2.18.1<br>><br>> _______________________________________________<br>> dri-devel mailing list<br>> <a href="mailto:dri-devel@lists.freedesktop.org">dri-devel@lists.freedesktop.org</a><br>> <a href="https://lists.freedesktop.org/mailman/listinfo/dri-devel">https://lists.freedesktop.org/mailman/listinfo/dri-devel</a></div>