diff --git a/include/drm-uapi/amdgpu_drm.h b/include/drm-uapi/amdgpu_drm.h index f41f9ae08d8..da35a2e66a3 100644 --- a/include/drm-uapi/amdgpu_drm.h +++ b/include/drm-uapi/amdgpu_drm.h @@ -333,6 +333,9 @@ union drm_amdgpu_ctx { #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 +#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_LOW 1 +#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_NORMAL_HIGH 2 +#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_HIGH 3 /* admin only */ /* for queues that need access to protected content */ #define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE (1 << 2) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.cpp b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.cpp index a6b89f00e38..fa512190aee 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.cpp +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.cpp @@ -982,7 +982,8 @@ amdgpu_cs_create(struct radeon_cmdbuf *rcs, goto fail; if (acs->aws->info.userq_ip_mask & BITFIELD_BIT(acs->ip_type)) { - if (!amdgpu_userq_init(acs->aws, &acs->aws->queues[acs->queue_index].userq, ip_type)) + if (!amdgpu_userq_init(acs->aws, &acs->aws->queues[acs->queue_index].userq, ip_type, + acs->queue_index)) goto fail; } diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_userq.c b/src/gallium/winsys/amdgpu/drm/amdgpu_userq.c index be5f42f9235..9a50d79fc20 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_userq.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_userq.c @@ -78,10 +78,11 @@ amdgpu_userq_deinit(struct amdgpu_winsys *aws, struct amdgpu_userq *userq) } bool -amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum amd_ip_type ip_type) +amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum amd_ip_type ip_type, + unsigned queue_index) { int r = -1; - uint32_t hw_ip_type, flags; + uint32_t hw_ip_type; 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,9 +99,6 @@ 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; @@ -178,11 +176,24 @@ amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum am } uint64_t ring_va = amdgpu_bo_get_va(userq->gtt_bo); - r = ac_drm_create_userqueue(aws->dev, hw_ip_type, - 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, flags, &userq->userq_handle); + unsigned priority = queue_index == AMDGPU_QUEUE_GFX_HIGH_PRIO ? + AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_HIGH : + AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_NORMAL_LOW; + + while (1) { + r = ac_drm_create_userqueue(aws->dev, hw_ip_type, + 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, priority, &userq->userq_handle); + if (r == -EACCES && priority == AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_HIGH) { + /* Try again with a lower priority. */ + priority = AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_NORMAL_HIGH; + continue; + } + break; + } + if (r) { fprintf(stderr, "amdgpu: failed to create userq\n"); goto fail; diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_userq.h b/src/gallium/winsys/amdgpu/drm/amdgpu_userq.h index 97364a48848..809ee4b5255 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_userq.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_userq.h @@ -86,7 +86,8 @@ struct amdgpu_userq { }; bool -amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum amd_ip_type ip_type); +amdgpu_userq_init(struct amdgpu_winsys *aws, struct amdgpu_userq *userq, enum amd_ip_type ip_type, + unsigned queue_index); void amdgpu_userq_deinit(struct amdgpu_winsys *aws, struct amdgpu_userq *userq);