winsys/amdgpu: Add support for queue priority in Mesa
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

This patch adds support for queue priority levels in Mesa's AMDGPU winsys layer.
The changes include:

1. Updated ac_drm_create_userqueue() to accept and pass through flags parameter
2. Modified amdgpu_userq_init() to use the flags when creating queues
3. Added flags field to amdgpu_userq struct to store priority settings
4. Updated header definitions to match kernel UAPI changes

This aligns with the kernel changes provided by Alex:
https://lists.freedesktop.org/archives/amd-gfx/2025-April/122782.html
https://lists.freedesktop.org/archives/amd-gfx/2025-April/122780.html
https://lists.freedesktop.org/archives/amd-gfx/2025-April/122786.html

v2: We only need 1 normal priority queue and 1 TMZ normal priority queue.(Marek Olšák)
v3: Simplified to only support normal priority queues
v4: use a local variable instead of being in struct amdgpu_userq.(Marek Olšák)
v5: rebase the latest main branch.

Signed-off-by: Jesse.Zhang <Jesse.zhang@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34568>
This commit is contained in:
Jesse.Zhang 2025-05-06 10:19:04 +08:00 committed by Marge Bot
parent 870d17012a
commit d8624e6a79
5 changed files with 18 additions and 5 deletions

View file

@ -329,6 +329,13 @@ union drm_amdgpu_ctx {
#define AMDGPU_USERQ_OP_CREATE 1
#define AMDGPU_USERQ_OP_FREE 2
/* queue priority levels */
#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK 0x3
#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_SHIFT 0
#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_NORMAL_LOW 0
/* for queues that need access to protected content */
#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE (1 << 2)
/*
* This structure is a container to pass input configuration
* info for all supported userqueue related operations.
@ -355,7 +362,7 @@ struct drm_amdgpu_userq_in {
* and doorbell_offset in the doorbell bo.
*/
__u32 doorbell_offset;
__u32 _pad;
__u32 flags;
/**
* @queue_va: Virtual address of the GPU memory which holds the queue
* object. The queue holds the workload packets.

View file

@ -996,7 +996,7 @@ int ac_drm_va_range_free(amdgpu_va_handle va_range_handle)
int ac_drm_create_userqueue(ac_drm_device *dev, uint32_t ip_type, uint32_t doorbell_handle,
uint32_t doorbell_offset, uint64_t queue_va, uint64_t queue_size,
uint64_t wptr_va, uint64_t rptr_va, void *mqd_in, uint32_t *queue_id)
uint64_t wptr_va, uint64_t rptr_va, void *mqd_in, uint32_t flags, uint32_t *queue_id)
{
int ret;
union drm_amdgpu_userq userq;
@ -1037,6 +1037,7 @@ int ac_drm_create_userqueue(ac_drm_device *dev, uint32_t ip_type, uint32_t doorb
userq.in.mqd = (uintptr_t)mqd_in;
userq.in.mqd_size = mqd_size;
userq.in.flags = flags;
ret = drm_ioctl_write_read(dev->fd, DRM_AMDGPU_USERQ,
&userq, sizeof(userq));

View file

@ -152,7 +152,7 @@ PROC int ac_drm_va_range_alloc(ac_drm_device *dev, enum amdgpu_gpu_va_range va_r
PROC int ac_drm_va_range_free(amdgpu_va_handle va_range_handle) TAIL;
PROC int ac_drm_create_userqueue(ac_drm_device *dev, uint32_t ip_type, uint32_t doorbell_handle,
uint32_t doorbell_offset, uint64_t queue_va, uint64_t queue_size,
uint64_t wptr_va, uint64_t rptr_va, void *mqd_in,
uint64_t wptr_va, uint64_t rptr_va, void *mqd_in, uint32_t flags,
uint32_t *queue_id) TAIL;
PROC int ac_drm_free_userqueue(ac_drm_device *dev, uint32_t queue_id) TAIL;
PROC int ac_drm_userq_signal(ac_drm_device *dev, struct drm_amdgpu_userq_signal *signal_data) TAIL;

View file

@ -81,7 +81,7 @@ bool
amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum amd_ip_type ip_type)
{
int r = -1;
uint32_t hw_ip_type;
uint32_t hw_ip_type, flags;
struct drm_amdgpu_userq_mqd_gfx11 gfx_mqd;
struct drm_amdgpu_userq_mqd_compute_gfx11 compute_mqd;
struct drm_amdgpu_userq_mqd_sdma_gfx11 sdma_mqd;
@ -98,6 +98,9 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
if (!amdgpu_userq_ring_init(aws, userq))
goto fail;
/* Set normal priority for the user queue. */
flags = AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_NORMAL_LOW;
switch (userq->ip_type) {
case AMD_IP_GFX:
hw_ip_type = AMDGPU_HW_IP_GFX;
@ -179,7 +182,7 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am
get_real_bo(amdgpu_winsys_bo(userq->doorbell_bo))->kms_handle,
AMDGPU_USERQ_DOORBELL_INDEX, ring_va, AMDGPU_USERQ_RING_SIZE,
amdgpu_bo_get_va(userq->wptr_bo), amdgpu_bo_get_va(userq->rptr_bo),
mqd, &userq->userq_handle);
mqd, flags, &userq->userq_handle);
if (r) {
fprintf(stderr, "amdgpu: failed to create userq\n");
goto fail;

View file

@ -75,6 +75,8 @@ struct amdgpu_userq {
uint32_t userq_handle;
enum amd_ip_type ip_type;
simple_mtx_t lock;
/* flags used for queue priority level */
uint32_t flags;
union {
struct amdgpu_userq_gfx_data gfx_data;