From: Danilo Krummrich <dakr@redhat.com>
To: "Christian König" <christian.koenig@amd.com>
Cc: airlied@gmail.com, daniel@ffwll.ch, matthew.brost@intel.com,
thomas.hellstrom@linux.intel.com, sarah.walker@imgtec.com,
donald.robson@imgtec.com, boris.brezillon@collabora.com,
faith@gfxstrand.net, dri-devel@lists.freedesktop.org,
nouveau@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH drm-misc-next v8 09/12] drm/gpuvm: reference count drm_gpuvm structures
Date: Fri, 3 Nov 2023 14:14:01 +0100 [thread overview]
Message-ID: <ZUTyGTxcH7WlHKsv@pollux> (raw)
In-Reply-To: <be93d9ef-3d3e-4262-a280-d2922b983ca1@amd.com>
On Fri, Nov 03, 2023 at 08:18:35AM +0100, Christian König wrote:
> Am 02.11.23 um 00:31 schrieb Danilo Krummrich:
> > Implement reference counting for struct drm_gpuvm.
>
> From the design point of view what is that good for?
It was discussed in this thread [1].
Essentially, the idea is to make sure that vm_bo->vm is always valid without the
driver having the need to take extra care. It also ensures that GPUVM can't be
freed with mappings still held.
>
> Background is that the most common use case I see is that this object is
> embedded into something else and a reference count is then not really a good
> idea.
Do you have a specific use-case in mind where this would interfere?
>
> Thanks,
> Christian.
[1] https://lore.kernel.org/dri-devel/6fa058a4-20d3-44b9-af58-755cfb375d75@redhat.com/
>
> >
> > Signed-off-by: Danilo Krummrich <dakr@redhat.com>
> > ---
> > drivers/gpu/drm/drm_gpuvm.c | 44 +++++++++++++++++++-------
> > drivers/gpu/drm/nouveau/nouveau_uvmm.c | 20 +++++++++---
> > include/drm/drm_gpuvm.h | 31 +++++++++++++++++-
> > 3 files changed, 78 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
> > index 53e2c406fb04..6a88eafc5229 100644
> > --- a/drivers/gpu/drm/drm_gpuvm.c
> > +++ b/drivers/gpu/drm/drm_gpuvm.c
> > @@ -746,6 +746,8 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
> > gpuvm->rb.tree = RB_ROOT_CACHED;
> > INIT_LIST_HEAD(&gpuvm->rb.list);
> > + kref_init(&gpuvm->kref);
> > +
> > gpuvm->name = name ? name : "unknown";
> > gpuvm->flags = flags;
> > gpuvm->ops = ops;
> > @@ -770,15 +772,8 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
> > }
> > EXPORT_SYMBOL_GPL(drm_gpuvm_init);
> > -/**
> > - * drm_gpuvm_destroy() - cleanup a &drm_gpuvm
> > - * @gpuvm: pointer to the &drm_gpuvm to clean up
> > - *
> > - * Note that it is a bug to call this function on a manager that still
> > - * holds GPU VA mappings.
> > - */
> > -void
> > -drm_gpuvm_destroy(struct drm_gpuvm *gpuvm)
> > +static void
> > +drm_gpuvm_fini(struct drm_gpuvm *gpuvm)
> > {
> > gpuvm->name = NULL;
> > @@ -790,7 +785,33 @@ drm_gpuvm_destroy(struct drm_gpuvm *gpuvm)
> > drm_gem_object_put(gpuvm->r_obj);
> > }
> > -EXPORT_SYMBOL_GPL(drm_gpuvm_destroy);
> > +
> > +static void
> > +drm_gpuvm_free(struct kref *kref)
> > +{
> > + struct drm_gpuvm *gpuvm = container_of(kref, struct drm_gpuvm, kref);
> > +
> > + if (drm_WARN_ON(gpuvm->drm, !gpuvm->ops->vm_free))
> > + return;
> > +
> > + drm_gpuvm_fini(gpuvm);
> > +
> > + gpuvm->ops->vm_free(gpuvm);
> > +}
> > +
> > +/**
> > + * drm_gpuvm_bo_put() - drop a struct drm_gpuvm reference
> > + * @gpuvm: the &drm_gpuvm to release the reference of
> > + *
> > + * This releases a reference to @gpuvm.
> > + */
> > +void
> > +drm_gpuvm_put(struct drm_gpuvm *gpuvm)
> > +{
> > + if (gpuvm)
> > + kref_put(&gpuvm->kref, drm_gpuvm_free);
> > +}
> > +EXPORT_SYMBOL_GPL(drm_gpuvm_put);
> > static int
> > __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
> > @@ -843,7 +864,7 @@ drm_gpuva_insert(struct drm_gpuvm *gpuvm,
> > if (unlikely(!drm_gpuvm_range_valid(gpuvm, addr, range)))
> > return -EINVAL;
> > - return __drm_gpuva_insert(gpuvm, va);
> > + return __drm_gpuva_insert(drm_gpuvm_get(gpuvm), va);
> > }
> > EXPORT_SYMBOL_GPL(drm_gpuva_insert);
> > @@ -876,6 +897,7 @@ drm_gpuva_remove(struct drm_gpuva *va)
> > }
> > __drm_gpuva_remove(va);
> > + drm_gpuvm_put(va->vm);
> > }
> > EXPORT_SYMBOL_GPL(drm_gpuva_remove);
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > index 54be12c1272f..cb2f06565c46 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
> > @@ -1780,6 +1780,18 @@ nouveau_uvmm_bo_unmap_all(struct nouveau_bo *nvbo)
> > }
> > }
> > +static void
> > +nouveau_uvmm_free(struct drm_gpuvm *gpuvm)
> > +{
> > + struct nouveau_uvmm *uvmm = uvmm_from_gpuvm(gpuvm);
> > +
> > + kfree(uvmm);
> > +}
> > +
> > +static const struct drm_gpuvm_ops gpuvm_ops = {
> > + .vm_free = nouveau_uvmm_free,
> > +};
> > +
> > int
> > nouveau_uvmm_ioctl_vm_init(struct drm_device *dev,
> > void *data,
> > @@ -1830,7 +1842,7 @@ nouveau_uvmm_ioctl_vm_init(struct drm_device *dev,
> > NOUVEAU_VA_SPACE_END,
> > init->kernel_managed_addr,
> > init->kernel_managed_size,
> > - NULL);
> > + &gpuvm_ops);
> > /* GPUVM takes care from here on. */
> > drm_gem_object_put(r_obj);
> > @@ -1849,8 +1861,7 @@ nouveau_uvmm_ioctl_vm_init(struct drm_device *dev,
> > return 0;
> > out_gpuvm_fini:
> > - drm_gpuvm_destroy(&uvmm->base);
> > - kfree(uvmm);
> > + drm_gpuvm_put(&uvmm->base);
> > out_unlock:
> > mutex_unlock(&cli->mutex);
> > return ret;
> > @@ -1902,7 +1913,6 @@ nouveau_uvmm_fini(struct nouveau_uvmm *uvmm)
> > mutex_lock(&cli->mutex);
> > nouveau_vmm_fini(&uvmm->vmm);
> > - drm_gpuvm_destroy(&uvmm->base);
> > - kfree(uvmm);
> > + drm_gpuvm_put(&uvmm->base);
> > mutex_unlock(&cli->mutex);
> > }
> > diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
> > index 0c2e24155a93..4e6e1fd3485a 100644
> > --- a/include/drm/drm_gpuvm.h
> > +++ b/include/drm/drm_gpuvm.h
> > @@ -247,6 +247,11 @@ struct drm_gpuvm {
> > struct list_head list;
> > } rb;
> > + /**
> > + * @kref: reference count of this object
> > + */
> > + struct kref kref;
> > +
> > /**
> > * @kernel_alloc_node:
> > *
> > @@ -273,7 +278,23 @@ void drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
> > u64 start_offset, u64 range,
> > u64 reserve_offset, u64 reserve_range,
> > const struct drm_gpuvm_ops *ops);
> > -void drm_gpuvm_destroy(struct drm_gpuvm *gpuvm);
> > +
> > +/**
> > + * drm_gpuvm_get() - acquire a struct drm_gpuvm reference
> > + * @gpuvm: the &drm_gpuvm to acquire the reference of
> > + *
> > + * This function acquires an additional reference to @gpuvm. It is illegal to
> > + * call this without already holding a reference. No locks required.
> > + */
> > +static inline struct drm_gpuvm *
> > +drm_gpuvm_get(struct drm_gpuvm *gpuvm)
> > +{
> > + kref_get(&gpuvm->kref);
> > +
> > + return gpuvm;
> > +}
> > +
> > +void drm_gpuvm_put(struct drm_gpuvm *gpuvm);
> > bool drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm, u64 addr, u64 range);
> > bool drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64 range);
> > @@ -673,6 +694,14 @@ static inline void drm_gpuva_init_from_op(struct drm_gpuva *va,
> > * operations to drivers.
> > */
> > struct drm_gpuvm_ops {
> > + /**
> > + * @vm_free: called when the last reference of a struct drm_gpuvm is
> > + * dropped
> > + *
> > + * This callback is mandatory.
> > + */
> > + void (*vm_free)(struct drm_gpuvm *gpuvm);
> > +
> > /**
> > * @op_alloc: called when the &drm_gpuvm allocates
> > * a struct drm_gpuva_op
>
next prev parent reply other threads:[~2023-11-03 13:15 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-01 23:30 [PATCH drm-misc-next v8 00/12] [RFC] DRM GPUVM features Danilo Krummrich
2023-11-01 23:30 ` [PATCH drm-misc-next v8 01/12] drm/gpuvm: convert WARN() to drm_WARN() variants Danilo Krummrich
2023-11-01 23:30 ` [PATCH drm-misc-next v8 02/12] drm/gpuvm: don't always WARN in drm_gpuvm_check_overflow() Danilo Krummrich
2023-11-02 13:19 ` Thomas Hellström
2023-11-01 23:30 ` [PATCH drm-misc-next v8 03/12] drm/gpuvm: export drm_gpuvm_range_valid() Danilo Krummrich
2023-11-02 13:20 ` Thomas Hellström
2023-11-01 23:30 ` [PATCH drm-misc-next v8 04/12] drm/nouveau: make use of drm_gpuvm_range_valid() Danilo Krummrich
2023-11-02 4:46 ` Dave Airlie
2023-11-01 23:30 ` [PATCH drm-misc-next v8 05/12] drm/gpuvm: add common dma-resv per struct drm_gpuvm Danilo Krummrich
2023-11-01 23:30 ` [PATCH drm-misc-next v8 06/12] drm/nouveau: make use of the GPUVM's shared dma-resv Danilo Krummrich
2023-11-01 23:30 ` [PATCH drm-misc-next v8 07/12] drm/gpuvm: add drm_gpuvm_flags to drm_gpuvm Danilo Krummrich
2023-11-01 23:31 ` [PATCH drm-misc-next v8 08/12] drm/nouveau: separately allocate struct nouveau_uvmm Danilo Krummrich
2023-11-02 4:44 ` Dave Airlie
2023-11-01 23:31 ` [PATCH drm-misc-next v8 09/12] drm/gpuvm: reference count drm_gpuvm structures Danilo Krummrich
2023-11-02 10:46 ` kernel test robot
2023-11-02 13:21 ` Thomas Hellström
2023-11-02 17:09 ` Thomas Hellström
2023-11-02 17:32 ` Danilo Krummrich
2023-11-02 18:04 ` Thomas Hellström
2023-11-03 7:18 ` Christian König
2023-11-03 13:14 ` Danilo Krummrich [this message]
[not found] ` <a2e13a27-d2e5-4ae3-9c11-c18b425b69cc@amd.com>
2023-11-03 15:34 ` Danilo Krummrich
2023-11-06 9:14 ` Christian König
2023-11-06 12:16 ` Danilo Krummrich
[not found] ` <8e87d962-c80c-40d9-94d7-58b6cd9dd794@amd.com>
2023-11-06 14:11 ` Danilo Krummrich
[not found] ` <6d3c48f6-a92d-49b3-b836-ee1bc95b56bf@amd.com>
2023-11-06 16:42 ` Danilo Krummrich
2023-11-09 15:50 ` Thomas Hellström
2023-11-09 16:03 ` Christian König
2023-11-09 18:34 ` Danilo Krummrich
2023-11-10 8:50 ` Christian König
2023-11-10 9:39 ` Thomas Hellström
2023-11-10 10:42 ` Christian König
2023-11-10 10:52 ` Thomas Hellström
2023-11-10 16:49 ` Danilo Krummrich
2023-11-10 16:43 ` Danilo Krummrich
2023-11-10 16:57 ` Danilo Krummrich
2023-11-13 7:22 ` Christian König
2023-11-13 12:57 ` Danilo Krummrich
2023-11-01 23:31 ` [PATCH drm-misc-next v8 10/12] drm/gpuvm: add an abstraction for a VM / BO combination Danilo Krummrich
2023-11-02 13:25 ` Thomas Hellström
2023-11-02 17:16 ` Thomas Hellström
2023-11-01 23:31 ` [PATCH drm-misc-next v8 11/12] drm/gpuvm: track/lock/validate external/evicted objects Danilo Krummrich
2023-11-01 23:31 ` [PATCH drm-misc-next v8 12/12] drm/nouveau: use GPUVM common infrastructure Danilo Krummrich
2023-11-02 4:47 ` Dave Airlie
2023-11-02 13:18 ` Thomas Hellström
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZUTyGTxcH7WlHKsv@pollux \
--to=dakr@redhat.com \
--cc=airlied@gmail.com \
--cc=boris.brezillon@collabora.com \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=donald.robson@imgtec.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=faith@gfxstrand.net \
--cc=linux-kernel@vger.kernel.org \
--cc=matthew.brost@intel.com \
--cc=nouveau@lists.freedesktop.org \
--cc=sarah.walker@imgtec.com \
--cc=thomas.hellstrom@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox