[PATCH 16/16] drm/amdgpu: user doorbell mgr for MES process doorbells

Shashank Sharma shashank.sharma at amd.com
Wed Mar 29 15:47:53 UTC 2023


This patch:
- Adds a amdgpu_doorbell object in MES process.
- Allocs doorbell pages for MES process using doorbell manager.
- uses doorbell manager to get an absolute index of doorbells.
- removes a offset calculation function which is no more required.
- removes prototype of a few functions which are not required.

PS: This patch ensures that we don't break the existing KFD
    functionality, but now KFD userspace library must also
    move to creating doorbell pages as AMDGPU GEM objects
    using libdrm functions in userspace. The reference code
    for the same is available with AMDGPU Usermode queue
    libdrm MR.

Cc: Alex Deucher <alexander.deucher at amd.com>
Cc: Christian Koenig <christian.koenig at amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma at amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 60 ++++++++++++-------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 12 ++---
 2 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 423cd642647c..7c6cf3d2c8ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -36,33 +36,40 @@ int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev)
 		       PAGE_SIZE);
 }
 
-int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
-				      unsigned int *doorbell_index)
+static int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
+					       struct amdgpu_mes_process *process)
 {
-	int r = ida_simple_get(&adev->mes.doorbell_ida, 2,
-			       adev->mes.max_doorbell_slices,
-			       GFP_KERNEL);
-	if (r > 0)
-		*doorbell_index = r;
+	int r;
+	struct amdgpu_doorbell_obj *proc_doorbells = &process->proc_doorbells;
+
+	/* Bitmap for dynamic allocation of doorbell */
+	proc_doorbells->doorbell_bitmap = bitmap_zalloc(
+					  AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
+					  GFP_KERNEL);
+	if (!proc_doorbells->doorbell_bitmap) {
+		DRM_ERROR("failed to allocate MES process doorbell bitmap\n");
+		return -ENOMEM;
+	}
+
+	/* Reserve actual doorbells from the BAR */
+	proc_doorbells->size = amdgpu_mes_doorbell_process_slice(adev);
+	r = amdgpu_doorbell_alloc_page(adev, proc_doorbells);
+	if (r) {
+		bitmap_free(proc_doorbells->doorbell_bitmap);
+		DRM_ERROR("failed to allocate MES process doorbells\n");
+		return r;
+	}
 
 	return r;
 }
 
 void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev,
-				      unsigned int doorbell_index)
+				       struct amdgpu_mes_process *process)
 {
-	if (doorbell_index)
-		ida_simple_remove(&adev->mes.doorbell_ida, doorbell_index);
-}
+	struct amdgpu_doorbell_obj *proc_doorbells = &process->proc_doorbells;
 
-unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
-					struct amdgpu_device *adev,
-					uint32_t doorbell_index,
-					unsigned int doorbell_id)
-{
-	return ((doorbell_index *
-		amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32) +
-		doorbell_id * 2);
+	bitmap_free(proc_doorbells->doorbell_bitmap);
+	amdgpu_doorbell_free_page(adev, proc_doorbells);
 }
 
 static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev,
@@ -275,15 +282,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
 		return -ENOMEM;
 	}
 
-	process->doorbell_bitmap =
-		kzalloc(DIV_ROUND_UP(AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
-				     BITS_PER_BYTE), GFP_KERNEL);
-	if (!process->doorbell_bitmap) {
-		DRM_ERROR("failed to allocate doorbell bitmap\n");
-		kfree(process);
-		return -ENOMEM;
-	}
-
 	/* allocate the process context bo and map it */
 	r = amdgpu_bo_create_kernel(adev, AMDGPU_MES_PROC_CTX_SIZE, PAGE_SIZE,
 				    AMDGPU_GEM_DOMAIN_GTT,
@@ -311,7 +309,7 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
 	}
 
 	/* allocate the starting doorbell index of the process */
-	r = amdgpu_mes_alloc_process_doorbells(adev, &process->doorbell_index);
+	r = amdgpu_mes_alloc_process_doorbells(adev, process);
 	if (r < 0) {
 		DRM_ERROR("failed to allocate doorbell for process\n");
 		goto clean_up_pasid;
@@ -336,7 +334,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
 			      &process->proc_ctx_gpu_addr,
 			      &process->proc_ctx_cpu_ptr);
 clean_up_memory:
-	kfree(process->doorbell_bitmap);
 	kfree(process);
 	return r;
 }
@@ -382,7 +379,7 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid)
 		idr_remove(&adev->mes.gang_id_idr, gang->gang_id);
 	}
 
-	amdgpu_mes_free_process_doorbells(adev, process->doorbell_index);
+	amdgpu_mes_free_process_doorbells(adev, process);
 	idr_remove(&adev->mes.pasid_idr, pasid);
 	amdgpu_mes_unlock(&adev->mes);
 
@@ -404,7 +401,6 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid)
 	amdgpu_bo_free_kernel(&process->proc_ctx_bo,
 			      &process->proc_ctx_gpu_addr,
 			      &process->proc_ctx_cpu_ptr);
-	kfree(process->doorbell_bitmap);
 	kfree(process);
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index e7e9dfe44c99..0c659ade527c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -145,8 +145,10 @@ struct amdgpu_mes_process {
 	uint64_t 		process_quantum;
 	struct 			list_head gang_list;
 	uint32_t 		doorbell_index;
-	unsigned long 		*doorbell_bitmap;
 	struct mutex		doorbell_lock;
+
+	/* process doorbells */
+	struct amdgpu_doorbell_obj proc_doorbells;
 };
 
 struct amdgpu_mes_gang {
@@ -364,14 +366,6 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,
 
 int amdgpu_mes_self_test(struct amdgpu_device *adev);
 
-int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
-					unsigned int *doorbell_index);
-void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev,
-					unsigned int doorbell_index);
-unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
-					struct amdgpu_device *adev,
-					uint32_t doorbell_index,
-					unsigned int doorbell_id);
 int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev);
 
 /*
-- 
2.40.0



More information about the amd-gfx mailing list