summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDavid Yat Sin <David.YatSin@amd.com>2025-03-18 19:49:55 +0000
committerAlex Deucher <alexander.deucher@amd.com>2026-01-05 16:59:56 -0500
commitc51bb53d5c68041dd02f66d9b638cda33647623e (patch)
tree5e17df0916061685e11b68a176ffbe4df839581b /drivers/gpu
parentd0c989a0aad3ff047b72c89c91969a535f72dd2e (diff)
drm/amdkfd: Add metadata ring buffer for compute
Add support for separate ring-buffer for metadata packets when using compute queues. Userspace application allocate the metadata ring-buffer and the queue ring-buffer with a single allocation. The metadata ring-buffer starts after the queue ring-buffer. Signed-off-by: David Yat Sin <David.YatSin@amd.com> Reviewed-by: Philip Yang <Philip.Yang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c21
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_queue.c7
4 files changed, 36 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 041237861107..88621cb7d409 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -221,6 +221,11 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
pr_debug("Size lower. clamped to KFD_MIN_QUEUE_RING_SIZE");
}
+ if ((args->metadata_ring_size != 0) && !is_power_of_2(args->metadata_ring_size)) {
+ pr_err("Metadata ring size must be a power of 2 or 0\n");
+ return -EINVAL;
+ }
+
if (!access_ok((const void __user *) args->read_pointer_address,
sizeof(uint32_t))) {
pr_err("Can't access read pointer\n");
@@ -255,6 +260,9 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
q_properties->priority = args->queue_priority;
q_properties->queue_address = args->ring_base_address;
q_properties->queue_size = args->ring_size;
+ if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL)
+ q_properties->metadata_queue_size = args->metadata_ring_size;
+
q_properties->read_ptr = (void __user *)args->read_pointer_address;
q_properties->write_ptr = (void __user *)args->write_pointer_address;
q_properties->eop_ring_buffer_address = args->eop_buffer_address;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
index f1c2c9e8cf6b..a06b4e89af8a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c
@@ -266,6 +266,27 @@ static void update_mqd(struct mqd_manager *mm, void *mqd,
m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
+ if (q->metadata_queue_size) {
+ /* On GC 12.1 is 64 DWs which is 4 times size of AQL packet */
+ if (q->metadata_queue_size == q->queue_size * 4) {
+ /*
+ * User application allocates main queue ring and metadata queue ring
+ * with a single allocation. metadata queue ring starts after main
+ * queue ring.
+ */
+ m->cp_hqd_kd_base =
+ lower_32_bits((q->queue_address + q->queue_size) >> 8);
+ m->cp_hqd_kd_base_hi =
+ upper_32_bits((q->queue_address + q->queue_size) >> 8);
+
+ m->cp_hqd_kd_cntl |= CP_HQD_KD_CNTL__KD_FETCHER_ENABLE_MASK;
+ /* KD_SIZE = 2 for metadata packet = 64 DWs */
+ m->cp_hqd_kd_cntl |= 2 << CP_HQD_KD_CNTL__KD_SIZE__SHIFT;
+ } else {
+ pr_warn("Invalid metadata ring size, metadata queue will be ignored\n");
+ }
+ }
+
m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
m->cp_hqd_pq_wptr_poll_addr_lo = lower_32_bits((uint64_t)q->write_ptr);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index ebc637c38c04..d798baa7e52e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -506,7 +506,8 @@ struct queue_properties {
enum kfd_queue_format format;
unsigned int queue_id;
uint64_t queue_address;
- uint64_t queue_size;
+ uint64_t queue_size;
+ uint64_t metadata_queue_size;
uint32_t priority;
uint32_t queue_percent;
void __user *read_ptr;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
index 56c97189e7f1..1b465fdb2c64 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
@@ -247,9 +247,12 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
properties->format == KFD_QUEUE_FORMAT_AQL &&
topo_dev->node_props.gfx_target_version >= 70000 &&
topo_dev->node_props.gfx_target_version < 90000)
- expected_queue_size = properties->queue_size / 2;
+ /* metadata_queue_size not supported on GFX7/GFX8 */
+ expected_queue_size =
+ properties->queue_size / 2;
else
- expected_queue_size = properties->queue_size;
+ expected_queue_size =
+ properties->queue_size + properties->metadata_queue_size;
vm = drm_priv_to_vm(pdd->drm_priv);
err = amdgpu_bo_reserve(vm->root.bo, false);