[PATCH v5 09/12] drm/virtio: rework virtio_gpu_object_create fencing

Chia-I Wu olvaffe at gmail.com
Tue Jul 2 02:43:15 UTC 2019


On Mon, Jul 1, 2019 at 11:04 AM Gurchetan Singh
<gurchetansingh at chromium.org> wrote:
>
>
>
> On Fri, Jun 28, 2019 at 5:14 AM Gerd Hoffmann <kraxel at redhat.com> wrote:
> >
> > Use gem reservation helpers and direct reservation_object_* calls
> > instead of ttm.
> >
> > v5: fix fencing (Chia-I Wu).
> > v3: Due to using the gem reservation object it is initialized and ready
> > for use before calling ttm_bo_init, so we can also drop the tricky fence
> > logic which checks whenever the command is in flight still.  We can
> > simply fence our object before submitting the virtio command and be done
> > with it.
> >
> > Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
> > Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> > ---
> >  drivers/gpu/drm/virtio/virtgpu_drv.h    |  2 +
> >  drivers/gpu/drm/virtio/virtgpu_object.c | 55 ++++++++++---------------
> >  drivers/gpu/drm/virtio/virtgpu_vq.c     |  4 ++
> >  3 files changed, 27 insertions(+), 34 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
> > index 356d27132388..c4b266b6f731 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> > @@ -267,6 +267,7 @@ void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);
> >  void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
> >                                     struct virtio_gpu_object *bo,
> >                                     struct virtio_gpu_object_params *params,
> > +                                   struct virtio_gpu_object_array *objs,
> >                                     struct virtio_gpu_fence *fence);
> >  void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
> >                                    uint32_t resource_id);
> > @@ -329,6 +330,7 @@ void
> >  virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
> >                                   struct virtio_gpu_object *bo,
> >                                   struct virtio_gpu_object_params *params,
> > +                                 struct virtio_gpu_object_array *objs,
> >                                   struct virtio_gpu_fence *fence);
> >  void virtio_gpu_ctrl_ack(struct virtqueue *vq);
> >  void virtio_gpu_cursor_ack(struct virtqueue *vq);
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
> > index 82bfbf983fd2..fa0ea22c68b0 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_object.c
> > +++ b/drivers/gpu/drm/virtio/virtgpu_object.c
> > @@ -97,7 +97,9 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
> >                              struct virtio_gpu_object **bo_ptr,
> >                              struct virtio_gpu_fence *fence)
> >  {
> > +       struct virtio_gpu_object_array *objs = NULL;
> >         struct virtio_gpu_object *bo;
> > +       struct ww_acquire_ctx ticket;
> >         size_t acc_size;
> >         int ret;
> >
> > @@ -123,12 +125,29 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
> >         }
> >         bo->dumb = params->dumb;
> >
> > +       if (fence) {
> > +               objs = virtio_gpu_array_alloc(1);
> > +               objs->objs[0] = &bo->gem_base;
> > +               drm_gem_object_get(objs->objs[0]);
>
> 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}?
Yeah, I had the same question in another thread.
>
> 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?
virtio_gpu_gem_object_close is called when this process (this
drm_file) does not need the object.  It is fine if there are still
pending operations.

virtio_gpu_free_object is called when the last reference is gone.  It
should be a critical error if there are still pending operations.

>
> > +
> > +               ret = drm_gem_lock_reservations(objs->objs, objs->nents,
> > +                                               &ticket);
> > +               if (ret == 0)
> > +                       reservation_object_add_excl_fence(objs->objs[0]->resv,
> > +                                                         &fence->f);
> > +       }
> > +
> >         if (params->virgl) {
> > -               virtio_gpu_cmd_resource_create_3d(vgdev, bo, params, fence);
> > +               virtio_gpu_cmd_resource_create_3d(vgdev, bo, params,
> > +                                                 objs, fence);
> >         } else {
> > -               virtio_gpu_cmd_create_resource(vgdev, bo, params, fence);
> > +               virtio_gpu_cmd_create_resource(vgdev, bo, params,
> > +                                              objs, fence);
> >         }
> >
> > +       if (fence)
> > +               drm_gem_unlock_reservations(objs->objs, objs->nents, &ticket);
> > +
> >         virtio_gpu_init_ttm_placement(bo);
> >         ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, params->size,
> >                           ttm_bo_type_device, &bo->placement, 0,
> > @@ -139,38 +158,6 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
> >         if (ret != 0)
> >                 return ret;
> >
> > -       if (fence) {
> > -               struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv;
> > -               struct list_head validate_list;
> > -               struct ttm_validate_buffer mainbuf;
> > -               struct ww_acquire_ctx ticket;
> > -               unsigned long irq_flags;
> > -               bool signaled;
> > -
> > -               INIT_LIST_HEAD(&validate_list);
> > -               memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer));
> > -
> > -               /* use a gem reference since unref list undoes them */
> > -               drm_gem_object_get(&bo->gem_base);
> > -               mainbuf.bo = &bo->tbo;
> > -               list_add(&mainbuf.head, &validate_list);
> > -
> > -               ret = virtio_gpu_object_list_validate(&ticket, &validate_list);
> > -               if (ret == 0) {
> > -                       spin_lock_irqsave(&drv->lock, irq_flags);
> > -                       signaled = virtio_fence_signaled(&fence->f);
> > -                       if (!signaled)
> > -                               /* virtio create command still in flight */
> > -                               ttm_eu_fence_buffer_objects(&ticket, &validate_list,
> > -                                                           &fence->f);
> > -                       spin_unlock_irqrestore(&drv->lock, irq_flags);
> > -                       if (signaled)
> > -                               /* virtio create command finished */
> > -                               ttm_eu_backoff_reservation(&ticket, &validate_list);
> > -               }
> > -               virtio_gpu_unref_list(&validate_list);
> > -       }
> > -
> >         *bo_ptr = bo;
> >         return 0;
> >  }
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
> > index 0c87c3e086f8..0a735e51a803 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_vq.c
> > +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
> > @@ -391,6 +391,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev,
> >  void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
> >                                     struct virtio_gpu_object *bo,
> >                                     struct virtio_gpu_object_params *params,
> > +                                   struct virtio_gpu_object_array *objs,
> >                                     struct virtio_gpu_fence *fence)
> >  {
> >         struct virtio_gpu_resource_create_2d *cmd_p;
> > @@ -398,6 +399,7 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
> >
> >         cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
> >         memset(cmd_p, 0, sizeof(*cmd_p));
> > +       vbuf->objs = objs;
> >
> >         cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_2D);
> >         cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
> > @@ -864,6 +866,7 @@ void
> >  virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
> >                                   struct virtio_gpu_object *bo,
> >                                   struct virtio_gpu_object_params *params,
> > +                                 struct virtio_gpu_object_array *objs,
> >                                   struct virtio_gpu_fence *fence)
> >  {
> >         struct virtio_gpu_resource_create_3d *cmd_p;
> > @@ -871,6 +874,7 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev,
> >
> >         cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
> >         memset(cmd_p, 0, sizeof(*cmd_p));
> > +       vbuf->objs = objs;
> >
> >         cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_3D);
> >         cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
> > --
> > 2.18.1
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list