[Intel-gfx] [RFC v2 2/2] drm/doc/rfc: VM_BIND uapi definition

Niranjana Vishwanathapura niranjana.vishwanathapura at intel.com
Wed Apr 20 20:18:17 UTC 2022


On Wed, Mar 30, 2022 at 02:51:41PM +0200, Daniel Vetter wrote:
>On Mon, Mar 07, 2022 at 12:31:46PM -0800, Niranjana Vishwanathapura wrote:
>> VM_BIND und related uapi definitions
>>
>> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura at intel.com>
>> ---
>>  Documentation/gpu/rfc/i915_vm_bind.h | 176 +++++++++++++++++++++++++++
>
>Maybe as the top level comment: The point of documenting uapi isn't to
>just spell out all the fields, but to define _how_ and _why_ things work.
>This part is completely missing from these docs here.
>

Thanks Daniel,

Some of the documentation is in the rst file.
Ok, will add documentation here on _how and _why_.

>>  1 file changed, 176 insertions(+)
>>  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h
>>
>> diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h
>> new file mode 100644
>> index 000000000000..80f00ee6c8a1
>> --- /dev/null
>> +++ b/Documentation/gpu/rfc/i915_vm_bind.h
>
>You need to incldue this somewhere so it's rendered, see the previous
>examples.

Looking at previous examples, my understanding is this is just a documentation
file at this point which goes into Documentation/gpu/rfc folder and will have to
remove it later once the actual uapi changes lands in include/uapi/drm/i915_drm.h.
Let me know if that is incorrect and needs change.

>
>> @@ -0,0 +1,176 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2022 Intel Corporation
>> + */
>> +
>> +/* VM_BIND feature availability through drm_i915_getparam */
>> +#define I915_PARAM_HAS_VM_BIND		57
>
>Needs to be kernel-docified, which means we need a prep patch that fixes
>up the existing mess.
>

Ok on kernel-doc, but as mentioned above, I am not sure we need prep
patch that fixes up other existing fields at this point.

