[1/1] drm/amdkfd: Add queue status indicator to HQD dump

Submitted by Zeng, Oak on June 24, 2019, 1:41 p.m.

Details

Message ID BL0PR12MB2580E815546C102A24AD52A180E00@BL0PR12MB2580.namprd12.prod.outlook.com
State New
Headers show
Series "Series without cover letter" ( rev: 2 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Zeng, Oak June 24, 2019, 1:41 p.m.
Hi Felix,

See one comment inline

Regards,
Oak

-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Kuehling, Felix

Sent: Friday, June 21, 2019 3:48 PM
To: amd-gfx@lists.freedesktop.org
Cc: Kuehling, Felix <Felix.Kuehling@amd.com>
Subject: [PATCH 1/1] drm/amdkfd: Add queue status indicator to HQD dump

Make it easy to distinguish unmapped, idle and busy queues in the HQD dump.

Also remove CU mask from the HQD dump because these registers are not per-queue, but per pipe.

Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>

---
 .../drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c    | 35 ++++++++++++++--
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 39 +++++++++++++-----  .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 39 +++++++++++++-----  .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 35 ++++++++++++++--  .../drm/amd/amdkfd/kfd_device_queue_manager.c | 40 +++++++++++--------
 .../gpu/drm/amd/include/kgd_kfd_interface.h   | 15 ++++++-
 6 files changed, 157 insertions(+), 46 deletions(-)

--
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
index 39ffb078beb4..4882b4112a7a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c
@@ -68,12 +68,14 @@  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 			struct mm_struct *mm);
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs);
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status);
 static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs);
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status);
 static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
 		uint32_t pipe_id, uint32_t queue_id);  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); @@ -454,9 +456,17 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs)
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		hqd_active = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE) -
+			      SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),
[Oak] Is above line a copy-past typo? I don't understand why you can use a active register - a base register.
+		hqd_pq_rptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_RPTR) -
+			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),
+		hqd_pq_wptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_LO) -
+			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR));
 	uint32_t i = 0, reg;
 #define HQD_N_REGS 56
 #define DUMP_REG(addr) do {				\
@@ -481,6 +491,12 @@  static int kgd_hqd_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[hqd_active][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
@@ -561,9 +577,14 @@  static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 
 static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs)
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;
 	uint32_t sdma_base_addr = get_sdma_base_addr(adev, engine_id, queue_id);
 	uint32_t i = 0, reg;
 #undef HQD_N_REGS
@@ -590,6 +611,12 @@  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[rlc_doorbell][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index c6abcf72e822..10b0ec8ca852 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -104,12 +104,14 @@  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 			struct mm_struct *mm);
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs);
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status);
 static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs);
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status);
 static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
 				uint32_t pipe_id, uint32_t queue_id);
 
@@ -373,11 +375,16 @@  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs)
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		hqd_active = mmCP_HQD_ACTIVE - mmCP_MQD_BASE_ADDR,
+		hqd_pq_rptr = mmCP_HQD_PQ_RPTR - mmCP_MQD_BASE_ADDR,
+		hqd_pq_wptr = mmCP_HQD_PQ_WPTR - mmCP_MQD_BASE_ADDR;
 	uint32_t i = 0, reg;
-#define HQD_N_REGS (35+4)
+#define HQD_N_REGS 35
 #define DUMP_REG(addr) do {				\
 		if (WARN_ON_ONCE(i >= HQD_N_REGS))	\
 			break;				\
@@ -391,11 +398,6 @@  static int kgd_hqd_dump(struct kgd_dev *kgd,
 
 	acquire_queue(kgd, pipe_id, queue_id);
 
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0);
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1);
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE2);
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE3);
-
 	for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_MQD_CONTROL; reg++)
 		DUMP_REG(reg);
 
@@ -404,6 +406,12 @@  static int kgd_hqd_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[hqd_active][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
@@ -473,9 +481,14 @@  static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 
 static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs)
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;
 	uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET +
 		queue_id * KFD_CIK_SDMA_QUEUE_OFFSET;
 	uint32_t i = 0, reg;
@@ -495,6 +508,12 @@  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[rlc_doorbell][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 4e8b4e949926..5d958ba9c524 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -61,12 +61,14 @@  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 			struct mm_struct *mm);
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs);
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status);
 static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs);
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status);
 static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
 		uint32_t pipe_id, uint32_t queue_id);  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); @@ -358,11 +360,16 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs)
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		hqd_active = mmCP_HQD_ACTIVE - mmCP_MQD_BASE_ADDR,
+		hqd_pq_rptr = mmCP_HQD_PQ_RPTR - mmCP_MQD_BASE_ADDR,
+		hqd_pq_wptr = mmCP_HQD_PQ_WPTR - mmCP_MQD_BASE_ADDR;
 	uint32_t i = 0, reg;
-#define HQD_N_REGS (54+4)
+#define HQD_N_REGS 54
 #define DUMP_REG(addr) do {				\
 		if (WARN_ON_ONCE(i >= HQD_N_REGS))	\
 			break;				\
@@ -376,11 +383,6 @@  static int kgd_hqd_dump(struct kgd_dev *kgd,
 
 	acquire_queue(kgd, pipe_id, queue_id);
 
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0);
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1);
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE2);
-	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE3);
-
 	for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_HQD_EOP_DONES; reg++)
 		DUMP_REG(reg);
 
@@ -389,6 +391,12 @@  static int kgd_hqd_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[hqd_active][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
@@ -457,9 +465,14 @@  static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 
 static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs)
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;
 	uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET +
 		queue_id * KFD_VI_SDMA_QUEUE_OFFSET;
 	uint32_t i = 0, reg;
@@ -488,6 +501,12 @@  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[rlc_doorbell][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
index d5af41143d12..2e1a37c469c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -75,12 +75,14 @@  static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 			struct mm_struct *mm);
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs);
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status);
 static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs);
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status);
 static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
 		uint32_t pipe_id, uint32_t queue_id);  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); @@ -440,9 +442,17 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
 
 static int kgd_hqd_dump(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs)
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		hqd_active = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE) -
+			      SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),
+		hqd_pq_rptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_RPTR) -
+			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),
+		hqd_pq_wptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_LO) -
+			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR));
 	uint32_t i = 0, reg;
 #define HQD_N_REGS 56
 #define DUMP_REG(addr) do {				\
@@ -467,6 +477,12 @@  static int kgd_hqd_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[hqd_active][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
@@ -546,9 +562,14 @@  static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
 
 static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs)
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status)
 {
 	struct amdgpu_device *adev = get_amdgpu_device(kgd);
+	const uint32_t
+		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,
+		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;
 	uint32_t sdma_base_addr = get_sdma_base_addr(adev, engine_id, queue_id);
 	uint32_t i = 0, reg;
 #undef HQD_N_REGS
@@ -572,6 +593,12 @@  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,
 	WARN_ON_ONCE(i != HQD_N_REGS);
 	*n_regs = i;
 
+	if (!(*dump)[rlc_doorbell][1])
+		*status = KFD_QUEUE_UNMAPPED;
+	else
+		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?
+			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;
+
 	return 0;
 }
 
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 9ffdda57e7f0..07d3b94c3319 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1874,22 +1874,28 @@  static void seq_reg_dump(struct seq_file *m,
 
 int dqm_debugfs_hqds(struct seq_file *m, void *data)  {
+	static const char * const status_string[] = {
+		[KFD_QUEUE_UNMAPPED] = "unmapped",
+		[KFD_QUEUE_IDLE] = "idle",
+		[KFD_QUEUE_BUSY] = "busy"
+	};
 	struct device_queue_manager *dqm = data;
 	uint32_t (*dump)[2], n_regs;
+	enum kfd_queue_status status;
 	int pipe, queue;
 	int r = 0;
 
-        r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,
-                KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE, &dump, &n_regs);
-        if (!r) {
-                seq_printf(m, "  HIQ on MEC %d Pipe %d Queue %d\n",
-                                KFD_CIK_HIQ_PIPE/get_pipes_per_mec(dqm)+1,
-                                KFD_CIK_HIQ_PIPE%get_pipes_per_mec(dqm),
-                                KFD_CIK_HIQ_QUEUE);
-                seq_reg_dump(m, dump, n_regs);
+	r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,
+		KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE, &dump, &n_regs, &status);
+	if (!r) {
+		seq_printf(m, "  HIQ on MEC %d Pipe %d Queue %d (%s)\n",
+				KFD_CIK_HIQ_PIPE/get_pipes_per_mec(dqm)+1,
+				KFD_CIK_HIQ_PIPE%get_pipes_per_mec(dqm),
+				KFD_CIK_HIQ_QUEUE, status_string[status]);
+		seq_reg_dump(m, dump, n_regs);
 
-                kfree(dump);
-        }
+		kfree(dump);
+	}
 
 	for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
 		int pipe_offset = pipe * get_queues_per_pipe(dqm); @@ -1900,12 +1906,13 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)
 				continue;
 
 			r = dqm->dev->kfd2kgd->hqd_dump(
-				dqm->dev->kgd, pipe, queue, &dump, &n_regs);
+				dqm->dev->kgd, pipe, queue, &dump, &n_regs,
+				&status);
 			if (r)
 				break;
 
-			seq_printf(m, "  CP Pipe %d, Queue %d\n",
-				  pipe, queue);
+			seq_printf(m, "  CP Pipe %d, Queue %d (%s)\n",
+				  pipe, queue, status_string[status]);
 			seq_reg_dump(m, dump, n_regs);
 
 			kfree(dump);
@@ -1917,12 +1924,13 @@  int dqm_debugfs_hqds(struct seq_file *m, void *data)
 		     queue < dqm->dev->device_info->num_sdma_queues_per_engine;
 		     queue++) {
 			r = dqm->dev->kfd2kgd->hqd_sdma_dump(
-				dqm->dev->kgd, pipe, queue, &dump, &n_regs);
+				dqm->dev->kgd, pipe, queue, &dump, &n_regs,
+				&status);
 			if (r)
 				break;
 
-			seq_printf(m, "  SDMA Engine %d, RLC %d\n",
-				  pipe, queue);
+			seq_printf(m, "  SDMA Engine %d, RLC %d (%s)\n",
+				  pipe, queue, status_string[status]);
 			seq_reg_dump(m, dump, n_regs);
 
 			kfree(dump);
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 98b9533e672b..bc4aca349c4c 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -187,6 +187,15 @@  struct tile_config {
 #define ALLOC_MEM_FLAGS_AQL_QUEUE_MEM	(1 << 27)
 #define ALLOC_MEM_FLAGS_COHERENT	(1 << 26) /* For GFXv9 or later */
 
+/*
+ * Queue status for HQD dump
+ */
+enum kfd_queue_status {
+	KFD_QUEUE_UNMAPPED, /* Queue is not mapped */
+	KFD_QUEUE_IDLE,     /* Queue is enabled but currently idle */
+	KFD_QUEUE_BUSY      /* Queue is enabled and has work pending */
+};
+
 /**
  * struct kfd2kgd_calls
  *
@@ -261,11 +270,13 @@  struct kfd2kgd_calls {
 
 	int (*hqd_dump)(struct kgd_dev *kgd,
 			uint32_t pipe_id, uint32_t queue_id,
-			uint32_t (**dump)[2], uint32_t *n_regs);
+			uint32_t (**dump)[2], uint32_t *n_regs,
+			enum kfd_queue_status *status);
 
 	int (*hqd_sdma_dump)(struct kgd_dev *kgd,
 			     uint32_t engine_id, uint32_t queue_id,
-			     uint32_t (**dump)[2], uint32_t *n_regs);
+			     uint32_t (**dump)[2], uint32_t *n_regs,
+			     enum kfd_queue_status *status);
 
 	bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
 				uint32_t pipe_id, uint32_t queue_id);

Comments

On 2019-06-24 9:41 a.m., Zeng, Oak wrote:
> Hi Felix,

>

> See one comment inline

>

> Regards,

> Oak

>

> -----Original Message-----

> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Kuehling, Felix

> Sent: Friday, June 21, 2019 3:48 PM

> To: amd-gfx@lists.freedesktop.org

> Cc: Kuehling, Felix <Felix.Kuehling@amd.com>

> Subject: [PATCH 1/1] drm/amdkfd: Add queue status indicator to HQD dump

>

> Make it easy to distinguish unmapped, idle and busy queues in the HQD dump.

>

> Also remove CU mask from the HQD dump because these registers are not per-queue, but per pipe.

>

> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>

> ---

>   .../drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c    | 35 ++++++++++++++--

>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 39 +++++++++++++-----  .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 39 +++++++++++++-----  .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 35 ++++++++++++++--  .../drm/amd/amdkfd/kfd_device_queue_manager.c | 40 +++++++++++--------

>   .../gpu/drm/amd/include/kgd_kfd_interface.h   | 15 ++++++-

>   6 files changed, 157 insertions(+), 46 deletions(-)

>

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c

> index 39ffb078beb4..4882b4112a7a 100644

> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c

> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c

> @@ -68,12 +68,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   			struct mm_struct *mm);

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs);

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status);

>   static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs);

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status);

>   static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,

>   		uint32_t pipe_id, uint32_t queue_id);  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); @@ -454,9 +456,17 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs)

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		hqd_active = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE) -

> +			      SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),

> [Oak] Is above line a copy-past typo? I don't understand why you can use a active register - a base register.


This is intentional. hqd_active is used as an index into the dump array. 
The array contains only the registers that are relevant for the HQD 
dump. The first register in dump is mmCP_MQD_BASE_ADDR. So the offset of 
any subsequent register can be calculated with "X - mmCP_MQD_BASE_ADDR".

The patch probably doesn't show enough context. You'll see what I mean 
if you read the whole function.

Regards,
   Felix


> +		hqd_pq_rptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_RPTR) -

> +			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),

> +		hqd_pq_wptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_LO) -

> +			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR));

>   	uint32_t i = 0, reg;

>   #define HQD_N_REGS 56

>   #define DUMP_REG(addr) do {				\

> @@ -481,6 +491,12 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[hqd_active][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> @@ -561,9 +577,14 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   

>   static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs)

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;

>   	uint32_t sdma_base_addr = get_sdma_base_addr(adev, engine_id, queue_id);

>   	uint32_t i = 0, reg;

>   #undef HQD_N_REGS

> @@ -590,6 +611,12 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[rlc_doorbell][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c

> index c6abcf72e822..10b0ec8ca852 100644

> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c

> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c

> @@ -104,12 +104,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   			struct mm_struct *mm);

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs);

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status);

>   static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs);

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status);

>   static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,

>   				uint32_t pipe_id, uint32_t queue_id);

>   

> @@ -373,11 +375,16 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs)

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		hqd_active = mmCP_HQD_ACTIVE - mmCP_MQD_BASE_ADDR,

> +		hqd_pq_rptr = mmCP_HQD_PQ_RPTR - mmCP_MQD_BASE_ADDR,

> +		hqd_pq_wptr = mmCP_HQD_PQ_WPTR - mmCP_MQD_BASE_ADDR;

>   	uint32_t i = 0, reg;

> -#define HQD_N_REGS (35+4)

> +#define HQD_N_REGS 35

>   #define DUMP_REG(addr) do {				\

>   		if (WARN_ON_ONCE(i >= HQD_N_REGS))	\

>   			break;				\

> @@ -391,11 +398,6 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,

>   

>   	acquire_queue(kgd, pipe_id, queue_id);

>   

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0);

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1);

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE2);

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE3);

> -

>   	for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_MQD_CONTROL; reg++)

>   		DUMP_REG(reg);

>   

> @@ -404,6 +406,12 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[hqd_active][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> @@ -473,9 +481,14 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   

>   static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs)

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;

>   	uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET +

>   		queue_id * KFD_CIK_SDMA_QUEUE_OFFSET;

>   	uint32_t i = 0, reg;

> @@ -495,6 +508,12 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[rlc_doorbell][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c

> index 4e8b4e949926..5d958ba9c524 100644

> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c

> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c

> @@ -61,12 +61,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   			struct mm_struct *mm);

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs);

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status);

>   static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs);

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status);

>   static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,

>   		uint32_t pipe_id, uint32_t queue_id);  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); @@ -358,11 +360,16 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs)

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		hqd_active = mmCP_HQD_ACTIVE - mmCP_MQD_BASE_ADDR,

> +		hqd_pq_rptr = mmCP_HQD_PQ_RPTR - mmCP_MQD_BASE_ADDR,

> +		hqd_pq_wptr = mmCP_HQD_PQ_WPTR - mmCP_MQD_BASE_ADDR;

>   	uint32_t i = 0, reg;

> -#define HQD_N_REGS (54+4)

> +#define HQD_N_REGS 54

>   #define DUMP_REG(addr) do {				\

>   		if (WARN_ON_ONCE(i >= HQD_N_REGS))	\

>   			break;				\

> @@ -376,11 +383,6 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,

>   

>   	acquire_queue(kgd, pipe_id, queue_id);

>   

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0);

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1);

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE2);

> -	DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE3);

> -

>   	for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_HQD_EOP_DONES; reg++)

>   		DUMP_REG(reg);

>   

> @@ -389,6 +391,12 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[hqd_active][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> @@ -457,9 +465,14 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   

>   static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs)

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;

>   	uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET +

>   		queue_id * KFD_VI_SDMA_QUEUE_OFFSET;

>   	uint32_t i = 0, reg;

> @@ -488,6 +501,12 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[rlc_doorbell][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c

> index d5af41143d12..2e1a37c469c4 100644

> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c

> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c

> @@ -75,12 +75,14 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   			struct mm_struct *mm);

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs);

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status);

>   static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   			     uint32_t __user *wptr, struct mm_struct *mm);  static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs);

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status);

>   static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,

>   		uint32_t pipe_id, uint32_t queue_id);  static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); @@ -440,9 +442,17 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,

>   

>   static int kgd_hqd_dump(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs)

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		hqd_active = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE) -

> +			      SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),

> +		hqd_pq_rptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_RPTR) -

> +			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR)),

> +		hqd_pq_wptr = (SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_LO) -

> +			       SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR));

>   	uint32_t i = 0, reg;

>   #define HQD_N_REGS 56

>   #define DUMP_REG(addr) do {				\

> @@ -467,6 +477,12 @@ static int kgd_hqd_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[hqd_active][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[hqd_pq_rptr][1] == (*dump)[hqd_pq_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> @@ -546,9 +562,14 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,

>   

>   static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs)

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status)

>   {

>   	struct amdgpu_device *adev = get_amdgpu_device(kgd);

> +	const uint32_t

> +		rlc_doorbell = mmSDMA0_RLC0_DOORBELL - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_rptr = mmSDMA0_RLC0_RB_RPTR - mmSDMA0_RLC0_RB_CNTL,

> +		rlc_rb_wptr = mmSDMA0_RLC0_RB_WPTR - mmSDMA0_RLC0_RB_CNTL;

>   	uint32_t sdma_base_addr = get_sdma_base_addr(adev, engine_id, queue_id);

>   	uint32_t i = 0, reg;

>   #undef HQD_N_REGS

> @@ -572,6 +593,12 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd,

>   	WARN_ON_ONCE(i != HQD_N_REGS);

>   	*n_regs = i;

>   

> +	if (!(*dump)[rlc_doorbell][1])

> +		*status = KFD_QUEUE_UNMAPPED;

> +	else

> +		*status = (*dump)[rlc_rb_rptr][1] == (*dump)[rlc_rb_wptr][1] ?

> +			KFD_QUEUE_IDLE : KFD_QUEUE_BUSY;

> +

>   	return 0;

>   }

>   

> 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 9ffdda57e7f0..07d3b94c3319 100644

> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c

> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c

> @@ -1874,22 +1874,28 @@ static void seq_reg_dump(struct seq_file *m,

>   

>   int dqm_debugfs_hqds(struct seq_file *m, void *data)  {

> +	static const char * const status_string[] = {

> +		[KFD_QUEUE_UNMAPPED] = "unmapped",

> +		[KFD_QUEUE_IDLE] = "idle",

> +		[KFD_QUEUE_BUSY] = "busy"

> +	};

>   	struct device_queue_manager *dqm = data;

>   	uint32_t (*dump)[2], n_regs;

> +	enum kfd_queue_status status;

>   	int pipe, queue;

>   	int r = 0;

>   

> -        r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,

> -                KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE, &dump, &n_regs);

> -        if (!r) {

> -                seq_printf(m, "  HIQ on MEC %d Pipe %d Queue %d\n",

> -                                KFD_CIK_HIQ_PIPE/get_pipes_per_mec(dqm)+1,

> -                                KFD_CIK_HIQ_PIPE%get_pipes_per_mec(dqm),

> -                                KFD_CIK_HIQ_QUEUE);

> -                seq_reg_dump(m, dump, n_regs);

> +	r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd,

> +		KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE, &dump, &n_regs, &status);

> +	if (!r) {

> +		seq_printf(m, "  HIQ on MEC %d Pipe %d Queue %d (%s)\n",

> +				KFD_CIK_HIQ_PIPE/get_pipes_per_mec(dqm)+1,

> +				KFD_CIK_HIQ_PIPE%get_pipes_per_mec(dqm),

> +				KFD_CIK_HIQ_QUEUE, status_string[status]);

> +		seq_reg_dump(m, dump, n_regs);

>   

> -                kfree(dump);

> -        }

> +		kfree(dump);

> +	}

>   

>   	for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {

>   		int pipe_offset = pipe * get_queues_per_pipe(dqm); @@ -1900,12 +1906,13 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)

>   				continue;

>   

>   			r = dqm->dev->kfd2kgd->hqd_dump(

> -				dqm->dev->kgd, pipe, queue, &dump, &n_regs);

> +				dqm->dev->kgd, pipe, queue, &dump, &n_regs,

> +				&status);

>   			if (r)

>   				break;

>   

> -			seq_printf(m, "  CP Pipe %d, Queue %d\n",

> -				  pipe, queue);

> +			seq_printf(m, "  CP Pipe %d, Queue %d (%s)\n",

> +				  pipe, queue, status_string[status]);

>   			seq_reg_dump(m, dump, n_regs);

>   

>   			kfree(dump);

> @@ -1917,12 +1924,13 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data)

>   		     queue < dqm->dev->device_info->num_sdma_queues_per_engine;

>   		     queue++) {

>   			r = dqm->dev->kfd2kgd->hqd_sdma_dump(

> -				dqm->dev->kgd, pipe, queue, &dump, &n_regs);

> +				dqm->dev->kgd, pipe, queue, &dump, &n_regs,

> +				&status);

>   			if (r)

>   				break;

>   

> -			seq_printf(m, "  SDMA Engine %d, RLC %d\n",

> -				  pipe, queue);

> +			seq_printf(m, "  SDMA Engine %d, RLC %d (%s)\n",

> +				  pipe, queue, status_string[status]);

>   			seq_reg_dump(m, dump, n_regs);

>   

>   			kfree(dump);

> diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h

> index 98b9533e672b..bc4aca349c4c 100644

> --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h

> +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h

> @@ -187,6 +187,15 @@ struct tile_config {

>   #define ALLOC_MEM_FLAGS_AQL_QUEUE_MEM	(1 << 27)

>   #define ALLOC_MEM_FLAGS_COHERENT	(1 << 26) /* For GFXv9 or later */

>   

> +/*

> + * Queue status for HQD dump

> + */

> +enum kfd_queue_status {

> +	KFD_QUEUE_UNMAPPED, /* Queue is not mapped */

> +	KFD_QUEUE_IDLE,     /* Queue is enabled but currently idle */

> +	KFD_QUEUE_BUSY      /* Queue is enabled and has work pending */

> +};

> +

>   /**

>    * struct kfd2kgd_calls

>    *

> @@ -261,11 +270,13 @@ struct kfd2kgd_calls {

>   

>   	int (*hqd_dump)(struct kgd_dev *kgd,

>   			uint32_t pipe_id, uint32_t queue_id,

> -			uint32_t (**dump)[2], uint32_t *n_regs);

> +			uint32_t (**dump)[2], uint32_t *n_regs,

> +			enum kfd_queue_status *status);

>   

>   	int (*hqd_sdma_dump)(struct kgd_dev *kgd,

>   			     uint32_t engine_id, uint32_t queue_id,

> -			     uint32_t (**dump)[2], uint32_t *n_regs);

> +			     uint32_t (**dump)[2], uint32_t *n_regs,

> +			     enum kfd_queue_status *status);

>   

>   	bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,

>   				uint32_t pipe_id, uint32_t queue_id);

> --

> 2.17.1

>

> _______________________________________________

> amd-gfx mailing list

> amd-gfx@lists.freedesktop.org

> https://lists.freedesktop.org/mailman/listinfo/amd-gfx