On Tuesday, September 22, 2026 5:20:41 PM Central European Summer Time James 
Zhu wrote:
> On 2026-09-22 11:09, Timur Kristóf wrote:
> > On Monday, September 21, 2026 10:03:02 PM Central European Summer Time
> > James> 
> > Zhu wrote:
> >> Add the DRM_AMDGPU_PROFILER ioctl number and its argument structures, the
> >> UAPI for GPU performance monitoring features such as SPM (Stream
> >> Performance Monitor).
> >> 
> >> struct drm_amdgpu_profiler_args carries an operation selector and a union
> >> of per-operation parameters, currently AMDGPU_PROFILER_OP_GET_VER and
> >> AMDGPU_PROFILER_OP_SPM. The SPM operations and the layout of the
> >> destination buffer are described by struct drm_amdgpu_spm_args and
> >> struct drm_amdgpu_spm_buffer_header.
> >> 
> >> The ioctl number and struct layout are frozen here. The implementation
> >> lands in the rest of this series and the ioctl is not registered in
> >> amdgpu_ioctls_kms[] until then, so this header change alone does not make
> >> the interface reachable.
> >> 
> >> Signed-off-by: James Zhu<[email protected]>
> >> Reviewed-by: Bing Ma<[email protected]>
> > 
> > Hi,
> > 
> > Can you guys please clarify why this is necessary and what the use case
> > is?
> > 
> > Are we sure we want a uAPI for this? RADV has been using SPM from
> > userspace
> > for many years now.
> 
> [JZ] current RADV SPM is for graphic engine. These patches are for
> compute engine SPM.
> 
> Thanks!

Is there any reason why it can't be done in userspace for compute too?


> > 
> >> ---
> >> 
> >>   include/uapi/drm/amdgpu_drm.h | 124 ++++++++++++++++++++++++++++++++++
> >>   1 file changed, 124 insertions(+)
> >> 
> >> diff --git a/include/uapi/drm/amdgpu_drm.h
> >> b/include/uapi/drm/amdgpu_drm.h
> >> index 9e5fa6f53e59..285949d63eb6 100644
> >> --- a/include/uapi/drm/amdgpu_drm.h
> >> +++ b/include/uapi/drm/amdgpu_drm.h
> >> @@ -60,6 +60,7 @@ extern "C" {
> >> 
> >>   #define DRM_AMDGPU_GEM_LIST_HANDLES      0x19
> >>   #define DRM_AMDGPU_PROC_OPTIONS          0x1A
> >>   #define DRM_AMDGPU_TRAP                  0x1B
> >> 
> >> +#define DRM_AMDGPU_PROFILER               0x1C
> >> 
> >>   #define DRM_IOCTL_AMDGPU_GEM_CREATE      DRM_IOWR(DRM_COMMAND_BASE +
> >> 
> >> DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) #define
> >> DRM_IOCTL_AMDGPU_GEM_MMAP  DRM_IOWR(DRM_COMMAND_BASE +
> >> DRM_AMDGPU_GEM_MMAP,
> >> union drm_amdgpu_gem_mmap) @@ -83,6 +84,7 @@ extern "C" {
> >> 
> >>   #define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE +
> >> 
> >> DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles) #define
> >> DRM_IOCTL_AMDGPU_PROC_OPTIONS      DRM_IOWR(DRM_COMMAND_BASE +
> >> DRM_AMDGPU_PROC_OPTIONS, struct drm_amdgpu_proc_options) #define
> >> DRM_IOCTL_AMDGPU_TRAP      DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_TRAP,
> > 
> > union
> > 
> >> drm_amdgpu_trap) +#define
> >> DRM_IOCTL_AMDGPU_PROFILER  DRM_IOWR(DRM_COMMAND_BASE +
> > 
> > DRM_AMDGPU_PROFILER,
> > 
> >> struct drm_amdgpu_profiler_args)
> >> 
> >>   /**
> >>   
> >>    * DOC: memory domains
> >> 
> >> @@ -1821,6 +1823,128 @@ struct drm_amdgpu_proc_options {
> >> 
> >>    } kfd_sigbus_delay;
> >>   
> >>   };
> >> 
> >> +/*
> >> + * Supported SPM (Stream Performance Monitor) Operations
> >> + */
> >> +/**
> >> + * drm_amdgpu_spm_op - SPM ioctl operations
> >> + */
> >> +enum drm_amdgpu_spm_op {
> >> +  AMDGPU_SPM_OP_ACQUIRE = 1,
> >> +  AMDGPU_SPM_OP_RELEASE,
> >> +  AMDGPU_SPM_OP_SET_DEST_BUF
> >> +};
> >> +
> >> +/**
> >> + * drm_amdgpu_spm_args - Arguments for SPM ioctl
> >> + *
> >> + * @dest_buf: [in] used for the address of the destination buffer
> >> + *            in @AMDGPU_SPM_OP_SET_DEST_BUF
> >> + * @buf_size: [in] size of the destination buffer
> >> + * @op: [in] specifies the operation to perform
> >> + * @timeout: [in/out] timeout in milliseconds (in), amount of time left
> >> + *           in the timeout window (out)
> >> + * @bytes_copied: [out] total amount of data that was copied to the
> >> previous dest_buf + * @has_data_loss: [out] non-zero if data was lost
> >> (e.g.
> >> due to ring buffer overflow), + *                 zero otherwise
> >> + * @reserved: must be zero for forward compatibility
> >> + *
> >> + * This ioctl performs different functions depending on the @op
> >> parameter.
> >> + *
> >> + * AMDGPU_SPM_OP_ACQUIRE
> >> + * ------------------------
> >> + *
> >> + * Acquires exclusive access of SPM on the specified XCP for the calling
> >> process. + * This must be called before using AMDGPU_SPM_OP_SET_DEST_BUF.
> >> + *
> >> + * AMDGPU_SPM_OP_RELEASE
> >> + * ------------------------
> >> + *
> >> + * Releases exclusive access of SPM on the specified XCP for the calling
> >> process, + * which allows another process to acquire it in the future.
> >> + *
> >> + * AMDGPU_SPM_OP_SET_DEST_BUF
> >> + * -----------------------------
> >> + *
> >> + * If @dest_buf is NULL, the destination buffer address is unset and
> >> copying of counters + * is stopped.
> >> + *
> >> + * If @dest_buf is not NULL, it specifies the pointer to a new
> >> destination
> >> buffer. + * @buf_size specifies the size of the buffer.
> >> + *
> >> + * If @timeout is non-0, the call will wait for up to @timeout ms for
> >> the
> >> previous + * buffer to be filled. If the previous buffer is filled before
> >> the timeout, @timeout + * is updated with the time remaining. If the
> >> timeout is exceeded, the function + * copies any partial data available
> >> into the previous user buffer and returns success. + * The amount of
> >> valid
> >> data in the previous user buffer is indicated by @bytes_copied. + *
> >> + * If @timeout is 0, the function immediately replaces the previous
> >> destination buffer + * without waiting for the previous buffer to be
> >> filled. That means the previous buffer + * may only be partially filled,
> >> and @bytes_copied will indicate how much data has been + * copied to it.
> >> + *
> >> + * If data was lost, e.g. due to a ring buffer overflow, @has_data_loss
> >> will be non-0. + *
> >> + * Returns negative error code on failure, 0 on success.
> >> + */
> >> +struct drm_amdgpu_spm_args {
> >> +  __u64 dest_buf;
> >> +  __u32 buf_size;
> >> +  __u32 op;
> >> +  __u32 timeout;
> >> +  __u32 bytes_copied;
> >> +  __u32 has_data_loss;
> >> +  __u32 reserved[9];      /* must be zero; pads this struct to 64
> > 
> > bytes */
> > 
> >> +};
> >> +
> >> +/**
> >> + * drm_amdgpu_spm_buffer_header - SPM Buffer header for
> >> drm_amdgpu_spm_args->dest_buf + *
> >> + * @version:       [out] SPM version (0-23: minor, 24-31: major)
> >> + * @bytes_copied:  [out] Amount of data copied for this sub-block
> >> + * @has_data_loss: [out] Boolean indicating whether data was lost for
> >> this
> >> sub-block + *                       (e.g. due to a ring-buffer overflow)
> >> + * @reserved:      Reserved for future use, must be zero
> >> + *
> >> + * This header precedes the SPM data in the destination buffer. The
> >> reserved + * field maintains 64-byte cache line alignment (32 bytes
> >> total).
> >> + */
> >> +struct drm_amdgpu_spm_buffer_header {
> >> +  __u32 version; /* 0-23: minor, 24-31: major */
> >> +  __u32 bytes_copied;
> >> +  __u32 has_data_loss;
> >> +  __u32 reserved[5]; /* pad to 32 bytes (64-byte cache line / 2) */
> >> +};
> >> +
> >> +/* Supported Profiler Operation */
> >> +#define AMDGPU_PROFILER_OP_GET_VER                1 /* get profiler UAPI
> > 
> > version */
> > 
> >> +#define AMDGPU_PROFILER_OP_SPM                    2
> >> +
> >> +/*
> >> + * Profiler IOCTL
> >> + */
> >> +/**
> >> + * struct drm_amdgpu_profiler_args - Profiler IOCTL arguments
> >> + * @op: Operation to perform (AMDGPU_PROFILER_OP_*)
> >> + * @pad: Must be zero for input validation
> >> + * @data: Operation-specific parameters (union)
> >> + *
> >> + * GET_VER operation:
> >> + * Returns the profiler UAPI version in @data.version as (MAJOR<<24) |
> >> MINOR. + * Input: @data must be zero (reserved for forward
> >> compatibility).
> >> + *
> >> + * Design note: GET_VER is intentionally a parameter-free query
> >> returning
> >> + * the global profiler UAPI version.
> >> + */
> >> +struct drm_amdgpu_profiler_args {
> >> +  __u32 op;                               /*
> > 
> > AMDGPU_PROFILER_OP_* */
> > 
> >> +  __u32 pad;                              /* must be zero */
> >> +  union {
> >> +          __u32 version;          /* GET_VER: out
> > 
> > (MAJOR<<24) | MINOR */
> > 
> >> +          struct drm_amdgpu_spm_args spm;
> >> +  } data;
> >> +};
> >> +
> >> 
> >>   #if defined(__cplusplus)
> >>   }
> >>   #endif




Reply via email to