>> +
>> +/* VM_BIND related ioctls */
>> +#define DRM_I915_GEM_VM_BIND		0x3d
>> +#define DRM_I915_GEM_VM_UNBIND		0x3e
>> +#define DRM_I915_GEM_WAIT_USER_FENCE	0x3f
>> +
>> +#define DRM_IOCTL_I915_GEM_VM_BIND		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
>> +#define DRM_IOCTL_I915_GEM_VM_UNBIND		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
>> +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
>> +
>> +/**
>> + * struct drm_i915_gem_vm_bind - VA to object/buffer mapping to [un]bind.
>
>Both binding and unbinding need to specify in excruciating detail what
>happens if there's overlaps (existing mappings, or unmapping a range which
>has no mapping, or only partially full of maps or different objects) and
>fun stuff like that.
>

Ok, will add those details.

>> + */
>> +struct drm_i915_gem_vm_bind {
>> +	/** vm to [un]bind */
>> +	__u32 vm_id;
>> +
>> +	/**
>> +	 * BO handle or file descriptor.
>> +	 * 'fd' value of -1 is reserved for system pages (SVM)
>> +	 */
>> +	union {
>> +		__u32 handle; /* For unbind, it is reserved and must be 0 */
>
>I think it'd be a lot cleaner if we do a bind and an unbind struct for
>these, instead of mixing it up.
>

Ok

>Also I thought mesa requested to be able to unmap an object from a vm
>without a range. Has that been dropped, and confirmed to not be needed.
>

Hmm...I think it was other way around. ie., to unmap with a range in vm
but without an object. We already support that.

>> +		__s32 fd;
>
>If we don't need it right away then don't add it yet. If it's planned to
>be used then it needs to be documented, but I kinda have no idea why you'd
>need an fd for svm?
>

It is not required for SVM, it was intended for future expanstions and '-1'
was reserved for SVM.
Ok, will remove it for now.

>> +	}
>> +
>> +	/** VA start to [un]bind */
>> +	__u64 start;
>> +
>> +	/** Offset in object to [un]bind */
>> +	__u64 offset;
>> +
>> +	/** VA length to [un]bind */
>> +	__u64 length;
>> +
>> +	/** Flags */
>> +	__u64 flags;
>> +	/** Bind the mapping immediately instead of during next submission */
>
>This aint kerneldoc.
>
>Also this needs to specify in much more detail what exactly this means,
>and also how it interacts with execbuf.
>

Ok

>So the patch here probably needs to include the missing pieces on the
>execbuf side of things. Like how does execbuf work when it's used with a
>vm_bind managed vm? That means:
>- document the pieces that are there
>- then add a patch to document how that all changes with vm_bind

Hmm, I am bit confused. The current execbuff handling documentation is in
i915_gem_execbuffer.c. Not sure how to update it in this design RFC patch.
With VM_BIND support, we only support vm_bind vmas in the execbuff and
based on comments from other patch in this series, we probably should not
allow any execlist entries in vm_bind mode (no implicit syncing and use
an extension for the batch address). May be I can update the rst file
in this series for these information for now. Thoughts?

>
>And do that for everything execbuf can do.
>
>> +#define I915_GEM_VM_BIND_IMMEDIATE   (1 << 0)
>> +	/** Read-only mapping */
>> +#define I915_GEM_VM_BIND_READONLY    (1 << 1)
>> +	/** Capture this mapping in the dump upon GPU error */
>> +#define I915_GEM_VM_BIND_CAPTURE     (1 << 2)
>> +
>> +	/** Zero-terminated chain of extensions */
>> +	__u64 extensions;
>> +};
>> +
>> +/**
>> + * struct drm_i915_vm_bind_ext_user_fence - Bind completion signaling extension.
>> + */
>> +struct drm_i915_vm_bind_ext_user_fence {
>> +#define I915_VM_BIND_EXT_USER_FENCE	0
>> +	/** @base: Extension link. See struct i915_user_extension. */
>> +	struct i915_user_extension base;
>> +
>> +	/** User/Memory fence qword alinged process virtual address */
>> +	__u64 addr;
>> +
>> +	/** User/Memory fence value to be written after bind completion */
>> +	__u64 val;
>> +
>> +	/** Reserved for future extensions */
>> +	__u64 rsvd;
>> +};
>> +
>> +/**
>> + * struct drm_i915_gem_execbuffer_ext_user_fence - First level batch completion
>> + * signaling extension.
>> + *
>> + * This extension allows user to attach a user fence (<addr, value> pair) to an
>> + * execbuf to be signaled by the command streamer after the completion of 1st
>> + * level batch, by writing the <value> at specified <addr> and triggering an
>> + * interrupt.
>> + * User can either poll for this user fence to signal or can also wait on it
>> + * with i915_gem_wait_user_fence ioctl.
>> + * This is very much usefaul for long running contexts where waiting on dma-fence
>> + * by user (like i915_gem_wait ioctl) is not supported.
>> + */
>> +struct drm_i915_gem_execbuffer_ext_user_fence {
>> +#define DRM_I915_GEM_EXECBUFFER_EXT_USER_FENCE		0
>> +	/** @base: Extension link. See struct i915_user_extension. */
>> +	struct i915_user_extension base;
>> +
>> +	/**
>> +	 * User/Memory fence qword aligned GPU virtual address.
>> +	 * Address has to be a valid GPU virtual address at the time of
>> +	 * 1st level batch completion.
>> +	 */
>> +	__u64 addr;
>> +
>> +	/**
>> +	 * User/Memory fence Value to be written to above address
>> +	 * after 1st level batch completes.
>> +	 */
>> +	__u64 value;
>> +
>> +	/** Reserved for future extensions */
>> +	__u64 rsvd;
>> +};
>> +
>> +struct drm_i915_gem_vm_control {
>> +/** Flag to opt-in for VM_BIND mode of binding during VM creation */
>
>This is very confusingly docunmented and I have no idea how you're going
>to use an empty extension. Also it's not kerneldoc.
>

Yah, I was also wondering how to define new flags bits for the flags
in structures already defined in i915_drm.h.
Ok, will just define the flag bit definition here and mention the
sturcture field in the documentation part.

>Please check that the stuff you're creating renders properly in the html
>output.
>
>> +#define I915_VM_CREATE_FLAGS_USE_VM_BIND	(1 << 0)
>> +};
>> +
>> +
>> +struct drm_i915_gem_create_ext {
>> +/** Extension to make the object private to a specified VM */
>> +#define I915_GEM_CREATE_EXT_VM_PRIVATE		2
>
>Why 2?
>
>Also this all needs to be documented what it precisely means.
>

Because 0 and 1 are already taken (I915_GEM_CREATE_EXT_* in i915_drm.h).
Ok, will add required documentation.

>> +};
>> +
>> +
>> +struct prelim_drm_i915_gem_context_create_ext {
>> +/** Flag to declare context as long running */
>> +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
>
>The compute mode context, again including full impact on execbuf, is not
>documented here. This also means any gaps in the context uapi
>documentation need to be filled first in prep patches.
>

Ok, will add documentation here.
As mentioned above, I guess the prep patch will later once this
RFC patch gets accepted?

>Also memory fences are extremely tricky, we need to specify in detail when
>they're allowed to be used and when not. This needs to reference the
>relevant sections from the dma-fence docs.
>

Ok

>> +};
>> +
>> +/**
>> + * struct drm_i915_gem_wait_user_fence
>> + *
>> + * Wait on user/memory fence. User/Memory fence can be woken up either by,
>> + *    1. GPU context indicated by 'ctx_id', or,
>> + *    2. Kerrnel driver async worker upon I915_UFENCE_WAIT_SOFT.
>> + *       'ctx_id' is ignored when this flag is set.
>> + *
>> + * Wakeup when below condition is true.
>> + * (*addr & MASK) OP (VALUE & MASK)
>> + *
>> + */
>> +~struct drm_i915_gem_wait_user_fence {
>> +	/** @base: Extension link. See struct i915_user_extension. */
>> +	__u64 extensions;
>> +
>> +	/** User/Memory fence address */
>> +	__u64 addr;
>> +
>> +	/** Id of the Context which will signal the fence. */
>> +	__u32 ctx_id;
>> +
>> +	/** Wakeup condition operator */
>> +	__u16 op;
>> +#define I915_UFENCE_WAIT_EQ      0
>> +#define I915_UFENCE_WAIT_NEQ     1
>> +#define I915_UFENCE_WAIT_GT      2
>> +#define I915_UFENCE_WAIT_GTE     3
>> +#define I915_UFENCE_WAIT_LT      4
>> +#define I915_UFENCE_WAIT_LTE     5
>> +#define I915_UFENCE_WAIT_BEFORE  6
>> +#define I915_UFENCE_WAIT_AFTER   7
>> +
>> +	/** Flags */
>> +	__u16 flags;
>> +#define I915_UFENCE_WAIT_SOFT    0x1
>> +#define I915_UFENCE_WAIT_ABSTIME 0x2
>> +
>> +	/** Wakeup value */
>> +	__u64 value;
>> +
>> +	/** Wakeup mask */
>> +	__u64 mask;
>> +#define I915_UFENCE_WAIT_U8     0xffu
>> +#define I915_UFENCE_WAIT_U16    0xffffu
>> +#define I915_UFENCE_WAIT_U32    0xfffffffful
>> +#define I915_UFENCE_WAIT_U64    0xffffffffffffffffull
>
>Do we really need all these flags, and does the hw really support all the
>combinations? Anything the hw doesn't support in MI_SEMAPHORE is pretty
>much useless as a umf (userspace memory fence) mode.
>

Hmm...The PIPE_CONTROL/MI_FLUSH instructions (used for wakup) support 64-bit
writes. The gem_wait_user_fence ioctl wakup condition is,
(*addr & MASK) OP (VALUE & MASK)
So, these values provide user options to configure wakeup.

The MI_SEMAPHORE seems to only support 32-bit value check for wakeup.
But that is different from the above gem_wait_user_fence ioctl wakeup.


>> +
>> +	/** Timeout */
>
>Needs to specificy the clock source.

Ok,

Niranjana

>-Daniel
>
>> +	__s64 timeout;
>> +};
>> --
>> 2.21.0.rc0.32.g243a4c7e27
>>
>
>-- 
>Daniel Vetter
>Software Engineer, Intel Corporation
>http://blog.ffwll.ch


More information about the dri-devel mailing list