[PATCH v3 4/4] drm/doc/rfc: i915 DG1 uAPI

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Wed Apr 21 14:25:07 UTC 2021


On 21/04/2021 14:54, Jason Ekstrand wrote:
> On Wed, Apr 21, 2021 at 3:22 AM Tvrtko Ursulin
> <tvrtko.ursulin at linux.intel.com> wrote:
>>
>> On 20/04/2021 18:00, Jason Ekstrand wrote:
>>> On Tue, Apr 20, 2021 at 11:34 AM Tvrtko Ursulin
>>> <tvrtko.ursulin at linux.intel.com> wrote:
>>>>
>>>>
>>>> On 19/04/2021 16:19, Jason Ekstrand wrote:
>>>>> On Mon, Apr 19, 2021 at 7:02 AM Matthew Auld <matthew.auld at intel.com> wrote:
>>>>>>
>>>>>> On 16/04/2021 17:38, Jason Ekstrand wrote:
>>>>>>> On Thu, Apr 15, 2021 at 11:04 AM Matthew Auld <matthew.auld at intel.com> wrote:
>>>>>>>>
>>>>>>>> Add an entry for the new uAPI needed for DG1.
>>>>>>>>
>>>>>>>> v2(Daniel):
>>>>>>>>       - include the overall upstreaming plan
>>>>>>>>       - add a note for mmap, there are differences here for TTM vs i915
>>>>>>>>       - bunch of other suggestions from Daniel
>>>>>>>> v3:
>>>>>>>>      (Daniel)
>>>>>>>>       - add a note for set/get caching stuff
>>>>>>>>       - add some more docs for existing query and extensions stuff
>>>>>>>>       - add an actual code example for regions query
>>>>>>>>       - bunch of other stuff
>>>>>>>>      (Jason)
>>>>>>>>       - uAPI change(!):
>>>>>>>>             - try a simpler design with the placements extension
>>>>>>>>             - rather than have a generic setparam which can cover multiple
>>>>>>>>               use cases, have each extension be responsible for one thing
>>>>>>>>               only
>>>>>>>>
>>>>>>>> Signed-off-by: Matthew Auld <matthew.auld at intel.com>
>>>>>>>> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
>>>>>>>> Cc: Jordan Justen <jordan.l.justen at intel.com>
>>>>>>>> Cc: Daniel Vetter <daniel.vetter at intel.com>
>>>>>>>> Cc: Kenneth Graunke <kenneth at whitecape.org>
>>>>>>>> Cc: Jason Ekstrand <jason at jlekstrand.net>
>>>>>>>> Cc: Dave Airlie <airlied at gmail.com>
>>>>>>>> Cc: dri-devel at lists.freedesktop.org
>>>>>>>> Cc: mesa-dev at lists.freedesktop.org
>>>>>>>> ---
>>>>>>>>      Documentation/gpu/rfc/i915_gem_lmem.h   | 255 ++++++++++++++++++++++++
>>>>>>>>      Documentation/gpu/rfc/i915_gem_lmem.rst | 139 +++++++++++++
>>>>>>>>      Documentation/gpu/rfc/index.rst         |   4 +
>>>>>>>>      3 files changed, 398 insertions(+)
>>>>>>>>      create mode 100644 Documentation/gpu/rfc/i915_gem_lmem.h
>>>>>>>>      create mode 100644 Documentation/gpu/rfc/i915_gem_lmem.rst
>>>>>>>>
>>>>>>>> diff --git a/Documentation/gpu/rfc/i915_gem_lmem.h b/Documentation/gpu/rfc/i915_gem_lmem.h
>>>>>>>> new file mode 100644
>>>>>>>> index 000000000000..2a82a452e9f2
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/Documentation/gpu/rfc/i915_gem_lmem.h
>>>>>>>> @@ -0,0 +1,255 @@
>>>>>>>> +/*
>>>>>>>> + * Note that drm_i915_query_item and drm_i915_query are existing bits of uAPI.
>>>>>>>> + * For the regions query we are just adding a new query id, so no actual new
>>>>>>>> + * ioctl or anything, but including it here for reference.
>>>>>>>> + */
>>>>>>>> +struct drm_i915_query_item {
>>>>>>>> +#define DRM_I915_QUERY_MEMORY_REGIONS   0xdeadbeaf
>>>>>>>> +       ....
>>>>>>>> +        __u64 query_id;
>>>>>>>> +
>>>>>>>> +        /*
>>>>>>>> +         * When set to zero by userspace, this is filled with the size of the
>>>>>>>> +         * data to be written at the data_ptr pointer. The kernel sets this
>>>>>>>> +         * value to a negative value to signal an error on a particular query
>>>>>>>> +         * item.
>>>>>>>> +         */
>>>>>>>> +        __s32 length;
>>>>>>>> +
>>>>>>>> +        __u32 flags;
>>>>>>>> +        /*
>>>>>>>> +         * Data will be written at the location pointed by data_ptr when the
>>>>>>>> +         * value of length matches the length of the data to be written by the
>>>>>>>> +         * kernel.
>>>>>>>> +         */
>>>>>>>> +        __u64 data_ptr;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +struct drm_i915_query {
>>>>>>>> +        __u32 num_items;
>>>>>>>> +        /*
>>>>>>>> +         * Unused for now. Must be cleared to zero.
>>>>>>>> +         */
>>>>>>>> +        __u32 flags;
>>>>>>>> +        /*
>>>>>>>> +         * This points to an array of num_items drm_i915_query_item structures.
>>>>>>>> +         */
>>>>>>>> +        __u64 items_ptr;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +#define DRM_IOCTL_I915_QUERY   DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
>>>>>>>> +
>>>>>>>> +/**
>>>>>>>> + * enum drm_i915_gem_memory_class
>>>>>>>> + */
>>>>>>>> +enum drm_i915_gem_memory_class {
>>>>>>>> +       /** @I915_MEMORY_CLASS_SYSTEM: system memory */
>>>>>>>> +       I915_MEMORY_CLASS_SYSTEM = 0,
>>>>>>>> +       /** @I915_MEMORY_CLASS_DEVICE: device local-memory */
>>>>>>>> +       I915_MEMORY_CLASS_DEVICE,
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +/**
>>>>>>>> + * struct drm_i915_gem_memory_class_instance
>>>>>>>> + */
>>>>>>>> +struct drm_i915_gem_memory_class_instance {
>>>>>>>> +       /** @memory_class: see enum drm_i915_gem_memory_class */
>>>>>>>> +       __u16 memory_class;
>>>>>>>> +
>>>>>>>> +       /** @memory_instance: which instance */
>>>>>>>> +       __u16 memory_instance;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +/**
>>>>>>>> + * struct drm_i915_memory_region_info
>>>>>>>> + *
>>>>>>>> + * Describes one region as known to the driver.
>>>>>>>> + *
>>>>>>>> + * Note that we reserve quite a lot of stuff here for potential future work. As
>>>>>>>> + * an example we might want expose the capabilities(see caps) for a given
>>>>>>>> + * region, which could include things like if the region is CPU
>>>>>>>> + * mappable/accessible etc.
>>>>>>>
>>>>>>> I get caps but I'm seriously at a loss as to what the rest of this
>>>>>>> would be used for.  Why are caps and flags both there and separate?
>>>>>>> Flags are typically something you set, not query.  Also, what's with
>>>>>>> rsvd1 at the end?  This smells of substantial over-building to me.
>>>>>>>
>>>>>>> I thought to myself, "maybe I'm missing a future use-case" so I looked
>>>>>>> at the internal tree and none of this is being used there either.
>>>>>>> This indicates to me that either I'm missing something and there's
>>>>>>> code somewhere I don't know about or, with three years of building on
>>>>>>> internal branches, we still haven't proven that any of this is needed.
>>>>>>> If it's the latter, which I strongly suspect, maybe we should drop the
>>>>>>> unnecessary bits and only add them back in if and when we have proof
>>>>>>> that they're useful.
>>>>>>
>>>>>> Do you mean just drop caps/flags here, but keep/inflate rsvd0/rsvd1,
>>>>>> which is less opinionated about future unknowns? If so, makes sense to me.
>>>>>
>>>>> I meant drop flags and rsvd1.  We need rsvd0 for padding and  I can
>>>>> see some value to caps.  We may want to advertise, for instance, what
>>>>> mapping coherency types are available per-heap.  But I don't see any
>>>>> use for any of the other fields.
>>>>
>>>> I'd suggest making sure at least enough rsvd fields remain so that flags
>>>> could be added later if needed. Experience from engine info shows that
>>>> both were required in order to extend the query via re-purposing the
>>>> rsvds and adding flag bits to indicate when a certain rsvd contains a
>>>> new piece of information.
>>>
>>> Looking at DII, all I see is we started using caps.  I already said
>>> I'm fine with caps.  I can already imagine some useful ones like
>>> specifying what kinds of mappings we can do.
>>>
>>> If we're concerned about more complicated stuff, I argue that we have
>>> no ability to predict what that will look like and so just throwing in
>>> a bunch of __u32 rsvd[N] is blind guessing.  I'm seeing a lot of that
>>> in the recently added APIs such as the flags and rsvd[4] in
>>> i915_user_extension.  What's that there for?  Why can't you put that
>>> information in the extension struct which derives from it?  Maybe it's
>>> so that we can extend it.  But we added that struct as part of an
>>> extension mechanism!?!
>>>
>>> If we want to make things extensible, Vulkan actually provides some
>>> prior art for this in the form of allowing queries to be extended just
>>> like input structs.  We could add a __u64 extensions field to
>>> memory_region_info and, if we ever need to query more info, the client
>>> can provide a chain of additional per-region queries.  Yeah, there are
>>> problems with it and it gets a bit clunky but it does work pretty
>>> well.
>>>
>>>> I probably cannot go into too much detail
>>>> here, but anyway the point is just to make sure too much is not stripped
>>>> out so that instead of simply adding fields/flags we have to add a new
>>>> query in the future. IMO some rsvd fields are not really harmful and if
>>>> they can make things easier in the future why not.
>>>
>>> Maybe it's my tired and generally grumpy state of mind but I'm not
>>> particularly favorable towards "why not?" as a justification for
>>> immutable kernel APIs.  We've already found a few places where
>>> Zoidberg API design has caused us problems.  We need an answer to
>>> "why?"  Future extensibility is a potentially valid answer but we need
>>> to do a better job of thinking through it than we have in the past.
>>
>> I did not simply say why not, did I?
> 
> You literally did:  "...and if they can make things easier in the
> future why not."

You quote the second *part* of *one* sentence from my reply in response 
to my statement that I said more in my reply that just that bit?

>> It is a balance thing between cost
>> and benefit. I see the cost of rsvd fields as approaching zero really ,
>> and cost of having to add query v2 if we end up having not enough rsvd
>> as definitely way bigger.
>>
>> If you look at the mentioned engine info query you will see that as soon
>> as you add some caps, flags become useful (so userspace can answer the
>> question of does the object not support this cap or does the kernel does
>> not even know about the cap).
>>
>> Furthermore, in that uapi, caps pertain to the property of the
>> underlying object being queried, while the flags pertain to the query
>> itself. I find that separation logical and useful.
> 
> Ok, that answers the question I asked above: "what are flags for and
> why are they different?"  At the very least, that should be
> documented.  Then again...  We really want a GETPARAM query any time a
> kernel interface changes, such as adding caps, and we can say that
> userspace should ignore caps it doesn't understand.  I think that
> solves both directions of the negotiation without flags.

I said to look at engine info didn't I.

Getparam also works to some extent, but it's IMO too flat and top-level 
to stuff the answers to random hierarchical questions.

GET_PARAM_DOES_QUERY_<x>_SUPPORT_CAP_<y>? Nah.. a bit clumsy I think 
when we can return the supported caps in the query itself.

>> I am not claiming to know memory region query will end up the same, and
>> I definitely agree we cannot guess the future. I am just saying rsvd
>> fields are inconsequential really in terms of maintenance burden and
>> have been proven useful in the past. So I disagree with the drive to
>> kick them all out.
> 
> Sure, it doesn't cost anything to have extra zeros in the struct.
> However, if/when the API grows using rsvd fields, we end up with "if
> CAP_FOO is set, rsvd[5] means blah" which makes for a horribly
> confusing API.  As a userspace person who has to remember how to use
> this stuff, I'd rather make another call or chain in a struct than try
> to remember and/or figure out what all 8 rsvd fields mean.

Well it's not called rsvd in the uapi which is aware of the new field 
but has a new name.

>> Btw extension chains also work for me. I this a bit more complicated and
>> we don't have prior art in i915 to use them on the read/get/query side
>> but we could add if a couple of rsvd is so objectionable.
> 
> Another option, which I think I mentioned somewhere, is that we could
> add a secondary query which takes a memory region class and instance
> and lets you query additional properties one-at-a-time.  That might be
> easier to extend.  Sure, it means more ioctls but they're not that
> expensive and they should only happen at driver initialization so I'm
> not that inclined to care about the cost there.

Or leave flags and some rsvd so you can add extensions later. :)

Regards,

Tvrtko


More information about the dri-devel mailing list