From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: "Christian König" <christian.koenig@amd.com>,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
maarten.lankhorst@linux.intel.com, matthew.auld@intel.com,
"Matthew Auld" <matthew.william.auld@gmail.com>
Subject: Re: [RFC PATCH] drm/ttm: Add a private member to the struct ttm_resource
Date: Tue, 14 Sep 2021 17:30:29 +0200 [thread overview]
Message-ID: <d632947c-fb77-34e8-fa3e-9ca3669384ee@linux.intel.com> (raw)
In-Reply-To: <YUCsvTiS+AWfLyyL@phenom.ffwll.local>
On 9/14/21 4:07 PM, Daniel Vetter wrote:
> On Tue, Sep 14, 2021 at 12:38:00PM +0200, Thomas Hellström wrote:
>> On Tue, 2021-09-14 at 10:53 +0200, Christian König wrote:
>>> Am 14.09.21 um 10:27 schrieb Thomas Hellström:
>>>> On Tue, 2021-09-14 at 09:40 +0200, Christian König wrote:
>>>>> Am 13.09.21 um 14:41 schrieb Thomas Hellström:
>>>>>> [SNIP]
>>>>>>>>> Let's say you have a struct ttm_object_vram and a struct
>>>>>>>>> ttm_object_gtt, both subclassing drm_gem_object. Then I'd
>>>>>>>>> say
>>>>>>>>> a
>>>>>>>>> driver would want to subclass those to attach identical
>>>>>>>>> data,
>>>>>>>>> extend functionality and provide a single i915_gem_object
>>>>>>>>> to
>>>>>>>>> the
>>>>>>>>> rest of the driver, which couldn't care less whether it's
>>>>>>>>> vram or
>>>>>>>>> gtt? Wouldn't you say having separate struct
>>>>>>>>> ttm_object_vram
>>>>>>>>> and a
>>>>>>>>> struct ttm_object_gtt in this case would be awkward?. We
>>>>>>>>> *want* to
>>>>>>>>> allow common handling.
>>>>>>>> Yeah, but that's a bad idea. This is like diamond
>>>>>>>> inheritance
>>>>>>>> in C++.
>>>>>>>>
>>>>>>>> When you need the same functionality in different backends
>>>>>>>> you
>>>>>>>> implement that as separate object and then add a parent
>>>>>>>> class.
>>>>>>>>
>>>>>>>>> It's the exact same situation here. With struct
>>>>>>>>> ttm_resource
>>>>>>>>> you
>>>>>>>>> let *different* implementation flavours subclass it,
>>>>>>>>> which
>>>>>>>>> makes it
>>>>>>>>> awkward for the driver to extend the functionality in a
>>>>>>>>> common way
>>>>>>>>> by subclassing, unless the driver only uses a single
>>>>>>>>> implementation.
>>>>>>>> Well the driver should use separate implementations for
>>>>>>>> their
>>>>>>>> different domains as much as possible.
>>>>>>>>
>>>>>>> Hmm, Now you lost me a bit. Are you saying that the way we do
>>>>>>> dynamic
>>>>>>> backends in the struct ttm_buffer_object to facilitate driver
>>>>>>> subclassing is a bad idea or that the RFC with backpointer is
>>>>>>> a
>>>>>>> bad
>>>>>>> idea?
>>>>>>>
>>>>>>>
>>>>>> Or if you mean diamond inheritance is bad, yes that's basically
>>>>>> my
>>>>>> point.
>>>>> That diamond inheritance is a bad idea. What I don't understand
>>>>> is
>>>>> why
>>>>> you need that in the first place?
>>>>>
>>>>> Information that you attach to a resource are specific to the
>>>>> domain
>>>>> where the resource is allocated from. So why do you want to
>>>>> attach
>>>>> the
>>>>> same information to a resources from different domains?
>>>> Again, for the same reason that we do that with struct
>>>> i915_gem_objects
>>>> and struct ttm_tts, to extend the functionality. I mean information
>>>> that we attach when we subclass a struct ttm_buffer_object doesn't
>>>> necessarily care about whether it's a VRAM or a GTT object. In
>>>> exactly
>>>> the same way, information that we want to attach to a struct
>>>> ttm_resource doesn't necessarily care whether it's a system or a
>>>> VRAM
>>>> resource, and need not be specific to any of those.
>>>>
>>>> In this particular case, as memory management becomes asynchronous,
>>>> you
>>>> can't attach things like sg-tables and gpu binding information to
>>>> the
>>>> gem object anymore, because the object may have a number of
>>>> migrations
>>>> in the pipeline. Such things need to be attached to the structure
>>>> that
>>>> abstracts the memory allocation, and which may have a completely
>>>> different lifetime than the object itself.
>>>>
>>>> In our particular case we want to attach information for cached
>>>> page
>>>> lookup and and sg-table, and moving forward probably the gpu
>>>> binding
>>>> (vma) information, and that is the same information for any
>>>> ttm_resource regardless where it's allocated from.
>>>>
>>>> Typical example: A pipelined GPU operation happening before an
>>>> async
>>>> eviction goes wrong. We need to error capture and reset. But if we
>>>> look
>>>> at the object for error capturing, it's already updated pointing to
>>>> an
>>>> after-eviction resource, and the resource sits on a ghost object
>>>> (or in
>>>> the future when ghost objects go away perhaps in limbo somewhere).
>>>>
>>>> We need to capture the memory pointed to by the struct ttm_resource
>>>> the
>>>> GPU was referencing, and to be able to do that we need to cache
>>>> driver-
>>>> specific info on the resource. Typically an sg-list and GPU binding
>>>> information.
>>>>
>>>> Anyway, that cached information needs to be destroyed together with
>>>> the
>>>> resource and thus we need to be able to access that information
>>>> from
>>>> the resource in some way, regardless whether it's a pointer or
>>>> whether
>>>> we embed the struct resource.
>>>>
>>>> I think it's pretty important here that we (using the inheritance
>>>> diagram below) recognize the need for D to inherit from A, just
>>>> like we
>>>> do for objects or ttm_tts.
>>>>
>>>>
>>>>>> Looking at
>>>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMultiple_inheritance%23%2Fmedia%2FFile%3ADiamond_inheritance.svg&data=04%7C01%7Cchristian.koenig%40amd.com%7C268bb562db8548b285b408d977598b2c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637672048739103176%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=bPyDqiSF%2FHFZbl74ux0vfwh3uma5hZIUf2xbzb9yZz8%3D&reserved=0
>>>>>>
>>>>>>
>>>>>>
>>>>>> 1)
>>>>>>
>>>>>> A would be the struct ttm_resource itself,
>>>>>> D would be struct i915_resource,
>>>>>> B would be struct ttm_range_mgr_node,
>>>>>> C would be struct i915_ttm_buddy_resource
>>>>>>
>>>>>> And we need to resolve the ambiguity using the awkward union
>>>>>> construct, iff we need to derive from both B and C.
>>>>>>
>>>>>> Struct ttm_buffer_object and struct ttm_tt instead have B) and
>>>>>> C)
>>>>>> being dynamic backends of A) or a single type derived from A)
>>>>>> Hence
>>>>>> the problem doesn't exist for these types.
>>>>>>
>>>>>> So the question from last email remains, if ditching this RFC,
>>>>>> can
>>>>>> we
>>>>>> have B) and C) implemented by helpers that can be used from D)
>>>>>> and
>>>>>> that don't derive from A?
>>>>> Well we already have that in the form of drm_mm. I mean the
>>>>> ttm_range_manager is just a relatively small glue code which
>>>>> implements
>>>>> the TTMs resource interface using the drm_mm object and a
>>>>> spinlock.
>>>>> IIRC
>>>>> that less than 200 lines of code.
>>>>>
>>>>> So you should already have the necessary helpers and just need to
>>>>> implement the resource manager as far as I can see.
>>>>>
>>>>> I mean I reused the ttm_range_manager_node in for amdgpu_gtt_mgr
>>>>> and
>>>>> could potentially reuse a bit more of the ttm_range_manager code.
>>>>> But
>>>>> I
>>>>> don't see that as much of an issue, the extra functionality there
>>>>> is
>>>>> just minimal.
>>>> Sure but that would give up the prereq of having reusable resource
>>>> manager implementations. What happens if someone would like to
>>>> reuse
>>>> the buddy manager? And to complicate things even more, the
>>>> information
>>>> we attach to VRAM resources also needs to be attached to system
>>>> resources. Sure we could probably re-implement a combined system-
>>>> buddy-
>>>> range manager, but that seems like something overly complex.
>>>>
>>>> The other object examples resolve the diamond inheritance with a
>>>> pointer to the specialization (BC) and let D derive from A.
>>>>
>>>> TTM resources do it backwards. If we can just recognize that and
>>>> ponder
>>>> what's the easiest way to resolve this given the current design, I
>>>> actually think we'd arrive at a backpointer to allow downcasting
>>>> from A
>>>> to D.
>>> Yeah, but I think you are approaching that from the wrong side.
>>>
>>> For use cases like this I think you should probably have the
>>> following
>>> objects and inheritances:
>>>
>>> 1. Driver specific objects like i915_sg, i915_vma which don't inherit
>>> anything from TTM.
>>> 2. i915_vram_node which inherits from ttm_resource or a potential
>>> ttm_buddy_allocator.
>>> 3. i915_gtt_node which inherits from ttm_range_manger_node.
>>> 4. Maybe i915_sys_node which inherits from ttm_resource as well.
>>>
>>> The managers for the individual domains then provide the glue code to
>>> implement both the TTM resource interface as well as a driver
>>> specific
>>> interface to access the driver objects.
>> Well yes, but this is not really much better than the union thing. More
>> memory efficient but also more duplicated type definitions and manager
>> definitions and in addition overriding the default system resource
>> manager, not counting the kerneldoc needed to explain why all this is
>> necessary.
>>
>> It was this complexity I was trying to get away from in the first
>> place.
> I honestly don't think the union thing is the worst. At least as long as
> we're reworking i915 at a fairly invasive pace it's probably the lest
> worst approach.
>
> For the specific case of sg list I'm also not sure how great our current
> i915 design of "everything is an sg" really is. In the wider community
> there's clear rejection of sg for p2p addresses, so having this as a
> per-ttm_res_manager kind of situation is probably not the worst.
OK well, I'm no defender of the usage of sg list itself, but I was under
the impression that as long as it was either only visible to the driver
code itself or constructed using dma_map_resource() returned addresses
for p2p it would be OK?
> In that world every ttm_res_manager would have it's own implementation of
> binding into ptes, which then iterate over the pagetables with some common
> abstraction. So in a way more of a helper approach for the i915
> implementations of the various hooks, at the cost of a bit of code
> duplication.
>
> I do agree with Christian that the various backpointers to sort out the
> diamond inheritence issue isn't not great. The other options aren't pretty
> either, but at least it's more contained to i915.
OK, I guess I will have to implement whatever ends up prettiest without
the back pointer then. I wonder whether there is something we can think
of in the future to avoid these diamond- or diamond like inheritances.
/Thomas
> -Daniel
>
>
>> /Thomas
>>
>>
>>
>>
>>> Amdgpu just uses a switch/case for now, but you could as well extend
>>> the
>>> ttm_resource_manager_func table and upcast that inside the driver.
>>>
>>> Regards,
>>> Christian.
>>>
>>>> Thanks,
>>>> Thomas
>>>>
>>>>
>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Thomas
>>>>>>
>>>>>>
>>>>>>
>>
prev parent reply other threads:[~2021-09-14 15:41 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-10 13:15 [RFC PATCH] drm/ttm: Add a private member to the struct ttm_resource Thomas Hellström
2021-09-10 14:40 ` Christian König
2021-09-10 15:30 ` Thomas Hellström
2021-09-10 17:03 ` Christian König
2021-09-11 6:07 ` Thomas Hellström
2021-09-13 6:17 ` Christian König
2021-09-13 9:36 ` Thomas Hellström
2021-09-13 9:41 ` Christian König
2021-09-13 10:16 ` Thomas Hellström
2021-09-13 12:41 ` Thomas Hellström
2021-09-14 7:40 ` Christian König
2021-09-14 8:27 ` Thomas Hellström
2021-09-14 8:53 ` Christian König
2021-09-14 10:38 ` Thomas Hellström
2021-09-14 14:07 ` Daniel Vetter
2021-09-14 15:30 ` Thomas Hellström [this message]
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=d632947c-fb77-34e8-fa3e-9ca3669384ee@linux.intel.com \
--to=thomas.hellstrom@linux.intel.com \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=matthew.auld@intel.com \
--cc=matthew.william.auld@gmail.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;
as well as URLs for NNTP newsgroup(s).