From: "Christian König" <christian.koenig@amd.com>
To: "Danilo Krummrich" <dakr@redhat.com>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>
Cc: airlied@gmail.com, daniel@ffwll.ch, matthew.brost@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, 10 Nov 2023 09:50:20 +0100 [thread overview]
Message-ID: <1d4ca394-ee0c-4617-adbe-1d47e295c8fb@amd.com> (raw)
In-Reply-To: <4532d9d5-4c5a-4639-8136-d3ba9995d7b6@redhat.com>
Am 09.11.23 um 19:34 schrieb Danilo Krummrich:
> On 11/9/23 17:03, Christian König wrote:
>> Am 09.11.23 um 16:50 schrieb Thomas Hellström:
>>> [SNIP]
>>>>>
>>> Did we get any resolution on this?
>>>
>>> FWIW, my take on this is that it would be possible to get GPUVM to
>>> work both with and without internal refcounting; If with, the driver
>>> needs a vm close to resolve cyclic references, if without that's not
>>> necessary. If GPUVM is allowed to refcount in mappings and vm_bos,
>>> that comes with a slight performance drop but as Danilo pointed out,
>>> the VM lifetime problem iterating over a vm_bo's mapping becomes
>>> much easier and the code thus becomes easier to maintain moving
>>> forward. That convinced me it's a good thing.
>>
>> I strongly believe you guys stumbled over one of the core problems
>> with the VM here and I think that reference counting is the right
>> answer to solving this.
>>
>> The big question is that what is reference counted and in which
>> direction does the dependency points, e.g. we have here VM, BO, BO_VM
>> and Mapping objects.
>>
>> Those patches here suggest a counted Mapping -> VM reference and I'm
>> pretty sure that this isn't a good idea. What we should rather really
>> have is a BO -> VM or BO_VM ->VM reference. In other words that each
>> BO which is part of the VM keeps a reference to the VM.
>
> We have both. Please see the subsequent patch introducing VM_BO
> structures for that.
>
> As I explained, mappings (struct drm_gpuva) keep a pointer to their VM
> they're mapped
> in and besides that it doesn't make sense to free a VM that still
> contains mappings,
> the reference count ensures that. This simply ensures memory safety.
>
>>
>> BTW: At least in amdgpu we can have BOs which (temporary) doesn't
>> have any mappings, but are still considered part of the VM.
>
> That should be possible.
>
>>
>>>
>>> Another issue Christian brought up is that something intended to be
>>> embeddable (a base class) shouldn't really have its own refcount. I
>>> think that's a valid point. If you at some point need to derive from
>>> multiple such structs each having its own refcount, things will
>>> start to get weird. One way to resolve that would be to have the
>>> driver's subclass provide get() and put() ops, and export a
>>> destructor for the base-class, rather than to have the base-class
>>> provide the refcount and a destructor ops.
>
> GPUVM simply follows the same pattern we have with drm_gem_objects.
> And I think it makes
> sense. Why would we want to embed two struct drm_gpuvm in a single
> driver structure?
Because you need one drm_gpuvm structure for each application using the
driver? Or am I missing something?
As far as I can see a driver would want to embed that into your fpriv
structure which is allocated during drm_driver.open callback.
>
>>
>> Well, I have never seen stuff like that in the kernel. Might be that
>> this works, but I would rather not try if avoidable.
>>
>>>
>>> That would also make it possible for the driver to decide the
>>> context for the put() call: If the driver needs to be able to call
>>> put() from irq / atomic context but the base-class'es destructor
>>> doesn't allow atomic context, the driver can push freeing out to a
>>> work item if needed.
>>>
>>> Finally, the refcount overflow Christian pointed out. Limiting the
>>> number of mapping sounds like a reasonable remedy to me.
>>
>> Well that depends, I would rather avoid having a dependency for
>> mappings.
>>
>> Taking the CPU VM handling as example as far as I know
>> vm_area_structs doesn't grab a reference to their mm_struct either.
>> Instead they get automatically destroyed when the mm_struct is
>> destroyed.
>
> Certainly, that would be possible. However, thinking about it, this
> might call for
> huge trouble.
>
> First of all, we'd still need to reference count a GPUVM and take a
> reference for each
> VM_BO, as we do already. Now instead of simply increasing the
> reference count for each
> mapping as well, we'd need a *mandatory* driver callback that is
> called when the GPUVM
> reference count drops to zero. Maybe something like vm_destroy().
>
> The reason is that GPUVM can't just remove all mappings from the tree
> nor can it free them
> by itself, since drivers might use them for tracking their allocated
> page tables and/or
> other stuff.
>
> Now, let's think about the scope this callback might be called from.
> When a VM_BO is destroyed
> the driver might hold a couple of locks (for Xe it would be the VM's
> shared dma-resv lock and
> potentially the corresponding object's dma-resv lock if they're not
> the same already). If
> destroying this VM_BO leads to the VM being destroyed, the drivers
> vm_destroy() callback would
> be called with those locks being held as well.
>
> I feel like doing this finally opens the doors of the locking hell
> entirely. I think we should
> really avoid that.
That's a really good point, but I fear exactly that's the use case.
I would expect that VM_BO structures are added in the
drm_gem_object_funcs.open callback and freed in drm_gem_object_funcs.close.
Since it is perfectly legal for userspace to close a BO while there are
still mappings (can trivial be that the app is killed) I would expect
that the drm_gem_object_funcs.close handling is something like asking
drm_gpuvm destroying the VM_BO and getting the mappings which should be
cleared in the page table in return.
In amdgpu we even go a step further and the VM structure keeps track of
all the mappings of deleted VM_BOs so that higher level can query those
and clear them later on.
Background is that the drm_gem_object_funcs.close can't fail, but it can
perfectly be that the app is killed because of an OOM situation and we
can't do page tables updates in that moment because of this.
>
>>
>> Which makes sense in that case because when the mm_struct is gone the
>> vm_area_struct doesn't make sense any more either.
>>
>> What we clearly need is a reference to prevent the VM or at least the
>> shared resv to go away to early.
>
> Yeah, that was a good hint and we've covered that.
>
>>
>> Regards,
>> Christian.
>>
>>>
>>> But I think all of this is fixable as follow-ups if needed, unless
>>> I'm missing something crucial.
>
> Fully agree, I think at this point we should go ahead and land this
> series.
Yeah, agree this is not UAPI so not nailed in stone. Feel free to add my
acked-by as well if you want.
Only keep in mind that when you give drivers some functionality in a
common component they usually expect to keep that functionality.
For example changing the dma_resv object to make sure that drivers can't
cause use after free errors any more was an extremely annoying
experience since every user of those interface had to change at once.
Regards,
Christian.
>
>>>
>>> Just my 2 cents.
>>>
>>> /Thomas
>>>
>>>
>>
>
next prev parent reply other threads:[~2023-11-10 18: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
[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 [this message]
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=1d4ca394-ee0c-4617-adbe-1d47e295c8fb@amd.com \
--to=christian.koenig@amd.com \
--cc=airlied@gmail.com \
--cc=boris.brezillon@collabora.com \
--cc=dakr@redhat.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
all inboxes | Powered by JetHome®