* [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x
@ 2026-08-20 15:36 Sreekant Somasekharan
2026-08-27 16:27 ` Somasekharan, Sreekant
2026-08-27 16:39 ` Kuehling, Felix
0 siblings, 2 replies; 3+ messages in thread
From: Sreekant Somasekharan @ 2026-08-20 15:36 UTC (permalink / raw)
To: amd-gfx; +Cc: harish.kasiviswanathan, Sreekant Somasekharan
When all HW SDMA slots are exhausted on GFX 12.0.x with MES enabled,
allow new queues to reuse HW queue IDs round-robin via a dedicated
monotonic rotor. Each oversubscribed queue gets a unique doorbell from
the per-process bitmap pool so MES can multiplex them independently.
Normal SDMA queues and all other GPU generations are unaffected.
Assisted-by: Claude:Sonnet 4.6
Signed-off-by: Sreekant Somasekharan <Sreekant.Somasekharan@amd.com>
---
.../drm/amd/amdkfd/kfd_device_queue_manager.c | 54 +++++++++++++++----
.../drm/amd/amdkfd/kfd_device_queue_manager.h | 4 ++
drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 +
3 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index a23384571193..10a672b87ca5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -556,8 +556,9 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
return -EINVAL;
q->doorbell_id = q->properties.queue_id;
- } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
- q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
+ } else if ((q->properties.type == KFD_QUEUE_TYPE_SDMA ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) &&
+ !q->properties.is_oversubscribed) {
/* For SDMA queues on SOC15 with 8-byte doorbell, use static
* doorbell assignments based on the engine and queue id.
* The doobell index distance between RLC (2*i) and (2*i+1)
@@ -583,7 +584,10 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
return -EINVAL;
q->doorbell_id = valid_id;
} else {
- /* For CP queues on SOC15 */
+ /* For CP queues on SOC15, and oversubscribed SDMA queues which
+ * reuse HW queue ids and so need a unique doorbell allocated
+ * from the per-process bitmap pool.
+ */
if (restore_id) {
if (*restore_id >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
return -EINVAL;
@@ -621,9 +625,14 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
unsigned int old;
struct kfd_node *dev = qpd->dqm->dev;
+ /* Oversubscribed SDMA queues allocate a doorbell from the bitmap pool
+ * (like CP queues), so they must be freed; normal SDMA queues use
+ * static doorbell assignments and must not be.
+ */
if (!KFD_IS_SOC15(dev) ||
- q->properties.type == KFD_QUEUE_TYPE_SDMA ||
- q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
+ ((q->properties.type == KFD_QUEUE_TYPE_SDMA ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) &&
+ !q->properties.is_oversubscribed))
return;
old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap);
@@ -1800,15 +1809,33 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
{
struct device *dev = dqm->dev->adev->dev;
int bit;
+ bool is_oversubscribed = false;
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
if (bitmap_empty(dqm->sdma_bitmap, get_num_sdma_queues(dqm))) {
- dev_warn(dev, "No more SDMA queue to allocate (%d total queues)\n",
- get_num_sdma_queues(dqm));
- return -ENOMEM;
- }
+ /* All HW queues are busy. On GFX 12.0.x under MES,
+ * oversubscribe by reusing a HW queue id round-robin;
+ * MES multiplexes the SW queues via their unique
+ * doorbells. The non-MES HWS runlist path cannot express
+ * duplicate sdma_ids, so it still fails with -ENOMEM.
+ */
+ unsigned int num_reserved, num_available;
+
+ if (KFD_GC_VERSION(dqm->dev) < IP_VERSION(12, 0, 0) ||
+ KFD_GC_VERSION(dqm->dev) >= IP_VERSION(12, 1, 0) ||
+ !dqm->dev->kfd->shared_resources.enable_mes) {
+ dev_warn(dev, "No more SDMA queue to allocate (%d total queues)\n",
+ get_num_sdma_queues(dqm));
+ return -ENOMEM;
+ }
- if (restore_sdma_id) {
+ num_reserved = kfd_get_num_sdma_engines(dqm->dev) *
+ dqm->dev->kfd->device_info.num_reserved_sdma_queues_per_engine;
+ num_available = get_num_sdma_queues(dqm) - num_reserved;
+ q->sdma_id = num_reserved +
+ dqm->sdma_oversub_rotor++ % num_available;
+ is_oversubscribed = true;
+ } else if (restore_sdma_id) {
if (*restore_sdma_id >= get_num_sdma_queues(dqm))
return -EINVAL;
@@ -1901,6 +1928,7 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
return -ENOMEM;
}
}
+ q->properties.is_oversubscribed = is_oversubscribed;
pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id);
@@ -1914,7 +1942,11 @@ static void deallocate_sdma_queue(struct device_queue_manager *dqm,
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
if (q->sdma_id >= get_num_sdma_queues(dqm))
return;
- set_bit(q->sdma_id, dqm->sdma_bitmap);
+ /* Don't return oversubscribed queue IDs to bitmap.
+ * They are shared by multiple queues and managed via round-robin.
+ */
+ if (!q->properties.is_oversubscribed)
+ set_bit(q->sdma_id, dqm->sdma_bitmap);
} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
if (q->sdma_id >= get_num_xgmi_sdma_queues(dqm))
return;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index c9f9f7a87111..81626e657055 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -255,6 +255,10 @@ struct device_queue_manager {
unsigned int gws_queue_count;
unsigned int total_queue_count;
unsigned int next_pipe_to_allocate;
+ /* Monotonically increasing counter used to round-robin oversubscribed
+ * SDMA queues across the available HW queue slots.
+ */
+ unsigned int sdma_oversub_rotor;
unsigned int *allocated_queues;
DECLARE_BITMAP(sdma_bitmap, KFD_MAX_SDMA_QUEUES);
DECLARE_BITMAP(xgmi_sdma_bitmap, KFD_MAX_SDMA_QUEUES);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index d8631847f0eb..5fff5e55fb09 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -531,6 +531,7 @@ struct queue_properties {
bool is_dbg_wa;
bool is_user_cu_masked;
bool is_reset;
+ bool is_oversubscribed;
/* Not relevant for user mode queues in cp scheduling */
unsigned int vmid;
/* Relevant only for sdma queues*/
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x
2026-08-20 15:36 [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x Sreekant Somasekharan
@ 2026-08-27 16:27 ` Somasekharan, Sreekant
2026-08-27 16:39 ` Kuehling, Felix
1 sibling, 0 replies; 3+ messages in thread
From: Somasekharan, Sreekant @ 2026-08-27 16:27 UTC (permalink / raw)
To: amd-gfx@lists.freedesktop.org
Cc: Kasiviswanathan, Harish, Kuehling, Felix, Yang, Philip
AMD General
ping
Regards,
-Sreekant
-----Original Message-----
From: Somasekharan, Sreekant <Sreekant.Somasekharan@amd.com>
Sent: August 20, 2026 11:36 AM
To: amd-gfx@lists.freedesktop.org
Cc: Kasiviswanathan, Harish <Harish.Kasiviswanathan@amd.com>; Somasekharan, Sreekant <Sreekant.Somasekharan@amd.com>
Subject: [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x
When all HW SDMA slots are exhausted on GFX 12.0.x with MES enabled, allow new queues to reuse HW queue IDs round-robin via a dedicated monotonic rotor. Each oversubscribed queue gets a unique doorbell from the per-process bitmap pool so MES can multiplex them independently.
Normal SDMA queues and all other GPU generations are unaffected.
Assisted-by: Claude:Sonnet 4.6
Signed-off-by: Sreekant Somasekharan <Sreekant.Somasekharan@amd.com>
---
.../drm/amd/amdkfd/kfd_device_queue_manager.c | 54 +++++++++++++++---- .../drm/amd/amdkfd/kfd_device_queue_manager.h | 4 ++
drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 +
3 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index a23384571193..10a672b87ca5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -556,8 +556,9 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
return -EINVAL;
q->doorbell_id = q->properties.queue_id;
- } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
- q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
+ } else if ((q->properties.type == KFD_QUEUE_TYPE_SDMA ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) &&
+ !q->properties.is_oversubscribed) {
/* For SDMA queues on SOC15 with 8-byte doorbell, use static
* doorbell assignments based on the engine and queue id.
* The doobell index distance between RLC (2*i) and (2*i+1) @@ -583,7 +584,10 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
return -EINVAL;
q->doorbell_id = valid_id;
} else {
- /* For CP queues on SOC15 */
+ /* For CP queues on SOC15, and oversubscribed SDMA queues which
+ * reuse HW queue ids and so need a unique doorbell allocated
+ * from the per-process bitmap pool.
+ */
if (restore_id) {
if (*restore_id >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
return -EINVAL;
@@ -621,9 +625,14 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
unsigned int old;
struct kfd_node *dev = qpd->dqm->dev;
+ /* Oversubscribed SDMA queues allocate a doorbell from the bitmap pool
+ * (like CP queues), so they must be freed; normal SDMA queues use
+ * static doorbell assignments and must not be.
+ */
if (!KFD_IS_SOC15(dev) ||
- q->properties.type == KFD_QUEUE_TYPE_SDMA ||
- q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
+ ((q->properties.type == KFD_QUEUE_TYPE_SDMA ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) &&
+ !q->properties.is_oversubscribed))
return;
old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap); @@ -1800,15 +1809,33 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm, {
struct device *dev = dqm->dev->adev->dev;
int bit;
+ bool is_oversubscribed = false;
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
if (bitmap_empty(dqm->sdma_bitmap, get_num_sdma_queues(dqm))) {
- dev_warn(dev, "No more SDMA queue to allocate (%d total queues)\n",
- get_num_sdma_queues(dqm));
- return -ENOMEM;
- }
+ /* All HW queues are busy. On GFX 12.0.x under MES,
+ * oversubscribe by reusing a HW queue id round-robin;
+ * MES multiplexes the SW queues via their unique
+ * doorbells. The non-MES HWS runlist path cannot express
+ * duplicate sdma_ids, so it still fails with -ENOMEM.
+ */
+ unsigned int num_reserved, num_available;
+
+ if (KFD_GC_VERSION(dqm->dev) < IP_VERSION(12, 0, 0) ||
+ KFD_GC_VERSION(dqm->dev) >= IP_VERSION(12, 1, 0) ||
+ !dqm->dev->kfd->shared_resources.enable_mes) {
+ dev_warn(dev, "No more SDMA queue to allocate (%d total queues)\n",
+ get_num_sdma_queues(dqm));
+ return -ENOMEM;
+ }
- if (restore_sdma_id) {
+ num_reserved = kfd_get_num_sdma_engines(dqm->dev) *
+ dqm->dev->kfd->device_info.num_reserved_sdma_queues_per_engine;
+ num_available = get_num_sdma_queues(dqm) - num_reserved;
+ q->sdma_id = num_reserved +
+ dqm->sdma_oversub_rotor++ % num_available;
+ is_oversubscribed = true;
+ } else if (restore_sdma_id) {
if (*restore_sdma_id >= get_num_sdma_queues(dqm))
return -EINVAL;
@@ -1901,6 +1928,7 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
return -ENOMEM;
}
}
+ q->properties.is_oversubscribed = is_oversubscribed;
pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id); @@ -1914,7 +1942,11 @@ static void deallocate_sdma_queue(struct device_queue_manager *dqm,
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
if (q->sdma_id >= get_num_sdma_queues(dqm))
return;
- set_bit(q->sdma_id, dqm->sdma_bitmap);
+ /* Don't return oversubscribed queue IDs to bitmap.
+ * They are shared by multiple queues and managed via round-robin.
+ */
+ if (!q->properties.is_oversubscribed)
+ set_bit(q->sdma_id, dqm->sdma_bitmap);
} else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
if (q->sdma_id >= get_num_xgmi_sdma_queues(dqm))
return;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index c9f9f7a87111..81626e657055 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -255,6 +255,10 @@ struct device_queue_manager {
unsigned int gws_queue_count;
unsigned int total_queue_count;
unsigned int next_pipe_to_allocate;
+ /* Monotonically increasing counter used to round-robin oversubscribed
+ * SDMA queues across the available HW queue slots.
+ */
+ unsigned int sdma_oversub_rotor;
unsigned int *allocated_queues;
DECLARE_BITMAP(sdma_bitmap, KFD_MAX_SDMA_QUEUES);
DECLARE_BITMAP(xgmi_sdma_bitmap, KFD_MAX_SDMA_QUEUES); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index d8631847f0eb..5fff5e55fb09 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -531,6 +531,7 @@ struct queue_properties {
bool is_dbg_wa;
bool is_user_cu_masked;
bool is_reset;
+ bool is_oversubscribed;
/* Not relevant for user mode queues in cp scheduling */
unsigned int vmid;
/* Relevant only for sdma queues*/
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x
2026-08-20 15:36 [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x Sreekant Somasekharan
2026-08-27 16:27 ` Somasekharan, Sreekant
@ 2026-08-27 16:39 ` Kuehling, Felix
1 sibling, 0 replies; 3+ messages in thread
From: Kuehling, Felix @ 2026-08-27 16:39 UTC (permalink / raw)
To: Sreekant Somasekharan, amd-gfx; +Cc: harish.kasiviswanathan
On 2026-08-20 11:36, Sreekant Somasekharan wrote:
> When all HW SDMA slots are exhausted on GFX 12.0.x with MES enabled,
> allow new queues to reuse HW queue IDs round-robin via a dedicated
> monotonic rotor. Each oversubscribed queue gets a unique doorbell from
> the per-process bitmap pool so MES can multiplex them independently.
This special handling of doorbells for oversubscribed SDMA queues is
only needed if you use more queues than doorbells _in the same process_.
Across multiple processes this is not needed, because each process gets
a unique set of doorbells.
Is the goal of this change really to enable oversubscription of SDMA
queue slots by a single process? Is that even useful? Do you have a use
case for that?
Regards,
Felix
>
> Normal SDMA queues and all other GPU generations are unaffected.
>
> Assisted-by: Claude:Sonnet 4.6
> Signed-off-by: Sreekant Somasekharan <Sreekant.Somasekharan@amd.com>
> ---
> .../drm/amd/amdkfd/kfd_device_queue_manager.c | 54 +++++++++++++++----
> .../drm/amd/amdkfd/kfd_device_queue_manager.h | 4 ++
> drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 +
> 3 files changed, 48 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> index a23384571193..10a672b87ca5 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> @@ -556,8 +556,9 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
> return -EINVAL;
>
> q->doorbell_id = q->properties.queue_id;
> - } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
> - q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
> + } else if ((q->properties.type == KFD_QUEUE_TYPE_SDMA ||
> + q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) &&
> + !q->properties.is_oversubscribed) {
> /* For SDMA queues on SOC15 with 8-byte doorbell, use static
> * doorbell assignments based on the engine and queue id.
> * The doobell index distance between RLC (2*i) and (2*i+1)
> @@ -583,7 +584,10 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
> return -EINVAL;
> q->doorbell_id = valid_id;
> } else {
> - /* For CP queues on SOC15 */
> + /* For CP queues on SOC15, and oversubscribed SDMA queues which
> + * reuse HW queue ids and so need a unique doorbell allocated
> + * from the per-process bitmap pool.
> + */
> if (restore_id) {
> if (*restore_id >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
> return -EINVAL;
> @@ -621,9 +625,14 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
> unsigned int old;
> struct kfd_node *dev = qpd->dqm->dev;
>
> + /* Oversubscribed SDMA queues allocate a doorbell from the bitmap pool
> + * (like CP queues), so they must be freed; normal SDMA queues use
> + * static doorbell assignments and must not be.
> + */
> if (!KFD_IS_SOC15(dev) ||
> - q->properties.type == KFD_QUEUE_TYPE_SDMA ||
> - q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
> + ((q->properties.type == KFD_QUEUE_TYPE_SDMA ||
> + q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) &&
> + !q->properties.is_oversubscribed))
> return;
>
> old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap);
> @@ -1800,15 +1809,33 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
> {
> struct device *dev = dqm->dev->adev->dev;
> int bit;
> + bool is_oversubscribed = false;
>
> if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
> if (bitmap_empty(dqm->sdma_bitmap, get_num_sdma_queues(dqm))) {
> - dev_warn(dev, "No more SDMA queue to allocate (%d total queues)\n",
> - get_num_sdma_queues(dqm));
> - return -ENOMEM;
> - }
> + /* All HW queues are busy. On GFX 12.0.x under MES,
> + * oversubscribe by reusing a HW queue id round-robin;
> + * MES multiplexes the SW queues via their unique
> + * doorbells. The non-MES HWS runlist path cannot express
> + * duplicate sdma_ids, so it still fails with -ENOMEM.
> + */
> + unsigned int num_reserved, num_available;
> +
> + if (KFD_GC_VERSION(dqm->dev) < IP_VERSION(12, 0, 0) ||
> + KFD_GC_VERSION(dqm->dev) >= IP_VERSION(12, 1, 0) ||
> + !dqm->dev->kfd->shared_resources.enable_mes) {
> + dev_warn(dev, "No more SDMA queue to allocate (%d total queues)\n",
> + get_num_sdma_queues(dqm));
> + return -ENOMEM;
> + }
>
> - if (restore_sdma_id) {
> + num_reserved = kfd_get_num_sdma_engines(dqm->dev) *
> + dqm->dev->kfd->device_info.num_reserved_sdma_queues_per_engine;
> + num_available = get_num_sdma_queues(dqm) - num_reserved;
> + q->sdma_id = num_reserved +
> + dqm->sdma_oversub_rotor++ % num_available;
> + is_oversubscribed = true;
> + } else if (restore_sdma_id) {
> if (*restore_sdma_id >= get_num_sdma_queues(dqm))
> return -EINVAL;
>
> @@ -1901,6 +1928,7 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm,
> return -ENOMEM;
> }
> }
> + q->properties.is_oversubscribed = is_oversubscribed;
>
> pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
> pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id);
> @@ -1914,7 +1942,11 @@ static void deallocate_sdma_queue(struct device_queue_manager *dqm,
> if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
> if (q->sdma_id >= get_num_sdma_queues(dqm))
> return;
> - set_bit(q->sdma_id, dqm->sdma_bitmap);
> + /* Don't return oversubscribed queue IDs to bitmap.
> + * They are shared by multiple queues and managed via round-robin.
> + */
> + if (!q->properties.is_oversubscribed)
> + set_bit(q->sdma_id, dqm->sdma_bitmap);
> } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
> if (q->sdma_id >= get_num_xgmi_sdma_queues(dqm))
> return;
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
> index c9f9f7a87111..81626e657055 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
> @@ -255,6 +255,10 @@ struct device_queue_manager {
> unsigned int gws_queue_count;
> unsigned int total_queue_count;
> unsigned int next_pipe_to_allocate;
> + /* Monotonically increasing counter used to round-robin oversubscribed
> + * SDMA queues across the available HW queue slots.
> + */
> + unsigned int sdma_oversub_rotor;
> unsigned int *allocated_queues;
> DECLARE_BITMAP(sdma_bitmap, KFD_MAX_SDMA_QUEUES);
> DECLARE_BITMAP(xgmi_sdma_bitmap, KFD_MAX_SDMA_QUEUES);
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> index d8631847f0eb..5fff5e55fb09 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> @@ -531,6 +531,7 @@ struct queue_properties {
> bool is_dbg_wa;
> bool is_user_cu_masked;
> bool is_reset;
> + bool is_oversubscribed;
> /* Not relevant for user mode queues in cp scheduling */
> unsigned int vmid;
> /* Relevant only for sdma queues*/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-27 16:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20 15:36 [PATCH] drm/amdkfd: Enable SDMA queue oversubscription for GFX 12.0.x Sreekant Somasekharan
2026-08-27 16:27 ` Somasekharan, Sreekant
2026-08-27 16:39 ` Kuehling, Felix
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox