All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/11] drm/amdgpu: add missing error handling
@ 2018-11-30 12:35 Christian König
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

We ignored the return code here.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 3a4e5d8d5162..e329a23e1f99 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -902,6 +902,9 @@ static int gmc_v9_0_sw_init(void *handle)
 	/* This interrupt is VMC page fault.*/
 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC, VMC_1_0__SRCID__VM_FAULT,
 				&adev->gmc.vm_fault);
+	if (r)
+		return r;
+
 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UTCL2, UTCL2_1_0__SRCID__FAULT,
 				&adev->gmc.vm_fault);
 
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-2-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling Christian König
                     ` (9 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This allows us to filter out VM faults in the GMC code.

v2: don't filter out all faults

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 +++++++++++++++----------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 6b6524f04ce0..6db4c58ddc13 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
 	if (!amdgpu_ih_prescreen_iv(adev))
 		return;
 
-	/* Before dispatching irq to IP blocks, send it to amdkfd */
-	amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
-
 	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
 	amdgpu_ih_decode_iv(adev, &entry);
 
@@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
 	unsigned client_id = entry->client_id;
 	unsigned src_id = entry->src_id;
 	struct amdgpu_irq_src *src;
+	bool handled = false;
 	int r;
 
 	trace_amdgpu_iv(entry);
 
 	if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
-		DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
+		DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
 		return;
 	}
 
 	if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
-		DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
+		DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
 		return;
 	}
 
 	if (adev->irq.virq[src_id]) {
 		generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
-	} else {
-		if (!adev->irq.client[client_id].sources) {
-			DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
-				  client_id, src_id);
-			return;
-		}
+		return;
+	}
 
+	if (!adev->irq.client[client_id].sources) {
+		DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
+			  client_id, src_id);
+		return;
+	} else {
 		src = adev->irq.client[client_id].sources[src_id];
 		if (!src) {
 			DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
@@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
 		}
 
 		r = src->funcs->process(adev, src, entry);
-		if (r)
+		if (r < 0)
 			DRM_ERROR("error processing interrupt (%d)\n", r);
+		else if (r)
+			handled = true;
 	}
+
+	/* Send it to amdkfd as well if it isn't already handled */
+	if (!handled)
+		amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
 }
 
 /**
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2 Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-3-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 04/11] drm/amdgpu: move IV prescreening into the GMC code Christian König
                     ` (8 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

printk_ratelimit() is much better suited to limit the number of reported
VM faults.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 37 -------------------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  5 ----
 drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c  |  7 ++---
 7 files changed, 6 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 2acb9838913e..a2f149da83f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3057,7 +3057,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	}
 
 	INIT_KFIFO(vm->faults);
-	vm->fault_credit = 16;
 
 	return 0;
 
@@ -3269,42 +3268,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 		amdgpu_vmid_free_reserved(adev, vm, i);
 }
 
-/**
- * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID
- *
- * @adev: amdgpu_device pointer
- * @pasid: PASID do identify the VM
- *
- * This function is expected to be called in interrupt context.
- *
- * Returns:
- * True if there was fault credit, false otherwise
- */
-bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
-				  unsigned int pasid)
-{
-	struct amdgpu_vm *vm;
-
-	spin_lock(&adev->vm_manager.pasid_lock);
-	vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
-	if (!vm) {
-		/* VM not found, can't track fault credit */
-		spin_unlock(&adev->vm_manager.pasid_lock);
-		return true;
-	}
-
-	/* No lock needed. only accessed by IRQ handler */
-	if (!vm->fault_credit) {
-		/* Too many faults in this VM */
-		spin_unlock(&adev->vm_manager.pasid_lock);
-		return false;
-	}
-
-	vm->fault_credit--;
-	spin_unlock(&adev->vm_manager.pasid_lock);
-	return true;
-}
-
 /**
  * amdgpu_vm_manager_init - init the VM manager
  *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 2a8898d19c8b..e8dcfd59fc93 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -229,9 +229,6 @@ struct amdgpu_vm {
 	/* Up to 128 pending retry page faults */
 	DECLARE_KFIFO(faults, u64, 128);
 
-	/* Limit non-retry fault storms */
-	unsigned int		fault_credit;
-
 	/* Points to the KFD process VM info */
 	struct amdkfd_process_info *process_info;
 
@@ -299,8 +296,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);
 void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
 void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
-bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
-				  unsigned int pasid);
 void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
 			 struct list_head *validated,
 			 struct amdgpu_bo_list_entry *entry);
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
index b5775c6a857b..3e6c8c4067cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -237,23 +237,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)
 {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
  /**
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
index df5ac4d85a00..447b3cbc47e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -216,23 +216,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)
 {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
index cf0fc61aebe6..2b94a6d1550e 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -216,23 +216,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)
 {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index dcdbb4d72472..9d7b43da6acc 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -227,23 +227,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)
 {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index d84b687240d1..b49290bcf109 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -258,12 +258,9 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
 	if (!pasid)
 		return true;
 
-	/* Not a retry fault, check fault credit */
-	if (!(dw5 & 0x80)) {
-		if (!amdgpu_vm_pasid_fault_credit(adev, pasid))
-			goto ignore_iv;
+	/* Not a retry fault */
+	if (!(dw5 & 0x80))
 		return true;
-	}
 
 	/* Track retry faults in per-VM fault FIFO. */
 	spin_lock(&adev->vm_manager.pasid_lock);
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 04/11] drm/amdgpu: move IV prescreening into the GMC code
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2 Christian König
  2018-11-30 12:35   ` [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-4-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 05/11] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2 Christian König
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

The GMC/VM subsystem is causing the faults, so move the handling here as
well.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  |  2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |  4 --
 drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 13 ----
 drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 13 ----
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 59 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 13 ----
 drivers/gpu/drm/amd/amdgpu/si_ih.c      | 14 -----
 drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 13 ----
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 82 -------------------------
 9 files changed, 59 insertions(+), 154 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
index 9ce8c93ec19b..f877bb78d10a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
@@ -51,14 +51,12 @@ struct amdgpu_ih_ring {
 struct amdgpu_ih_funcs {
 	/* ring read/write ptr handling, called from interrupt context */
 	u32 (*get_wptr)(struct amdgpu_device *adev);
-	bool (*prescreen_iv)(struct amdgpu_device *adev);
 	void (*decode_iv)(struct amdgpu_device *adev,
 			  struct amdgpu_iv_entry *entry);
 	void (*set_rptr)(struct amdgpu_device *adev);
 };
 
 #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
-#define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev))
 #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
 #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 6db4c58ddc13..318874952bc2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -145,10 +145,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
 	u32 ring_index = ih->rptr >> 2;
 	struct amdgpu_iv_entry entry;
 
-	/* Prescreening of high-frequency interrupts */
-	if (!amdgpu_ih_prescreen_iv(adev))
-		return;
-
 	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
 	amdgpu_ih_decode_iv(adev, &entry);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
index 3e6c8c4067cb..8a8b4967a101 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -228,18 +228,6 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
  * [127:96] - reserved
  */
 
-/**
- * cik_ih_prescreen_iv - prescreen an interrupt vector
- *
- * @adev: amdgpu_device pointer
- *
- * Returns true if the interrupt vector should be further processed.
- */
-static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)
-{
-	return true;
-}
-
  /**
  * cik_ih_decode_iv - decode an interrupt vector
  *
@@ -445,7 +433,6 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = {
 
 static const struct amdgpu_ih_funcs cik_ih_funcs = {
 	.get_wptr = cik_ih_get_wptr,
-	.prescreen_iv = cik_ih_prescreen_iv,
 	.decode_iv = cik_ih_decode_iv,
 	.set_rptr = cik_ih_set_rptr
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
index 447b3cbc47e5..9d3ea298e116 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -207,18 +207,6 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
 	return (wptr & adev->irq.ih.ptr_mask);
 }
 
-/**
- * cz_ih_prescreen_iv - prescreen an interrupt vector
- *
- * @adev: amdgpu_device pointer
- *
- * Returns true if the interrupt vector should be further processed.
- */
-static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)
-{
-	return true;
-}
-
 /**
  * cz_ih_decode_iv - decode an interrupt vector
  *
@@ -426,7 +414,6 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = {
 
 static const struct amdgpu_ih_funcs cz_ih_funcs = {
 	.get_wptr = cz_ih_get_wptr,
-	.prescreen_iv = cz_ih_prescreen_iv,
 	.decode_iv = cz_ih_decode_iv,
 	.set_rptr = cz_ih_set_rptr
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index e329a23e1f99..8995fca47efb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -244,6 +244,62 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
 	return 0;
 }
 
+/**
+ * vega10_ih_prescreen_iv - prescreen an interrupt vector
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Returns true if the interrupt vector should be further processed.
+ */
+static bool gmc_v9_0_prescreen_iv(struct amdgpu_device *adev,
+				  struct amdgpu_iv_entry *entry,
+				  uint64_t addr)
+{
+	struct amdgpu_vm *vm;
+	u64 key;
+	int r;
+
+	/* No PASID, can't identify faulting process */
+	if (!entry->pasid)
+		return true;
+
+	/* Not a retry fault */
+	if (!(entry->src_data[1] & 0x80))
+		return true;
+
+	/* Track retry faults in per-VM fault FIFO. */
+	spin_lock(&adev->vm_manager.pasid_lock);
+	vm = idr_find(&adev->vm_manager.pasid_idr, entry->pasid);
+	if (!vm) {
+		/* VM not found, process it normally */
+		spin_unlock(&adev->vm_manager.pasid_lock);
+		return true;
+	}
+
+	key = AMDGPU_VM_FAULT(entry->pasid, addr);
+	r = amdgpu_vm_add_fault(vm->fault_hash, key);
+
+	/* Hash table is full or the fault is already being processed,
+	 * ignore further page faults
+	 */
+	if (r != 0) {
+		spin_unlock(&adev->vm_manager.pasid_lock);
+		return false;
+	}
+	/* No locking required with single writer and single reader */
+	r = kfifo_put(&vm->faults, key);
+	if (!r) {
+		/* FIFO is full. Ignore it until there is space */
+		amdgpu_vm_clear_fault(vm->fault_hash, key);
+		spin_unlock(&adev->vm_manager.pasid_lock);
+		return false;
+	}
+
+	spin_unlock(&adev->vm_manager.pasid_lock);
+	/* It's the first fault for this address, process it normally */
+	return true;
+}
+
 static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
 				struct amdgpu_irq_src *source,
 				struct amdgpu_iv_entry *entry)
@@ -255,6 +311,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
 	addr = (u64)entry->src_data[0] << 12;
 	addr |= ((u64)entry->src_data[1] & 0xf) << 44;
 
+	if (!gmc_v9_0_prescreen_iv(adev, entry, addr))
+		return 1; /* This also prevents sending it to KFD */
+
 	if (!amdgpu_sriov_vf(adev)) {
 		status = RREG32(hub->vm_l2_pro_fault_status);
 		WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
index 2b94a6d1550e..a3984d10b604 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -207,18 +207,6 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
 	return (wptr & adev->irq.ih.ptr_mask);
 }
 
-/**
- * iceland_ih_prescreen_iv - prescreen an interrupt vector
- *
- * @adev: amdgpu_device pointer
- *
- * Returns true if the interrupt vector should be further processed.
- */
-static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)
-{
-	return true;
-}
-
 /**
  * iceland_ih_decode_iv - decode an interrupt vector
  *
@@ -424,7 +412,6 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = {
 
 static const struct amdgpu_ih_funcs iceland_ih_funcs = {
 	.get_wptr = iceland_ih_get_wptr,
-	.prescreen_iv = iceland_ih_prescreen_iv,
 	.decode_iv = iceland_ih_decode_iv,
 	.set_rptr = iceland_ih_set_rptr
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
index b3d7d9f83202..2938fb9f17cc 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
@@ -118,19 +118,6 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev)
 	return (wptr & adev->irq.ih.ptr_mask);
 }
 
-/**
- * si_ih_prescreen_iv - prescreen an interrupt vector
- *
- * @adev: amdgpu_device pointer
- *
- * Returns true if the interrupt vector should be further processed.
- */
-static bool si_ih_prescreen_iv(struct amdgpu_device *adev)
-{
-	/* Process all interrupts */
-	return true;
-}
-
 static void si_ih_decode_iv(struct amdgpu_device *adev,
 			     struct amdgpu_iv_entry *entry)
 {
@@ -301,7 +288,6 @@ static const struct amd_ip_funcs si_ih_ip_funcs = {
 
 static const struct amdgpu_ih_funcs si_ih_funcs = {
 	.get_wptr = si_ih_get_wptr,
-	.prescreen_iv = si_ih_prescreen_iv,
 	.decode_iv = si_ih_decode_iv,
 	.set_rptr = si_ih_set_rptr
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index 9d7b43da6acc..15da06ddeb75 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -218,18 +218,6 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
 	return (wptr & adev->irq.ih.ptr_mask);
 }
 
-/**
- * tonga_ih_prescreen_iv - prescreen an interrupt vector
- *
- * @adev: amdgpu_device pointer
- *
- * Returns true if the interrupt vector should be further processed.
- */
-static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)
-{
-	return true;
-}
-
 /**
  * tonga_ih_decode_iv - decode an interrupt vector
  *
@@ -490,7 +478,6 @@ static const struct amd_ip_funcs tonga_ih_ip_funcs = {
 
 static const struct amdgpu_ih_funcs tonga_ih_funcs = {
 	.get_wptr = tonga_ih_get_wptr,
-	.prescreen_iv = tonga_ih_prescreen_iv,
 	.decode_iv = tonga_ih_decode_iv,
 	.set_rptr = tonga_ih_set_rptr
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index b49290bcf109..2c250b01a903 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -219,87 +219,6 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
 	return (wptr & adev->irq.ih.ptr_mask);
 }
 
-/**
- * vega10_ih_prescreen_iv - prescreen an interrupt vector
- *
- * @adev: amdgpu_device pointer
- *
- * Returns true if the interrupt vector should be further processed.
- */
-static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
-{
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u32 dw0, dw3, dw4, dw5;
-	u16 pasid;
-	u64 addr, key;
-	struct amdgpu_vm *vm;
-	int r;
-
-	dw0 = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw3 = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
-	dw4 = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]);
-	dw5 = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]);
-
-	/* Filter retry page faults, let only the first one pass. If
-	 * there are too many outstanding faults, ignore them until
-	 * some faults get cleared.
-	 */
-	switch (dw0 & 0xff) {
-	case SOC15_IH_CLIENTID_VMC:
-	case SOC15_IH_CLIENTID_UTCL2:
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	pasid = dw3 & 0xffff;
-	/* No PASID, can't identify faulting process */
-	if (!pasid)
-		return true;
-
-	/* Not a retry fault */
-	if (!(dw5 & 0x80))
-		return true;
-
-	/* Track retry faults in per-VM fault FIFO. */
-	spin_lock(&adev->vm_manager.pasid_lock);
-	vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
-	addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12);
-	key = AMDGPU_VM_FAULT(pasid, addr);
-	if (!vm) {
-		/* VM not found, process it normally */
-		spin_unlock(&adev->vm_manager.pasid_lock);
-		return true;
-	} else {
-		r = amdgpu_vm_add_fault(vm->fault_hash, key);
-
-		/* Hash table is full or the fault is already being processed,
-		 * ignore further page faults
-		 */
-		if (r != 0) {
-			spin_unlock(&adev->vm_manager.pasid_lock);
-			goto ignore_iv;
-		}
-	}
-	/* No locking required with single writer and single reader */
-	r = kfifo_put(&vm->faults, key);
-	if (!r) {
-		/* FIFO is full. Ignore it until there is space */
-		amdgpu_vm_clear_fault(vm->fault_hash, key);
-		spin_unlock(&adev->vm_manager.pasid_lock);
-		goto ignore_iv;
-	}
-
-	spin_unlock(&adev->vm_manager.pasid_lock);
-	/* It's the first fault for this address, process it normally */
-	return true;
-
-ignore_iv:
-	adev->irq.ih.rptr += 32;
-	return false;
-}
-
 /**
  * vega10_ih_decode_iv - decode an interrupt vector
  *
@@ -484,7 +403,6 @@ const struct amd_ip_funcs vega10_ih_ip_funcs = {
 
 static const struct amdgpu_ih_funcs vega10_ih_funcs = {
 	.get_wptr = vega10_ih_get_wptr,
-	.prescreen_iv = vega10_ih_prescreen_iv,
 	.decode_iv = vega10_ih_decode_iv,
 	.set_rptr = vega10_ih_set_rptr
 };
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 05/11] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (2 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 04/11] drm/amdgpu: move IV prescreening into the GMC code Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-5-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 06/11] drm/amdgpu: simplify IH programming Christian König
                     ` (6 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Let's start to support multiple rings.

v2: decode IV is needed as well

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c  |  6 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  | 13 +++---
 drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 29 +++++++------
 drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 31 +++++++-------
 drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 29 +++++++------
 drivers/gpu/drm/amd/amdgpu/si_ih.c      | 31 +++++++-------
 drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 43 ++++++++++---------
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 56 +++++++++++++------------
 8 files changed, 128 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
index 8af67f649660..fb8dd6179926 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
@@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 	if (!ih->enabled || adev->shutdown)
 		return IRQ_NONE;
 
-	wptr = amdgpu_ih_get_wptr(adev);
+	wptr = amdgpu_ih_get_wptr(adev, ih);
 
 restart_ih:
 	/* is somebody else already processing irqs? */
@@ -154,11 +154,11 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 		ih->rptr &= ih->ptr_mask;
 	}
 
-	amdgpu_ih_set_rptr(adev);
+	amdgpu_ih_set_rptr(adev, ih);
 	atomic_set(&ih->lock, 0);
 
 	/* make sure wptr hasn't changed while processing */
-	wptr = amdgpu_ih_get_wptr(adev);
+	wptr = amdgpu_ih_get_wptr(adev, ih);
 	if (wptr != ih->rptr)
 		goto restart_ih;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
index f877bb78d10a..d810fd73d574 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
@@ -50,15 +50,16 @@ struct amdgpu_ih_ring {
 /* provided by the ih block */
 struct amdgpu_ih_funcs {
 	/* ring read/write ptr handling, called from interrupt context */
-	u32 (*get_wptr)(struct amdgpu_device *adev);
-	void (*decode_iv)(struct amdgpu_device *adev,
+	u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
+	void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 			  struct amdgpu_iv_entry *entry);
-	void (*set_rptr)(struct amdgpu_device *adev);
+	void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
 };
 
-#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
-#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
-#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
+#define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih))
+#define amdgpu_ih_decode_iv(adev, iv) \
+	(adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv))
+#define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih))
 
 int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 			unsigned ring_size, bool use_bus_addr);
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
index 8a8b4967a101..884aa9b81e86 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device *adev)
  * Used by cik_irq_process().
  * Returns the value of the wptr.
  */
-static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
+static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
+			   struct amdgpu_ih_ring *ih)
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
+	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
 
 	if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
 		wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
@@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
 		 * this should allow us to catchup.
 		 */
 		dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
-			wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
-		adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
+			 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
+		ih->rptr = (wptr + 16) & ih->ptr_mask;
 		tmp = RREG32(mmIH_RB_CNTL);
 		tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
 		WREG32(mmIH_RB_CNTL, tmp);
 	}
-	return (wptr & adev->irq.ih.ptr_mask);
+	return (wptr & ih->ptr_mask);
 }
 
 /*        CIK IV Ring
@@ -237,16 +238,17 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
  * position and also advance the position.
  */
 static void cik_ih_decode_iv(struct amdgpu_device *adev,
+			     struct amdgpu_ih_ring *ih,
 			     struct amdgpu_iv_entry *entry)
 {
 	/* wptr/rptr are in bytes! */
-	u32 ring_index = adev->irq.ih.rptr >> 2;
+	u32 ring_index = ih->rptr >> 2;
 	uint32_t dw[4];
 
-	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
-	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
-	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
+	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
+	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
+	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
+	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
 
 	entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
 	entry->src_id = dw[0] & 0xff;
@@ -256,7 +258,7 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
 	entry->pasid = (dw[2] >> 16) & 0xffff;
 
 	/* wptr/rptr are in bytes! */
-	adev->irq.ih.rptr += 16;
+	ih->rptr += 16;
 }
 
 /**
@@ -266,9 +268,10 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
  *
  * Set the IH ring buffer rptr.
  */
-static void cik_ih_set_rptr(struct amdgpu_device *adev)
+static void cik_ih_set_rptr(struct amdgpu_device *adev,
+			    struct amdgpu_ih_ring *ih)
 {
-	WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
+	WREG32(mmIH_RB_RPTR, ih->rptr);
 }
 
 static int cik_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
index 9d3ea298e116..c59eed041fb5 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -185,11 +185,12 @@ static void cz_ih_irq_disable(struct amdgpu_device *adev)
  * Used by cz_irq_process(VI).
  * Returns the value of the wptr.
  */
-static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
+static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
+			  struct amdgpu_ih_ring *ih)
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
+	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -198,13 +199,13 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
 		 * this should allow us to catchup.
 		 */
 		dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
-			wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
-		adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
+			wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
+		ih->rptr = (wptr + 16) & ih->ptr_mask;
 		tmp = RREG32(mmIH_RB_CNTL);
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 		WREG32(mmIH_RB_CNTL, tmp);
 	}
-	return (wptr & adev->irq.ih.ptr_mask);
+	return (wptr & ih->ptr_mask);
 }
 
 /**
@@ -216,16 +217,17 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
  * position and also advance the position.
  */
 static void cz_ih_decode_iv(struct amdgpu_device *adev,
-				 struct amdgpu_iv_entry *entry)
+			    struct amdgpu_ih_ring *ih,
+			    struct amdgpu_iv_entry *entry)
 {
 	/* wptr/rptr are in bytes! */
-	u32 ring_index = adev->irq.ih.rptr >> 2;
+	u32 ring_index = ih->rptr >> 2;
 	uint32_t dw[4];
 
-	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
-	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
-	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
+	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
+	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
+	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
+	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
 
 	entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
 	entry->src_id = dw[0] & 0xff;
@@ -235,7 +237,7 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
 	entry->pasid = (dw[2] >> 16) & 0xffff;
 
 	/* wptr/rptr are in bytes! */
-	adev->irq.ih.rptr += 16;
+	ih->rptr += 16;
 }
 
 /**
@@ -245,9 +247,10 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
  *
  * Set the IH ring buffer rptr.
  */
-static void cz_ih_set_rptr(struct amdgpu_device *adev)
+static void cz_ih_set_rptr(struct amdgpu_device *adev,
+			   struct amdgpu_ih_ring *ih)
 {
-	WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
+	WREG32(mmIH_RB_RPTR, ih->rptr);
 }
 
 static int cz_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
index a3984d10b604..f006ed509db3 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -185,11 +185,12 @@ static void iceland_ih_irq_disable(struct amdgpu_device *adev)
  * Used by cz_irq_process(VI).
  * Returns the value of the wptr.
  */
-static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
+static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
+			       struct amdgpu_ih_ring *ih)
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
+	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -198,13 +199,13 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
 		 * this should allow us to catchup.
 		 */
 		dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
-			wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
-		adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
+			 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
+		ih->rptr = (wptr + 16) & ih->ptr_mask;
 		tmp = RREG32(mmIH_RB_CNTL);
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 		WREG32(mmIH_RB_CNTL, tmp);
 	}
-	return (wptr & adev->irq.ih.ptr_mask);
+	return (wptr & ih->ptr_mask);
 }
 
 /**
@@ -216,16 +217,17 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
  * position and also advance the position.
  */
 static void iceland_ih_decode_iv(struct amdgpu_device *adev,
+				 struct amdgpu_ih_ring *ih,
 				 struct amdgpu_iv_entry *entry)
 {
 	/* wptr/rptr are in bytes! */
-	u32 ring_index = adev->irq.ih.rptr >> 2;
+	u32 ring_index = ih->rptr >> 2;
 	uint32_t dw[4];
 
-	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
-	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
-	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
+	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
+	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
+	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
+	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
 
 	entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
 	entry->src_id = dw[0] & 0xff;
@@ -235,7 +237,7 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
 	entry->pasid = (dw[2] >> 16) & 0xffff;
 
 	/* wptr/rptr are in bytes! */
-	adev->irq.ih.rptr += 16;
+	ih->rptr += 16;
 }
 
 /**
@@ -245,9 +247,10 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
  *
  * Set the IH ring buffer rptr.
  */
-static void iceland_ih_set_rptr(struct amdgpu_device *adev)
+static void iceland_ih_set_rptr(struct amdgpu_device *adev,
+				struct amdgpu_ih_ring *ih)
 {
-	WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
+	WREG32(mmIH_RB_RPTR, ih->rptr);
 }
 
 static int iceland_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
index 2938fb9f17cc..5cabc9687f76 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
@@ -100,34 +100,36 @@ static void si_ih_irq_disable(struct amdgpu_device *adev)
 	mdelay(1);
 }
 
-static u32 si_ih_get_wptr(struct amdgpu_device *adev)
+static u32 si_ih_get_wptr(struct amdgpu_device *adev,
+			  struct amdgpu_ih_ring *ih)
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
+	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
 
 	if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
 		wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
 		dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
-			wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
-		adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
+			wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
+		ih->rptr = (wptr + 16) & ih->ptr_mask;
 		tmp = RREG32(IH_RB_CNTL);
 		tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
 		WREG32(IH_RB_CNTL, tmp);
 	}
-	return (wptr & adev->irq.ih.ptr_mask);
+	return (wptr & ih->ptr_mask);
 }
 
 static void si_ih_decode_iv(struct amdgpu_device *adev,
-			     struct amdgpu_iv_entry *entry)
+			    struct amdgpu_ih_ring *ih,
+			    struct amdgpu_iv_entry *entry)
 {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
+	u32 ring_index = ih->rptr >> 2;
 	uint32_t dw[4];
 
-	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
-	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
-	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
+	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
+	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
+	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
+	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
 
 	entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
 	entry->src_id = dw[0] & 0xff;
@@ -135,12 +137,13 @@ static void si_ih_decode_iv(struct amdgpu_device *adev,
 	entry->ring_id = dw[2] & 0xff;
 	entry->vmid = (dw[2] >> 8) & 0xff;
 
-	adev->irq.ih.rptr += 16;
+	ih->rptr += 16;
 }
 
-static void si_ih_set_rptr(struct amdgpu_device *adev)
+static void si_ih_set_rptr(struct amdgpu_device *adev,
+			   struct amdgpu_ih_ring *ih)
 {
-	WREG32(IH_RB_RPTR, adev->irq.ih.rptr);
+	WREG32(IH_RB_RPTR, ih->rptr);
 }
 
 static int si_ih_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index 15da06ddeb75..30e3911dedb5 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -193,14 +193,15 @@ static void tonga_ih_irq_disable(struct amdgpu_device *adev)
  * Used by cz_irq_process(VI).
  * Returns the value of the wptr.
  */
-static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
+static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
+			     struct amdgpu_ih_ring *ih)
 {
 	u32 wptr, tmp;
 
 	if (adev->irq.ih.use_bus_addr)
-		wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]);
+		wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
 	else
-		wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
+		wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -209,13 +210,13 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
 		 * this should allow us to catchup.
 		 */
 		dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
-			wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
-		adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
+			 wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
+		ih->rptr = (wptr + 16) & ih->ptr_mask;
 		tmp = RREG32(mmIH_RB_CNTL);
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 		WREG32(mmIH_RB_CNTL, tmp);
 	}
-	return (wptr & adev->irq.ih.ptr_mask);
+	return (wptr & ih->ptr_mask);
 }
 
 /**
@@ -227,16 +228,17 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
  * position and also advance the position.
  */
 static void tonga_ih_decode_iv(struct amdgpu_device *adev,
-				 struct amdgpu_iv_entry *entry)
+			       struct amdgpu_ih_ring *ih,
+			       struct amdgpu_iv_entry *entry)
 {
 	/* wptr/rptr are in bytes! */
-	u32 ring_index = adev->irq.ih.rptr >> 2;
+	u32 ring_index = ih->rptr >> 2;
 	uint32_t dw[4];
 
-	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
-	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
-	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
+	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
+	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
+	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
+	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
 
 	entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
 	entry->src_id = dw[0] & 0xff;
@@ -246,7 +248,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
 	entry->pasid = (dw[2] >> 16) & 0xffff;
 
 	/* wptr/rptr are in bytes! */
-	adev->irq.ih.rptr += 16;
+	ih->rptr += 16;
 }
 
 /**
@@ -256,17 +258,18 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
  *
  * Set the IH ring buffer rptr.
  */
-static void tonga_ih_set_rptr(struct amdgpu_device *adev)
+static void tonga_ih_set_rptr(struct amdgpu_device *adev,
+			      struct amdgpu_ih_ring *ih)
 {
-	if (adev->irq.ih.use_doorbell) {
+	if (ih->use_doorbell) {
 		/* XXX check if swapping is necessary on BE */
-		if (adev->irq.ih.use_bus_addr)
-			adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
+		if (ih->use_bus_addr)
+			ih->ring[ih->rptr_offs] = ih->rptr;
 		else
-			adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
-		WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr);
+			adev->wb.wb[ih->rptr_offs] = ih->rptr;
+		WDOORBELL32(ih->doorbell_index, ih->rptr);
 	} else {
-		WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
+		WREG32(mmIH_RB_RPTR, ih->rptr);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index 2c250b01a903..28b0e9a6cc42 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -191,14 +191,15 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev)
  * ring buffer overflow and deal with it.
  * Returns the value of the wptr.
  */
-static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
+static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
+			      struct amdgpu_ih_ring *ih)
 {
 	u32 wptr, tmp;
 
-	if (adev->irq.ih.use_bus_addr)
-		wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]);
+	if (ih->use_bus_addr)
+		wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
 	else
-		wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
+		wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -207,16 +208,16 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
 		 * from the last not overwritten vector (wptr + 32). Hopefully
 		 * this should allow us to catchup.
 		 */
-		tmp = (wptr + 32) & adev->irq.ih.ptr_mask;
+		tmp = (wptr + 32) & ih->ptr_mask;
 		dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
-			wptr, adev->irq.ih.rptr, tmp);
-		adev->irq.ih.rptr = tmp;
+			 wptr, ih->rptr, tmp);
+		ih->rptr = tmp;
 
 		tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 		WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp);
 	}
-	return (wptr & adev->irq.ih.ptr_mask);
+	return (wptr & ih->ptr_mask);
 }
 
 /**
@@ -228,20 +229,21 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
  * position and also advance the position.
  */
 static void vega10_ih_decode_iv(struct amdgpu_device *adev,
-				 struct amdgpu_iv_entry *entry)
+				struct amdgpu_ih_ring *ih,
+				struct amdgpu_iv_entry *entry)
 {
 	/* wptr/rptr are in bytes! */
-	u32 ring_index = adev->irq.ih.rptr >> 2;
+	u32 ring_index = ih->rptr >> 2;
 	uint32_t dw[8];
 
-	dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
-	dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
-	dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
-	dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
-	dw[4] = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]);
-	dw[5] = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]);
-	dw[6] = le32_to_cpu(adev->irq.ih.ring[ring_index + 6]);
-	dw[7] = le32_to_cpu(adev->irq.ih.ring[ring_index + 7]);
+	dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
+	dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
+	dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
+	dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
+	dw[4] = le32_to_cpu(ih->ring[ring_index + 4]);
+	dw[5] = le32_to_cpu(ih->ring[ring_index + 5]);
+	dw[6] = le32_to_cpu(ih->ring[ring_index + 6]);
+	dw[7] = le32_to_cpu(ih->ring[ring_index + 7]);
 
 	entry->client_id = dw[0] & 0xff;
 	entry->src_id = (dw[0] >> 8) & 0xff;
@@ -257,9 +259,8 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
 	entry->src_data[2] = dw[6];
 	entry->src_data[3] = dw[7];
 
-
 	/* wptr/rptr are in bytes! */
-	adev->irq.ih.rptr += 32;
+	ih->rptr += 32;
 }
 
 /**
@@ -269,17 +270,18 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
  *
  * Set the IH ring buffer rptr.
  */
-static void vega10_ih_set_rptr(struct amdgpu_device *adev)
+static void vega10_ih_set_rptr(struct amdgpu_device *adev,
+			       struct amdgpu_ih_ring *ih)
 {
-	if (adev->irq.ih.use_doorbell) {
+	if (ih->use_doorbell) {
 		/* XXX check if swapping is necessary on BE */
-		if (adev->irq.ih.use_bus_addr)
-			adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
+		if (ih->use_bus_addr)
+			ih->ring[ih->rptr_offs] = ih->rptr;
 		else
-			adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
-		WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr);
+			adev->wb.wb[ih->rptr_offs] = ih->rptr;
+		WDOORBELL32(ih->doorbell_index, ih->rptr);
 	} else {
-		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, adev->irq.ih.rptr);
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
 	}
 }
 
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 06/11] drm/amdgpu: simplify IH programming
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (3 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 05/11] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2 Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-6-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2 Christian König
                     ` (5 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Calculate all the addresses and pointers in amdgpu_ih.c

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c  | 34 +++++++++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  | 23 +++++++++-------
 drivers/gpu/drm/amd/amdgpu/cik_ih.c     |  9 +++----
 drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 11 ++++----
 drivers/gpu/drm/amd/amdgpu/iceland_ih.c |  9 +++----
 drivers/gpu/drm/amd/amdgpu/si_ih.c      |  9 +++----
 drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 27 +++++--------------
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 36 +++++++++----------------
 8 files changed, 73 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
index fb8dd6179926..d0a5db777b6d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
@@ -52,6 +52,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 	ih->use_bus_addr = use_bus_addr;
 
 	if (use_bus_addr) {
+		dma_addr_t dma_addr;
+
 		if (ih->ring)
 			return 0;
 
@@ -59,21 +61,26 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 		 * add them to the end of the ring allocation.
 		 */
 		ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8,
-					      &ih->rb_dma_addr, GFP_KERNEL);
+					      &dma_addr, GFP_KERNEL);
 		if (ih->ring == NULL)
 			return -ENOMEM;
 
 		memset((void *)ih->ring, 0, ih->ring_size + 8);
-		ih->wptr_offs = (ih->ring_size / 4) + 0;
-		ih->rptr_offs = (ih->ring_size / 4) + 1;
+		ih->gpu_addr = dma_addr;
+		ih->wptr_addr = dma_addr + ih->ring_size;
+		ih->wptr_cpu = &ih->ring[ih->ring_size / 4];
+		ih->rptr_addr = dma_addr + ih->ring_size + 4;
+		ih->rptr_cpu = &ih->ring[(ih->ring_size / 4) + 1];
 	} else {
-		r = amdgpu_device_wb_get(adev, &ih->wptr_offs);
+		unsigned wptr_offs, rptr_offs;
+
+		r = amdgpu_device_wb_get(adev, &wptr_offs);
 		if (r)
 			return r;
 
-		r = amdgpu_device_wb_get(adev, &ih->rptr_offs);
+		r = amdgpu_device_wb_get(adev, &rptr_offs);
 		if (r) {
-			amdgpu_device_wb_free(adev, ih->wptr_offs);
+			amdgpu_device_wb_free(adev, wptr_offs);
 			return r;
 		}
 
@@ -82,10 +89,15 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
 					    &ih->ring_obj, &ih->gpu_addr,
 					    (void **)&ih->ring);
 		if (r) {
-			amdgpu_device_wb_free(adev, ih->rptr_offs);
-			amdgpu_device_wb_free(adev, ih->wptr_offs);
+			amdgpu_device_wb_free(adev, rptr_offs);
+			amdgpu_device_wb_free(adev, wptr_offs);
 			return r;
 		}
+
+		ih->wptr_addr = adev->wb.gpu_addr + wptr_offs * 4;
+		ih->wptr_cpu = &adev->wb.wb[wptr_offs];
+		ih->rptr_addr = adev->wb.gpu_addr + rptr_offs * 4;
+		ih->rptr_cpu = &adev->wb.wb[rptr_offs];
 	}
 	return 0;
 }
@@ -109,13 +121,13 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
 		 * add them to the end of the ring allocation.
 		 */
 		dma_free_coherent(adev->dev, ih->ring_size + 8,
-				  (void *)ih->ring, ih->rb_dma_addr);
+				  (void *)ih->ring, ih->gpu_addr);
 		ih->ring = NULL;
 	} else {
 		amdgpu_bo_free_kernel(&ih->ring_obj, &ih->gpu_addr,
 				      (void **)&ih->ring);
-		amdgpu_device_wb_free(adev, ih->wptr_offs);
-		amdgpu_device_wb_free(adev, ih->rptr_offs);
+		amdgpu_device_wb_free(adev, (ih->wptr_addr - ih->gpu_addr) / 4);
+		amdgpu_device_wb_free(adev, (ih->rptr_addr - ih->gpu_addr) / 4);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
index d810fd73d574..1ccb1831382a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
@@ -31,20 +31,25 @@ struct amdgpu_iv_entry;
  * R6xx+ IH ring
  */
 struct amdgpu_ih_ring {
-	struct amdgpu_bo	*ring_obj;
-	volatile uint32_t	*ring;
-	unsigned		rptr;
 	unsigned		ring_size;
-	uint64_t		gpu_addr;
 	uint32_t		ptr_mask;
-	atomic_t		lock;
-	bool                    enabled;
-	unsigned		wptr_offs;
-	unsigned		rptr_offs;
 	u32			doorbell_index;
 	bool			use_doorbell;
 	bool			use_bus_addr;
-	dma_addr_t		rb_dma_addr; /* only used when use_bus_addr = true */
+
+	struct amdgpu_bo	*ring_obj;
+	volatile uint32_t	*ring;
+	uint64_t		gpu_addr;
+
+	uint64_t		wptr_addr;
+	volatile uint32_t	*wptr_cpu;
+
+	uint64_t		rptr_addr;
+	volatile uint32_t	*rptr_cpu;
+
+	bool                    enabled;
+	unsigned		rptr;
+	atomic_t		lock;
 };
 
 /* provided by the ih block */
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
index 884aa9b81e86..721c757156e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -103,9 +103,9 @@ static void cik_ih_disable_interrupts(struct amdgpu_device *adev)
  */
 static int cik_ih_irq_init(struct amdgpu_device *adev)
 {
+	struct amdgpu_ih_ring *ih = &adev->irq.ih;
 	int rb_bufsz;
 	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
-	u64 wptr_off;
 
 	/* disable irqs */
 	cik_ih_disable_interrupts(adev);
@@ -131,9 +131,8 @@ static int cik_ih_irq_init(struct amdgpu_device *adev)
 	ih_rb_cntl |= IH_RB_CNTL__WPTR_WRITEBACK_ENABLE_MASK;
 
 	/* set the writeback address whether it's enabled or not */
-	wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
-	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
+	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
+	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
 
 	WREG32(mmIH_RB_CNTL, ih_rb_cntl);
 
@@ -188,7 +187,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
+	wptr = le32_to_cpu(*ih->wptr_cpu);
 
 	if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
 		wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
index c59eed041fb5..61024b9c7a4b 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -103,9 +103,9 @@ static void cz_ih_disable_interrupts(struct amdgpu_device *adev)
  */
 static int cz_ih_irq_init(struct amdgpu_device *adev)
 {
-	int rb_bufsz;
+	struct amdgpu_ih_ring *ih = &adev->irq.ih;
 	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
-	u64 wptr_off;
+	int rb_bufsz;
 
 	/* disable irqs */
 	cz_ih_disable_interrupts(adev);
@@ -133,9 +133,8 @@ static int cz_ih_irq_init(struct amdgpu_device *adev)
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
 
 	/* set the writeback address whether it's enabled or not */
-	wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
-	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
+	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
+	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
 
 	WREG32(mmIH_RB_CNTL, ih_rb_cntl);
 
@@ -190,7 +189,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
+	wptr = le32_to_cpu(*ih->wptr_cpu);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
index f006ed509db3..b1626e1d2f5d 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -103,9 +103,9 @@ static void iceland_ih_disable_interrupts(struct amdgpu_device *adev)
  */
 static int iceland_ih_irq_init(struct amdgpu_device *adev)
 {
+	struct amdgpu_ih_ring *ih = &adev->irq.ih;
 	int rb_bufsz;
 	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
-	u64 wptr_off;
 
 	/* disable irqs */
 	iceland_ih_disable_interrupts(adev);
@@ -133,9 +133,8 @@ static int iceland_ih_irq_init(struct amdgpu_device *adev)
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
 
 	/* set the writeback address whether it's enabled or not */
-	wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
-	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
+	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
+	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
 
 	WREG32(mmIH_RB_CNTL, ih_rb_cntl);
 
@@ -190,7 +189,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
+	wptr = le32_to_cpu(*ih->wptr_cpu);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
index 5cabc9687f76..8c50c9cab455 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
@@ -57,9 +57,9 @@ static void si_ih_disable_interrupts(struct amdgpu_device *adev)
 
 static int si_ih_irq_init(struct amdgpu_device *adev)
 {
+	struct amdgpu_ih_ring *ih = &adev->irq.ih;
 	int rb_bufsz;
 	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
-	u64 wptr_off;
 
 	si_ih_disable_interrupts(adev);
 	WREG32(INTERRUPT_CNTL2, adev->irq.ih.gpu_addr >> 8);
@@ -76,9 +76,8 @@ static int si_ih_irq_init(struct amdgpu_device *adev)
 		     (rb_bufsz << 1) |
 		     IH_WPTR_WRITEBACK_ENABLE;
 
-	wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
-	WREG32(IH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
+	WREG32(IH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
+	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
 	WREG32(IH_RB_CNTL, ih_rb_cntl);
 	WREG32(IH_RB_RPTR, 0);
 	WREG32(IH_RB_WPTR, 0);
@@ -105,7 +104,7 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev,
 {
 	u32 wptr, tmp;
 
-	wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
+	wptr = le32_to_cpu(*ih->wptr_cpu);
 
 	if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
 		wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index 30e3911dedb5..a20b711a6756 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -99,9 +99,9 @@ static void tonga_ih_disable_interrupts(struct amdgpu_device *adev)
  */
 static int tonga_ih_irq_init(struct amdgpu_device *adev)
 {
-	int rb_bufsz;
 	u32 interrupt_cntl, ih_rb_cntl, ih_doorbell_rtpr;
-	u64 wptr_off;
+	struct amdgpu_ih_ring *ih = &adev->irq.ih;
+	int rb_bufsz;
 
 	/* disable irqs */
 	tonga_ih_disable_interrupts(adev);
@@ -118,10 +118,7 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)
 	WREG32(mmINTERRUPT_CNTL, interrupt_cntl);
 
 	/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
-	if (adev->irq.ih.use_bus_addr)
-		WREG32(mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
-	else
-		WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
+	WREG32(mmIH_RB_BASE, ih->gpu_addr >> 8);
 
 	rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
 	ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
@@ -136,12 +133,8 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)
 	WREG32(mmIH_RB_CNTL, ih_rb_cntl);
 
 	/* set the writeback address whether it's enabled or not */
-	if (adev->irq.ih.use_bus_addr)
-		wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
-	else
-		wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
-	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
+	WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
+	WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
 
 	/* set rptr, wptr to 0 */
 	WREG32(mmIH_RB_RPTR, 0);
@@ -198,10 +191,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
 {
 	u32 wptr, tmp;
 
-	if (adev->irq.ih.use_bus_addr)
-		wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
-	else
-		wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
+	wptr = le32_to_cpu(*ih->wptr_cpu);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -263,10 +253,7 @@ static void tonga_ih_set_rptr(struct amdgpu_device *adev,
 {
 	if (ih->use_doorbell) {
 		/* XXX check if swapping is necessary on BE */
-		if (ih->use_bus_addr)
-			ih->ring[ih->rptr_offs] = ih->rptr;
-		else
-			adev->wb.wb[ih->rptr_offs] = ih->rptr;
+		*ih->rptr_cpu = ih->rptr;
 		WDOORBELL32(ih->doorbell_index, ih->rptr);
 	} else {
 		WREG32(mmIH_RB_RPTR, ih->rptr);
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index 28b0e9a6cc42..3e9ebb0de94d 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -86,11 +86,11 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
  */
 static int vega10_ih_irq_init(struct amdgpu_device *adev)
 {
+	struct amdgpu_ih_ring *ih = &adev->irq.ih;
 	int ret = 0;
 	int rb_bufsz;
 	u32 ih_rb_cntl, ih_doorbell_rtpr;
 	u32 tmp;
-	u64 wptr_off;
 
 	/* disable irqs */
 	vega10_ih_disable_interrupts(adev);
@@ -99,15 +99,11 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
 
 	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
 	/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
-	if (adev->irq.ih.use_bus_addr) {
-		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
-		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, ((u64)adev->irq.ih.rb_dma_addr >> 40) & 0xff);
-		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 1);
-	} else {
-		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
-		WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (adev->irq.ih.gpu_addr >> 40) & 0xff);
-		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 4);
-	}
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
+		     (adev->irq.ih.gpu_addr >> 40) & 0xff);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
+				   ih->use_bus_addr ? 1 : 4);
 	rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
@@ -124,12 +120,10 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
 
 	/* set the writeback address whether it's enabled or not */
-	if (adev->irq.ih.use_bus_addr)
-		wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
-	else
-		wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFFFF);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
+		     lower_32_bits(ih->wptr_addr));
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI,
+		     upper_32_bits(ih->wptr_addr) & 0xFFFF);
 
 	/* set rptr, wptr to 0 */
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
@@ -196,10 +190,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
 {
 	u32 wptr, tmp;
 
-	if (ih->use_bus_addr)
-		wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
-	else
-		wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
+	wptr = le32_to_cpu(*ih->wptr_cpu);
 
 	if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
 		wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
@@ -275,10 +266,7 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev,
 {
 	if (ih->use_doorbell) {
 		/* XXX check if swapping is necessary on BE */
-		if (ih->use_bus_addr)
-			ih->ring[ih->rptr_offs] = ih->rptr;
-		else
-			adev->wb.wb[ih->rptr_offs] = ih->rptr;
+		*ih->rptr_cpu = ih->rptr;
 		WDOORBELL32(ih->doorbell_index, ih->rptr);
 	} else {
 		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (4 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 06/11] drm/amdgpu: simplify IH programming Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-7-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 08/11] drm/amdgpu: add the IH to the IV trace Christian König
                     ` (4 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

The entries are ignored for now, but it at least stops crashing the
hardware when somebody tries to push something to the other IH rings.

v2: limit ring size, add TODO comment

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |   4 +-
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 129 +++++++++++++++++++-----
 2 files changed, 107 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
index f6ce171cb8aa..7e06fa64321a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
@@ -87,8 +87,8 @@ struct amdgpu_irq {
 	/* status, etc. */
 	bool				msi_enabled; /* msi enabled */
 
-	/* interrupt ring */
-	struct amdgpu_ih_ring		ih;
+	/* interrupt rings */
+	struct amdgpu_ih_ring		ih, ih1, ih2;
 	const struct amdgpu_ih_funcs	*ih_funcs;
 
 	/* gen irq stuff */
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index 3e9ebb0de94d..562fd036bb9e 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -50,6 +50,16 @@ static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
 	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
 	adev->irq.ih.enabled = true;
+
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 1);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
+	adev->irq.ih1.enabled = true;
+
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 1);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
+	adev->irq.ih2.enabled = true;
 }
 
 /**
@@ -71,6 +81,47 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
 	adev->irq.ih.enabled = false;
 	adev->irq.ih.rptr = 0;
+
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 0);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
+	/* set rptr, wptr to 0 */
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
+	adev->irq.ih1.enabled = false;
+	adev->irq.ih1.rptr = 0;
+
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 0);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
+	/* set rptr, wptr to 0 */
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
+	adev->irq.ih2.enabled = false;
+	adev->irq.ih2.rptr = 0;
+}
+
+static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
+{
+	int rb_bufsz = order_base_2(ih->ring_size / 4);
+
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
+				   MC_SPACE, ih->use_bus_addr ? 1 : 4);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
+				   WPTR_OVERFLOW_CLEAR, 1);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
+				   WPTR_OVERFLOW_ENABLE, 1);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
+	/* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register
+	 * value is written to memory
+	 */
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
+				   WPTR_WRITEBACK_ENABLE, 1);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
+
+	return ih_rb_cntl;
 }
 
 /**
@@ -86,9 +137,8 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
  */
 static int vega10_ih_irq_init(struct amdgpu_device *adev)
 {
-	struct amdgpu_ih_ring *ih = &adev->irq.ih;
+	struct amdgpu_ih_ring *ih;
 	int ret = 0;
-	int rb_bufsz;
 	u32 ih_rb_cntl, ih_doorbell_rtpr;
 	u32 tmp;
 
@@ -97,26 +147,15 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
 
 	adev->nbio_funcs->ih_control(adev);
 
-	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
+	ih = &adev->irq.ih;
 	/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
-	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
-		     (adev->irq.ih.gpu_addr >> 40) & 0xff);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
-				   ih->use_bus_addr ? 1 : 4);
-	rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
-	/* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
-	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
-
-	if (adev->irq.msi_enabled)
-		ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM, 1);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
 
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
+	ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
+				   !!adev->irq.msi_enabled);
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
 
 	/* set the writeback address whether it's enabled or not */
@@ -131,18 +170,49 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
 
 	ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
 	if (adev->irq.ih.use_doorbell) {
-		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
-						 OFFSET, adev->irq.ih.doorbell_index);
-		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
+		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
+						 IH_DOORBELL_RPTR, OFFSET,
+						 adev->irq.ih.doorbell_index);
+		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
+						 IH_DOORBELL_RPTR,
 						 ENABLE, 1);
 	} else {
-		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
+		ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
+						 IH_DOORBELL_RPTR,
 						 ENABLE, 0);
 	}
 	WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
 	adev->nbio_funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell,
 					    adev->irq.ih.doorbell_index);
 
+	ih = &adev->irq.ih1;
+	/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
+		     (ih->gpu_addr >> 40) & 0xff);
+
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+	ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
+
+	/* set rptr, wptr to 0 */
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
+
+	ih = &adev->irq.ih2;
+	/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
+		     (ih->gpu_addr >> 40) & 0xff);
+
+	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
+	ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
+
+	/* set rptr, wptr to 0 */
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
+	WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
+
 	tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
 	tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
 			    CLIENT18_IS_STORM_CLIENT, 1);
@@ -290,6 +360,15 @@ static int vega10_ih_sw_init(void *handle)
 	if (r)
 		return r;
 
+	r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
+	if (r)
+		return r;
+
+	r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
+	if (r)
+		return r;
+
+	/* TODO add doorbell for IH1 & IH2 as well */
 	adev->irq.ih.use_doorbell = true;
 	adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
 
@@ -303,6 +382,8 @@ static int vega10_ih_sw_fini(void *handle)
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	amdgpu_irq_fini(adev);
+	amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
+	amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
 	amdgpu_ih_ring_fini(adev, &adev->irq.ih);
 
 	return 0;
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 08/11] drm/amdgpu: add the IH to the IV trace
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (5 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2 Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-8-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 09/11] drm/amdgpu: add support for processing IH ring 1 & 2 Christian König
                     ` (3 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

To distinct on which IH ring an IV was found.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c   |  4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 11 +++++++----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 318874952bc2..127ed7de841d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -148,6 +148,8 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
 	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
 	amdgpu_ih_decode_iv(adev, &entry);
 
+	trace_amdgpu_iv(ih - &adev->irq.ih, &entry);
+
 	amdgpu_irq_dispatch(adev, &entry);
 }
 
@@ -367,8 +369,6 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
 	bool handled = false;
 	int r;
 
-	trace_amdgpu_iv(entry);
-
 	if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
 		DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
 		return;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 626abca770a0..6e388d7753c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -76,9 +76,10 @@ TRACE_EVENT(amdgpu_mm_wreg,
 );
 
 TRACE_EVENT(amdgpu_iv,
-	    TP_PROTO(struct amdgpu_iv_entry *iv),
-	    TP_ARGS(iv),
+	    TP_PROTO(unsigned ih, struct amdgpu_iv_entry *iv),
+	    TP_ARGS(ih, iv),
 	    TP_STRUCT__entry(
+			     __field(unsigned, ih)
 			     __field(unsigned, client_id)
 			     __field(unsigned, src_id)
 			     __field(unsigned, ring_id)
@@ -90,6 +91,7 @@ TRACE_EVENT(amdgpu_iv,
 			     __array(unsigned, src_data, 4)
 			    ),
 	    TP_fast_assign(
+			   __entry->ih = ih;
 			   __entry->client_id = iv->client_id;
 			   __entry->src_id = iv->src_id;
 			   __entry->ring_id = iv->ring_id;
@@ -103,8 +105,9 @@ TRACE_EVENT(amdgpu_iv,
 			   __entry->src_data[2] = iv->src_data[2];
 			   __entry->src_data[3] = iv->src_data[3];
 			   ),
-	    TP_printk("client_id:%u src_id:%u ring:%u vmid:%u timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x",
-		      __entry->client_id, __entry->src_id,
+	    TP_printk("ih: %u client_id:%u src_id:%u ring:%u vmid:%u "
+		      "timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x",
+		      __entry->ih, __entry->client_id, __entry->src_id,
 		      __entry->ring_id, __entry->vmid,
 		      __entry->timestamp, __entry->pasid,
 		      __entry->src_data[0], __entry->src_data[1],
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 09/11] drm/amdgpu: add support for processing IH ring 1 & 2
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (6 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 08/11] drm/amdgpu: add the IH to the IV trace Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-9-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 10/11] drm/amdgpu: add support for self irq on Vega10 Christian König
                     ` (2 subsequent siblings)
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Previously we only added the ring buffer memory, now add the handling as
well.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 33 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |  4 ++-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 127ed7de841d..64ec92bd74fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -176,6 +176,36 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
 	return ret;
 }
 
+/**
+ * amdgpu_irq_handle_ih1 - kick of processing for IH1
+ *
+ * @work: work structure in struct amdgpu_irq
+ *
+ * Kick of processing IH ring 1.
+ */
+static void amdgpu_irq_handle_ih1(struct work_struct *work)
+{
+	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
+						  irq.ih1_work);
+
+	amdgpu_ih_process(adev, &adev->irq.ih1, amdgpu_irq_callback);
+}
+
+/**
+ * amdgpu_irq_handle_ih2 - kick of processing for IH2
+ *
+ * @work: work structure in struct amdgpu_irq
+ *
+ * Kick of processing IH ring 2.
+ */
+static void amdgpu_irq_handle_ih2(struct work_struct *work)
+{
+	struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
+						  irq.ih2_work);
+
+	amdgpu_ih_process(adev, &adev->irq.ih2, amdgpu_irq_callback);
+}
+
 /**
  * amdgpu_msi_ok - check whether MSI functionality is enabled
  *
@@ -240,6 +270,9 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 				amdgpu_hotplug_work_func);
 	}
 
+	INIT_WORK(&adev->irq.ih1_work, amdgpu_irq_handle_ih1);
+	INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
+
 	adev->irq.installed = true;
 	r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq);
 	if (r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
index 7e06fa64321a..c27decfda494 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
@@ -89,7 +89,9 @@ struct amdgpu_irq {
 
 	/* interrupt rings */
 	struct amdgpu_ih_ring		ih, ih1, ih2;
-	const struct amdgpu_ih_funcs	*ih_funcs;
+	const struct amdgpu_ih_funcs    *ih_funcs;
+	struct work_struct		ih1_work, ih2_work;
+	struct amdgpu_irq_src		self_irq;
 
 	/* gen irq stuff */
 	struct irq_domain		*domain; /* GPU irq controller domain */
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 10/11] drm/amdgpu: add support for self irq on Vega10
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (7 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 09/11] drm/amdgpu: add support for processing IH ring 1 & 2 Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-10-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 12:35   ` [PATCH 11/11] drm/amdgpu: disable IH ring 1 & 2 WPTR overflow " Christian König
  2018-11-30 15:41   ` [PATCH 01/11] drm/amdgpu: add missing error handling Alex Deucher
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This finally enables processing of ring 1 & 2.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 68 ++++++++++++++++++++++++--
 1 file changed, 63 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index 562fd036bb9e..f5c5ea628fdf 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -258,7 +258,7 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev)
 static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
 			      struct amdgpu_ih_ring *ih)
 {
-	u32 wptr, tmp;
+	u32 wptr, reg, tmp;
 
 	wptr = le32_to_cpu(*ih->wptr_cpu);
 
@@ -274,9 +274,18 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
 			 wptr, ih->rptr, tmp);
 		ih->rptr = tmp;
 
-		tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
+		if (ih == &adev->irq.ih)
+			reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
+		else if (ih == &adev->irq.ih1)
+			reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
+		else if (ih == &adev->irq.ih2)
+			reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
+		else
+			BUG();
+
+		tmp = RREG32_NO_KIQ(reg);
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
-		WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp);
+		WREG32_NO_KIQ(reg, tmp);
 	}
 	return (wptr & ih->ptr_mask);
 }
@@ -338,9 +347,52 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev,
 		/* XXX check if swapping is necessary on BE */
 		*ih->rptr_cpu = ih->rptr;
 		WDOORBELL32(ih->doorbell_index, ih->rptr);
-	} else {
+	} else if (ih == &adev->irq.ih) {
 		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
+	} else if (ih == &adev->irq.ih1) {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
+	} else if (ih == &adev->irq.ih2) {
+		WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
+	}
+}
+
+/**
+ * vega10_ih_self_irq - dispatch work for ring 1 and 2
+ *
+ * @adev: amdgpu_device pointer
+ * @source: irq source
+ * @entry: IV with WPTR update
+ *
+ * Update the WPTR from the IV and schedule work to handle the entries.
+ */
+static int vega10_ih_self_irq(struct amdgpu_device *adev,
+			      struct amdgpu_irq_src *source,
+			      struct amdgpu_iv_entry *entry)
+{
+	uint32_t wptr = cpu_to_le32(entry->src_data[0]);
+
+	switch (entry->ring_id) {
+	case 1:
+		*adev->irq.ih1.wptr_cpu = wptr;
+		schedule_work(&adev->irq.ih1_work);
+		break;
+	case 2:
+		*adev->irq.ih2.wptr_cpu = wptr;
+		schedule_work(&adev->irq.ih2_work);
+		break;
+	default: break;
 	}
+	return 0;
+}
+
+static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = {
+	.process = vega10_ih_self_irq,
+};
+
+static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
+{
+	adev->irq.self_irq.num_types = 0;
+	adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs;
 }
 
 static int vega10_ih_early_init(void *handle)
@@ -348,13 +400,19 @@ static int vega10_ih_early_init(void *handle)
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	vega10_ih_set_interrupt_funcs(adev);
+	vega10_ih_set_self_irq_funcs(adev);
 	return 0;
 }
 
 static int vega10_ih_sw_init(void *handle)
 {
-	int r;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+	int r;
+
+	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
+			      &adev->irq.self_irq);
+	if (r)
+		return r;
 
 	r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true);
 	if (r)
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 11/11] drm/amdgpu: disable IH ring 1 & 2 WPTR overflow on Vega10
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (8 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 10/11] drm/amdgpu: add support for self irq on Vega10 Christian König
@ 2018-11-30 12:35   ` Christian König
       [not found]     ` <20181130123558.14898-11-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 15:41   ` [PATCH 01/11] drm/amdgpu: add missing error handling Alex Deucher
  10 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-11-30 12:35 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

That should add back pressure on the client.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index f5c5ea628fdf..dd7f52f08fd7 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -193,6 +193,8 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
 
 	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
 	ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
+				   WPTR_OVERFLOW_ENABLE, 0);
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
 
 	/* set rptr, wptr to 0 */
@@ -207,6 +209,8 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
 
 	ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
 	ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
+	ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
+				   WPTR_OVERFLOW_ENABLE, 0);
 	WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
 
 	/* set rptr, wptr to 0 */
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH 01/11] drm/amdgpu: add missing error handling
       [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (9 preceding siblings ...)
  2018-11-30 12:35   ` [PATCH 11/11] drm/amdgpu: disable IH ring 1 & 2 WPTR overflow " Christian König
@ 2018-11-30 15:41   ` Alex Deucher
  10 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 15:41 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> We ignored the return code here.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index 3a4e5d8d5162..e329a23e1f99 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -902,6 +902,9 @@ static int gmc_v9_0_sw_init(void *handle)
>         /* This interrupt is VMC page fault.*/
>         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC, VMC_1_0__SRCID__VM_FAULT,
>                                 &adev->gmc.vm_fault);
> +       if (r)
> +               return r;
> +
>         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UTCL2, UTCL2_1_0__SRCID__FAULT,
>                                 &adev->gmc.vm_fault);
>
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 06/11] drm/amdgpu: simplify IH programming
       [not found]     ` <20181130123558.14898-6-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 15:45       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 15:45 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> Calculate all the addresses and pointers in amdgpu_ih.c
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c  | 34 +++++++++++++++--------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  | 23 +++++++++-------
>  drivers/gpu/drm/amd/amdgpu/cik_ih.c     |  9 +++----
>  drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 11 ++++----
>  drivers/gpu/drm/amd/amdgpu/iceland_ih.c |  9 +++----
>  drivers/gpu/drm/amd/amdgpu/si_ih.c      |  9 +++----
>  drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 27 +++++--------------
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 36 +++++++++----------------
>  8 files changed, 73 insertions(+), 85 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> index fb8dd6179926..d0a5db777b6d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> @@ -52,6 +52,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>         ih->use_bus_addr = use_bus_addr;
>
>         if (use_bus_addr) {
> +               dma_addr_t dma_addr;
> +
>                 if (ih->ring)
>                         return 0;
>
> @@ -59,21 +61,26 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>                  * add them to the end of the ring allocation.
>                  */
>                 ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8,
> -                                             &ih->rb_dma_addr, GFP_KERNEL);
> +                                             &dma_addr, GFP_KERNEL);
>                 if (ih->ring == NULL)
>                         return -ENOMEM;
>
>                 memset((void *)ih->ring, 0, ih->ring_size + 8);
> -               ih->wptr_offs = (ih->ring_size / 4) + 0;
> -               ih->rptr_offs = (ih->ring_size / 4) + 1;
> +               ih->gpu_addr = dma_addr;
> +               ih->wptr_addr = dma_addr + ih->ring_size;
> +               ih->wptr_cpu = &ih->ring[ih->ring_size / 4];
> +               ih->rptr_addr = dma_addr + ih->ring_size + 4;
> +               ih->rptr_cpu = &ih->ring[(ih->ring_size / 4) + 1];
>         } else {
> -               r = amdgpu_device_wb_get(adev, &ih->wptr_offs);
> +               unsigned wptr_offs, rptr_offs;
> +
> +               r = amdgpu_device_wb_get(adev, &wptr_offs);
>                 if (r)
>                         return r;
>
> -               r = amdgpu_device_wb_get(adev, &ih->rptr_offs);
> +               r = amdgpu_device_wb_get(adev, &rptr_offs);
>                 if (r) {
> -                       amdgpu_device_wb_free(adev, ih->wptr_offs);
> +                       amdgpu_device_wb_free(adev, wptr_offs);
>                         return r;
>                 }
>
> @@ -82,10 +89,15 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>                                             &ih->ring_obj, &ih->gpu_addr,
>                                             (void **)&ih->ring);
>                 if (r) {
> -                       amdgpu_device_wb_free(adev, ih->rptr_offs);
> -                       amdgpu_device_wb_free(adev, ih->wptr_offs);
> +                       amdgpu_device_wb_free(adev, rptr_offs);
> +                       amdgpu_device_wb_free(adev, wptr_offs);
>                         return r;
>                 }
> +
> +               ih->wptr_addr = adev->wb.gpu_addr + wptr_offs * 4;
> +               ih->wptr_cpu = &adev->wb.wb[wptr_offs];
> +               ih->rptr_addr = adev->wb.gpu_addr + rptr_offs * 4;
> +               ih->rptr_cpu = &adev->wb.wb[rptr_offs];
>         }
>         return 0;
>  }
> @@ -109,13 +121,13 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
>                  * add them to the end of the ring allocation.
>                  */
>                 dma_free_coherent(adev->dev, ih->ring_size + 8,
> -                                 (void *)ih->ring, ih->rb_dma_addr);
> +                                 (void *)ih->ring, ih->gpu_addr);
>                 ih->ring = NULL;
>         } else {
>                 amdgpu_bo_free_kernel(&ih->ring_obj, &ih->gpu_addr,
>                                       (void **)&ih->ring);
> -               amdgpu_device_wb_free(adev, ih->wptr_offs);
> -               amdgpu_device_wb_free(adev, ih->rptr_offs);
> +               amdgpu_device_wb_free(adev, (ih->wptr_addr - ih->gpu_addr) / 4);
> +               amdgpu_device_wb_free(adev, (ih->rptr_addr - ih->gpu_addr) / 4);
>         }
>  }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> index d810fd73d574..1ccb1831382a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> @@ -31,20 +31,25 @@ struct amdgpu_iv_entry;
>   * R6xx+ IH ring
>   */
>  struct amdgpu_ih_ring {
> -       struct amdgpu_bo        *ring_obj;
> -       volatile uint32_t       *ring;
> -       unsigned                rptr;
>         unsigned                ring_size;
> -       uint64_t                gpu_addr;
>         uint32_t                ptr_mask;
> -       atomic_t                lock;
> -       bool                    enabled;
> -       unsigned                wptr_offs;
> -       unsigned                rptr_offs;
>         u32                     doorbell_index;
>         bool                    use_doorbell;
>         bool                    use_bus_addr;
> -       dma_addr_t              rb_dma_addr; /* only used when use_bus_addr = true */
> +
> +       struct amdgpu_bo        *ring_obj;
> +       volatile uint32_t       *ring;
> +       uint64_t                gpu_addr;
> +
> +       uint64_t                wptr_addr;
> +       volatile uint32_t       *wptr_cpu;
> +
> +       uint64_t                rptr_addr;
> +       volatile uint32_t       *rptr_cpu;
> +
> +       bool                    enabled;
> +       unsigned                rptr;
> +       atomic_t                lock;
>  };
>
>  /* provided by the ih block */
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> index 884aa9b81e86..721c757156e8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> @@ -103,9 +103,9 @@ static void cik_ih_disable_interrupts(struct amdgpu_device *adev)
>   */
>  static int cik_ih_irq_init(struct amdgpu_device *adev)
>  {
> +       struct amdgpu_ih_ring *ih = &adev->irq.ih;
>         int rb_bufsz;
>         u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
> -       u64 wptr_off;
>
>         /* disable irqs */
>         cik_ih_disable_interrupts(adev);
> @@ -131,9 +131,8 @@ static int cik_ih_irq_init(struct amdgpu_device *adev)
>         ih_rb_cntl |= IH_RB_CNTL__WPTR_WRITEBACK_ENABLE_MASK;
>
>         /* set the writeback address whether it's enabled or not */
> -       wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
> -       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
> -       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
> +       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
> +       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
>
>         WREG32(mmIH_RB_CNTL, ih_rb_cntl);
>
> @@ -188,7 +187,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
> +       wptr = le32_to_cpu(*ih->wptr_cpu);
>
>         if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
>                 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
> diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> index c59eed041fb5..61024b9c7a4b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> @@ -103,9 +103,9 @@ static void cz_ih_disable_interrupts(struct amdgpu_device *adev)
>   */
>  static int cz_ih_irq_init(struct amdgpu_device *adev)
>  {
> -       int rb_bufsz;
> +       struct amdgpu_ih_ring *ih = &adev->irq.ih;
>         u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
> -       u64 wptr_off;
> +       int rb_bufsz;
>
>         /* disable irqs */
>         cz_ih_disable_interrupts(adev);
> @@ -133,9 +133,8 @@ static int cz_ih_irq_init(struct amdgpu_device *adev)
>         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
>
>         /* set the writeback address whether it's enabled or not */
> -       wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
> -       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
> -       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
> +       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
> +       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
>
>         WREG32(mmIH_RB_CNTL, ih_rb_cntl);
>
> @@ -190,7 +189,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
> +       wptr = le32_to_cpu(*ih->wptr_cpu);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> index f006ed509db3..b1626e1d2f5d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> @@ -103,9 +103,9 @@ static void iceland_ih_disable_interrupts(struct amdgpu_device *adev)
>   */
>  static int iceland_ih_irq_init(struct amdgpu_device *adev)
>  {
> +       struct amdgpu_ih_ring *ih = &adev->irq.ih;
>         int rb_bufsz;
>         u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
> -       u64 wptr_off;
>
>         /* disable irqs */
>         iceland_ih_disable_interrupts(adev);
> @@ -133,9 +133,8 @@ static int iceland_ih_irq_init(struct amdgpu_device *adev)
>         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
>
>         /* set the writeback address whether it's enabled or not */
> -       wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
> -       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
> -       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
> +       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
> +       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
>
>         WREG32(mmIH_RB_CNTL, ih_rb_cntl);
>
> @@ -190,7 +189,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
> +       wptr = le32_to_cpu(*ih->wptr_cpu);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
> index 5cabc9687f76..8c50c9cab455 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
> @@ -57,9 +57,9 @@ static void si_ih_disable_interrupts(struct amdgpu_device *adev)
>
>  static int si_ih_irq_init(struct amdgpu_device *adev)
>  {
> +       struct amdgpu_ih_ring *ih = &adev->irq.ih;
>         int rb_bufsz;
>         u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
> -       u64 wptr_off;
>
>         si_ih_disable_interrupts(adev);
>         WREG32(INTERRUPT_CNTL2, adev->irq.ih.gpu_addr >> 8);
> @@ -76,9 +76,8 @@ static int si_ih_irq_init(struct amdgpu_device *adev)
>                      (rb_bufsz << 1) |
>                      IH_WPTR_WRITEBACK_ENABLE;
>
> -       wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
> -       WREG32(IH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
> -       WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
> +       WREG32(IH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
> +       WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
>         WREG32(IH_RB_CNTL, ih_rb_cntl);
>         WREG32(IH_RB_RPTR, 0);
>         WREG32(IH_RB_WPTR, 0);
> @@ -105,7 +104,7 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev,
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
> +       wptr = le32_to_cpu(*ih->wptr_cpu);
>
>         if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
>                 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
> diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> index 30e3911dedb5..a20b711a6756 100644
> --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> @@ -99,9 +99,9 @@ static void tonga_ih_disable_interrupts(struct amdgpu_device *adev)
>   */
>  static int tonga_ih_irq_init(struct amdgpu_device *adev)
>  {
> -       int rb_bufsz;
>         u32 interrupt_cntl, ih_rb_cntl, ih_doorbell_rtpr;
> -       u64 wptr_off;
> +       struct amdgpu_ih_ring *ih = &adev->irq.ih;
> +       int rb_bufsz;
>
>         /* disable irqs */
>         tonga_ih_disable_interrupts(adev);
> @@ -118,10 +118,7 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)
>         WREG32(mmINTERRUPT_CNTL, interrupt_cntl);
>
>         /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
> -       if (adev->irq.ih.use_bus_addr)
> -               WREG32(mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
> -       else
> -               WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
> +       WREG32(mmIH_RB_BASE, ih->gpu_addr >> 8);
>
>         rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
>         ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
> @@ -136,12 +133,8 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)
>         WREG32(mmIH_RB_CNTL, ih_rb_cntl);
>
>         /* set the writeback address whether it's enabled or not */
> -       if (adev->irq.ih.use_bus_addr)
> -               wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
> -       else
> -               wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
> -       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
> -       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
> +       WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
> +       WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
>
>         /* set rptr, wptr to 0 */
>         WREG32(mmIH_RB_RPTR, 0);
> @@ -198,10 +191,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
>  {
>         u32 wptr, tmp;
>
> -       if (adev->irq.ih.use_bus_addr)
> -               wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
> -       else
> -               wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
> +       wptr = le32_to_cpu(*ih->wptr_cpu);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> @@ -263,10 +253,7 @@ static void tonga_ih_set_rptr(struct amdgpu_device *adev,
>  {
>         if (ih->use_doorbell) {
>                 /* XXX check if swapping is necessary on BE */
> -               if (ih->use_bus_addr)
> -                       ih->ring[ih->rptr_offs] = ih->rptr;
> -               else
> -                       adev->wb.wb[ih->rptr_offs] = ih->rptr;
> +               *ih->rptr_cpu = ih->rptr;
>                 WDOORBELL32(ih->doorbell_index, ih->rptr);
>         } else {
>                 WREG32(mmIH_RB_RPTR, ih->rptr);
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index 28b0e9a6cc42..3e9ebb0de94d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -86,11 +86,11 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
>   */
>  static int vega10_ih_irq_init(struct amdgpu_device *adev)
>  {
> +       struct amdgpu_ih_ring *ih = &adev->irq.ih;
>         int ret = 0;
>         int rb_bufsz;
>         u32 ih_rb_cntl, ih_doorbell_rtpr;
>         u32 tmp;
> -       u64 wptr_off;
>
>         /* disable irqs */
>         vega10_ih_disable_interrupts(adev);
> @@ -99,15 +99,11 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>
>         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
>         /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
> -       if (adev->irq.ih.use_bus_addr) {
> -               WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
> -               WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, ((u64)adev->irq.ih.rb_dma_addr >> 40) & 0xff);
> -               ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 1);
> -       } else {
> -               WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
> -               WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (adev->irq.ih.gpu_addr >> 40) & 0xff);
> -               ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 4);
> -       }
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
> +                    (adev->irq.ih.gpu_addr >> 40) & 0xff);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
> +                                  ih->use_bus_addr ? 1 : 4);
>         rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
>         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
>         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
> @@ -124,12 +120,10 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
>
>         /* set the writeback address whether it's enabled or not */
> -       if (adev->irq.ih.use_bus_addr)
> -               wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
> -       else
> -               wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
> -       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
> -       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFFFF);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
> +                    lower_32_bits(ih->wptr_addr));
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI,
> +                    upper_32_bits(ih->wptr_addr) & 0xFFFF);
>
>         /* set rptr, wptr to 0 */
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
> @@ -196,10 +190,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
>  {
>         u32 wptr, tmp;
>
> -       if (ih->use_bus_addr)
> -               wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
> -       else
> -               wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
> +       wptr = le32_to_cpu(*ih->wptr_cpu);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> @@ -275,10 +266,7 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev,
>  {
>         if (ih->use_doorbell) {
>                 /* XXX check if swapping is necessary on BE */
> -               if (ih->use_bus_addr)
> -                       ih->ring[ih->rptr_offs] = ih->rptr;
> -               else
> -                       adev->wb.wb[ih->rptr_offs] = ih->rptr;
> +               *ih->rptr_cpu = ih->rptr;
>                 WDOORBELL32(ih->doorbell_index, ih->rptr);
>         } else {
>                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2
       [not found]     ` <20181130123558.14898-7-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:01       ` Alex Deucher
       [not found]         ` <CADnq5_MwEqFZsPcgtkpL9vQKLEjqUev51QKtak9nEweNZ5Q7_Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:01 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> The entries are ignored for now, but it at least stops crashing the
> hardware when somebody tries to push something to the other IH rings.
>
> v2: limit ring size, add TODO comment
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

We may want to guard this with some flag so we can easily disable it
(like we did for the paging queue) in case we run into issues on any
asics.

Alex

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |   4 +-
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 129 +++++++++++++++++++-----
>  2 files changed, 107 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> index f6ce171cb8aa..7e06fa64321a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> @@ -87,8 +87,8 @@ struct amdgpu_irq {
>         /* status, etc. */
>         bool                            msi_enabled; /* msi enabled */
>
> -       /* interrupt ring */
> -       struct amdgpu_ih_ring           ih;
> +       /* interrupt rings */
> +       struct amdgpu_ih_ring           ih, ih1, ih2;
>         const struct amdgpu_ih_funcs    *ih_funcs;
>
>         /* gen irq stuff */
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index 3e9ebb0de94d..562fd036bb9e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -50,6 +50,16 @@ static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
>         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
>         adev->irq.ih.enabled = true;
> +
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 1);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
> +       adev->irq.ih1.enabled = true;
> +
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 1);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
> +       adev->irq.ih2.enabled = true;
>  }
>
>  /**
> @@ -71,6 +81,47 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
>         adev->irq.ih.enabled = false;
>         adev->irq.ih.rptr = 0;
> +
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 0);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
> +       /* set rptr, wptr to 0 */
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
> +       adev->irq.ih1.enabled = false;
> +       adev->irq.ih1.rptr = 0;
> +
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 0);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
> +       /* set rptr, wptr to 0 */
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
> +       adev->irq.ih2.enabled = false;
> +       adev->irq.ih2.rptr = 0;
> +}
> +
> +static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
> +{
> +       int rb_bufsz = order_base_2(ih->ring_size / 4);
> +
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
> +                                  MC_SPACE, ih->use_bus_addr ? 1 : 4);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
> +                                  WPTR_OVERFLOW_CLEAR, 1);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
> +                                  WPTR_OVERFLOW_ENABLE, 1);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
> +       /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register
> +        * value is written to memory
> +        */
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
> +                                  WPTR_WRITEBACK_ENABLE, 1);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
> +
> +       return ih_rb_cntl;
>  }
>
>  /**
> @@ -86,9 +137,8 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
>   */
>  static int vega10_ih_irq_init(struct amdgpu_device *adev)
>  {
> -       struct amdgpu_ih_ring *ih = &adev->irq.ih;
> +       struct amdgpu_ih_ring *ih;
>         int ret = 0;
> -       int rb_bufsz;
>         u32 ih_rb_cntl, ih_doorbell_rtpr;
>         u32 tmp;
>
> @@ -97,26 +147,15 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>
>         adev->nbio_funcs->ih_control(adev);
>
> -       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
> +       ih = &adev->irq.ih;
>         /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
> -       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
> -       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
> -                    (adev->irq.ih.gpu_addr >> 40) & 0xff);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
> -                                  ih->use_bus_addr ? 1 : 4);
> -       rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
> -       /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
> -
> -       if (adev->irq.msi_enabled)
> -               ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM, 1);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
>
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
> +       ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
> +                                  !!adev->irq.msi_enabled);
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
>
>         /* set the writeback address whether it's enabled or not */
> @@ -131,18 +170,49 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>
>         ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
>         if (adev->irq.ih.use_doorbell) {
> -               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
> -                                                OFFSET, adev->irq.ih.doorbell_index);
> -               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
> +               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
> +                                                IH_DOORBELL_RPTR, OFFSET,
> +                                                adev->irq.ih.doorbell_index);
> +               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
> +                                                IH_DOORBELL_RPTR,
>                                                  ENABLE, 1);
>         } else {
> -               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
> +               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
> +                                                IH_DOORBELL_RPTR,
>                                                  ENABLE, 0);
>         }
>         WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
>         adev->nbio_funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell,
>                                             adev->irq.ih.doorbell_index);
>
> +       ih = &adev->irq.ih1;
> +       /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
> +                    (ih->gpu_addr >> 40) & 0xff);
> +
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
> +       ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
> +
> +       /* set rptr, wptr to 0 */
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
> +
> +       ih = &adev->irq.ih2;
> +       /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
> +                    (ih->gpu_addr >> 40) & 0xff);
> +
> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
> +       ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
> +
> +       /* set rptr, wptr to 0 */
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
> +
>         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
>         tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
>                             CLIENT18_IS_STORM_CLIENT, 1);
> @@ -290,6 +360,15 @@ static int vega10_ih_sw_init(void *handle)
>         if (r)
>                 return r;
>
> +       r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
> +       if (r)
> +               return r;
> +
> +       r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
> +       if (r)
> +               return r;
> +
> +       /* TODO add doorbell for IH1 & IH2 as well */
>         adev->irq.ih.use_doorbell = true;
>         adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
>
> @@ -303,6 +382,8 @@ static int vega10_ih_sw_fini(void *handle)
>         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>
>         amdgpu_irq_fini(adev);
> +       amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
> +       amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
>         amdgpu_ih_ring_fini(adev, &adev->irq.ih);
>
>         return 0;
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 08/11] drm/amdgpu: add the IH to the IV trace
       [not found]     ` <20181130123558.14898-8-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:01       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:01 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> To distinct on which IH ring an IV was found.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c   |  4 ++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 11 +++++++----
>  2 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index 318874952bc2..127ed7de841d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -148,6 +148,8 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
>         entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>         amdgpu_ih_decode_iv(adev, &entry);
>
> +       trace_amdgpu_iv(ih - &adev->irq.ih, &entry);
> +
>         amdgpu_irq_dispatch(adev, &entry);
>  }
>
> @@ -367,8 +369,6 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>         bool handled = false;
>         int r;
>
> -       trace_amdgpu_iv(entry);
> -
>         if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
>                 DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>                 return;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
> index 626abca770a0..6e388d7753c1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
> @@ -76,9 +76,10 @@ TRACE_EVENT(amdgpu_mm_wreg,
>  );
>
>  TRACE_EVENT(amdgpu_iv,
> -           TP_PROTO(struct amdgpu_iv_entry *iv),
> -           TP_ARGS(iv),
> +           TP_PROTO(unsigned ih, struct amdgpu_iv_entry *iv),
> +           TP_ARGS(ih, iv),
>             TP_STRUCT__entry(
> +                            __field(unsigned, ih)
>                              __field(unsigned, client_id)
>                              __field(unsigned, src_id)
>                              __field(unsigned, ring_id)
> @@ -90,6 +91,7 @@ TRACE_EVENT(amdgpu_iv,
>                              __array(unsigned, src_data, 4)
>                             ),
>             TP_fast_assign(
> +                          __entry->ih = ih;
>                            __entry->client_id = iv->client_id;
>                            __entry->src_id = iv->src_id;
>                            __entry->ring_id = iv->ring_id;
> @@ -103,8 +105,9 @@ TRACE_EVENT(amdgpu_iv,
>                            __entry->src_data[2] = iv->src_data[2];
>                            __entry->src_data[3] = iv->src_data[3];
>                            ),
> -           TP_printk("client_id:%u src_id:%u ring:%u vmid:%u timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x",
> -                     __entry->client_id, __entry->src_id,
> +           TP_printk("ih: %u client_id:%u src_id:%u ring:%u vmid:%u "
> +                     "timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x",
> +                     __entry->ih, __entry->client_id, __entry->src_id,
>                       __entry->ring_id, __entry->vmid,
>                       __entry->timestamp, __entry->pasid,
>                       __entry->src_data[0], __entry->src_data[1],
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]     ` <20181130123558.14898-2-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:02       ` Alex Deucher
       [not found]         ` <CADnq5_OipWaH0=BMMmzJMu-gUKZt-L=nG4Dkt2GWQgMnCKxG1w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2018-11-30 20:55       ` Zeng, Oak
  1 sibling, 1 reply; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:02 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> This allows us to filter out VM faults in the GMC code.
>
> v2: don't filter out all faults
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 +++++++++++++++----------
>  1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index 6b6524f04ce0..6db4c58ddc13 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
>         if (!amdgpu_ih_prescreen_iv(adev))
>                 return;
>
> -       /* Before dispatching irq to IP blocks, send it to amdkfd */
> -       amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
> -
>         entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>         amdgpu_ih_decode_iv(adev, &entry);
>
> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>         unsigned client_id = entry->client_id;
>         unsigned src_id = entry->src_id;
>         struct amdgpu_irq_src *src;
> +       bool handled = false;
>         int r;
>
>         trace_amdgpu_iv(entry);
>
>         if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
> -               DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
> +               DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>                 return;
>         }
>
>         if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
> -               DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
> +               DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>                 return;
>         }
>
>         if (adev->irq.virq[src_id]) {
>                 generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
> -       } else {
> -               if (!adev->irq.client[client_id].sources) {
> -                       DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
> -                                 client_id, src_id);
> -                       return;
> -               }
> +               return;
> +       }
>
> +       if (!adev->irq.client[client_id].sources) {
> +               DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
> +                         client_id, src_id);
> +               return;
> +       } else {
>                 src = adev->irq.client[client_id].sources[src_id];
>                 if (!src) {
>                         DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id);
> @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>                 }
>
>                 r = src->funcs->process(adev, src, entry);
> -               if (r)
> +               if (r < 0)
>                         DRM_ERROR("error processing interrupt (%d)\n", r);
> +               else if (r)
> +                       handled = true;
>         }
> +
> +       /* Send it to amdkfd as well if it isn't already handled */
> +       if (!handled)
> +               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>  }
>
>  /**
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling
       [not found]     ` <20181130123558.14898-3-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:04       ` Alex Deucher
  2018-11-30 21:07       ` Zeng, Oak
  1 sibling, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:04 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> printk_ratelimit() is much better suited to limit the number of reported
> VM faults.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 37 -------------------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  5 ----
>  drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 18 +-----------
>  drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 18 +-----------
>  drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 18 +-----------
>  drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 18 +-----------
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c  |  7 ++---
>  7 files changed, 6 insertions(+), 115 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 2acb9838913e..a2f149da83f8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -3057,7 +3057,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
>         }
>
>         INIT_KFIFO(vm->faults);
> -       vm->fault_credit = 16;
>
>         return 0;
>
> @@ -3269,42 +3268,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
>                 amdgpu_vmid_free_reserved(adev, vm, i);
>  }
>
> -/**
> - * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID
> - *
> - * @adev: amdgpu_device pointer
> - * @pasid: PASID do identify the VM
> - *
> - * This function is expected to be called in interrupt context.
> - *
> - * Returns:
> - * True if there was fault credit, false otherwise
> - */
> -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
> -                                 unsigned int pasid)
> -{
> -       struct amdgpu_vm *vm;
> -
> -       spin_lock(&adev->vm_manager.pasid_lock);
> -       vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
> -       if (!vm) {
> -               /* VM not found, can't track fault credit */
> -               spin_unlock(&adev->vm_manager.pasid_lock);
> -               return true;
> -       }
> -
> -       /* No lock needed. only accessed by IRQ handler */
> -       if (!vm->fault_credit) {
> -               /* Too many faults in this VM */
> -               spin_unlock(&adev->vm_manager.pasid_lock);
> -               return false;
> -       }
> -
> -       vm->fault_credit--;
> -       spin_unlock(&adev->vm_manager.pasid_lock);
> -       return true;
> -}
> -
>  /**
>   * amdgpu_vm_manager_init - init the VM manager
>   *
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index 2a8898d19c8b..e8dcfd59fc93 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -229,9 +229,6 @@ struct amdgpu_vm {
>         /* Up to 128 pending retry page faults */
>         DECLARE_KFIFO(faults, u64, 128);
>
> -       /* Limit non-retry fault storms */
> -       unsigned int            fault_credit;
> -
>         /* Points to the KFD process VM info */
>         struct amdkfd_process_info *process_info;
>
> @@ -299,8 +296,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
>  int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);
>  void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
>  void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
> -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
> -                                 unsigned int pasid);
>  void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
>                          struct list_head *validated,
>                          struct amdgpu_bo_list_entry *entry);
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> index b5775c6a857b..3e6c8c4067cb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> @@ -237,23 +237,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
>   */
>  static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)
>  {
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> -       u16 pasid;
> -
> -       switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -       case 146:
> -       case 147:
> -               pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -               if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -                       return true;
> -               break;
> -       default:
> -               /* Not a VM fault */
> -               return true;
> -       }
> -
> -       adev->irq.ih.rptr += 16;
> -       return false;
> +       return true;
>  }
>
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> index df5ac4d85a00..447b3cbc47e5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> @@ -216,23 +216,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
>   */
>  static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)
>  {
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> -       u16 pasid;
> -
> -       switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -       case 146:
> -       case 147:
> -               pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -               if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -                       return true;
> -               break;
> -       default:
> -               /* Not a VM fault */
> -               return true;
> -       }
> -
> -       adev->irq.ih.rptr += 16;
> -       return false;
> +       return true;
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> index cf0fc61aebe6..2b94a6d1550e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> @@ -216,23 +216,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
>   */
>  static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)
>  {
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> -       u16 pasid;
> -
> -       switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -       case 146:
> -       case 147:
> -               pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -               if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -                       return true;
> -               break;
> -       default:
> -               /* Not a VM fault */
> -               return true;
> -       }
> -
> -       adev->irq.ih.rptr += 16;
> -       return false;
> +       return true;
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> index dcdbb4d72472..9d7b43da6acc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> @@ -227,23 +227,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
>   */
>  static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)
>  {
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> -       u16 pasid;
> -
> -       switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -       case 146:
> -       case 147:
> -               pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -               if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -                       return true;
> -               break;
> -       default:
> -               /* Not a VM fault */
> -               return true;
> -       }
> -
> -       adev->irq.ih.rptr += 16;
> -       return false;
> +       return true;
>  }
>
>  /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index d84b687240d1..b49290bcf109 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -258,12 +258,9 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
>         if (!pasid)
>                 return true;
>
> -       /* Not a retry fault, check fault credit */
> -       if (!(dw5 & 0x80)) {
> -               if (!amdgpu_vm_pasid_fault_credit(adev, pasid))
> -                       goto ignore_iv;
> +       /* Not a retry fault */
> +       if (!(dw5 & 0x80))
>                 return true;
> -       }
>
>         /* Track retry faults in per-VM fault FIFO. */
>         spin_lock(&adev->vm_manager.pasid_lock);
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2
       [not found]         ` <CADnq5_MwEqFZsPcgtkpL9vQKLEjqUev51QKtak9nEweNZ5Q7_Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2018-11-30 16:04           ` Christian König
  0 siblings, 0 replies; 32+ messages in thread
From: Christian König @ 2018-11-30 16:04 UTC (permalink / raw)
  To: Alex Deucher; +Cc: amd-gfx list

Am 30.11.18 um 17:01 schrieb Alex Deucher:
> On Fri, Nov 30, 2018 at 7:36 AM Christian König
> <ckoenig.leichtzumerken@gmail.com> wrote:
>> The entries are ignored for now, but it at least stops crashing the
>> hardware when somebody tries to push something to the other IH rings.
>>
>> v2: limit ring size, add TODO comment
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
> We may want to guard this with some flag so we can easily disable it
> (like we did for the paging queue) in case we run into issues on any
> asics.

This should actually fix some issues since when you currently enable 
sources which go to ring 1 & 2 the hardware just crashes.

But I can add some checking if the rings are actually allocated. This 
way we can disable them by just commenting out two lines.

Christian.

>
> Alex
>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 129 +++++++++++++++++++-----
>>   2 files changed, 107 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>> index f6ce171cb8aa..7e06fa64321a 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>> @@ -87,8 +87,8 @@ struct amdgpu_irq {
>>          /* status, etc. */
>>          bool                            msi_enabled; /* msi enabled */
>>
>> -       /* interrupt ring */
>> -       struct amdgpu_ih_ring           ih;
>> +       /* interrupt rings */
>> +       struct amdgpu_ih_ring           ih, ih1, ih2;
>>          const struct amdgpu_ih_funcs    *ih_funcs;
>>
>>          /* gen irq stuff */
>> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
>> index 3e9ebb0de94d..562fd036bb9e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
>> @@ -50,6 +50,16 @@ static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
>>          ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
>>          WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
>>          adev->irq.ih.enabled = true;
>> +
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 1);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
>> +       adev->irq.ih1.enabled = true;
>> +
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 1);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
>> +       adev->irq.ih2.enabled = true;
>>   }
>>
>>   /**
>> @@ -71,6 +81,47 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
>>          WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
>>          adev->irq.ih.enabled = false;
>>          adev->irq.ih.rptr = 0;
>> +
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 0);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
>> +       /* set rptr, wptr to 0 */
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
>> +       adev->irq.ih1.enabled = false;
>> +       adev->irq.ih1.rptr = 0;
>> +
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 0);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
>> +       /* set rptr, wptr to 0 */
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
>> +       adev->irq.ih2.enabled = false;
>> +       adev->irq.ih2.rptr = 0;
>> +}
>> +
>> +static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
>> +{
>> +       int rb_bufsz = order_base_2(ih->ring_size / 4);
>> +
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
>> +                                  MC_SPACE, ih->use_bus_addr ? 1 : 4);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
>> +                                  WPTR_OVERFLOW_CLEAR, 1);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
>> +                                  WPTR_OVERFLOW_ENABLE, 1);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
>> +       /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register
>> +        * value is written to memory
>> +        */
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
>> +                                  WPTR_WRITEBACK_ENABLE, 1);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
>> +
>> +       return ih_rb_cntl;
>>   }
>>
>>   /**
>> @@ -86,9 +137,8 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
>>    */
>>   static int vega10_ih_irq_init(struct amdgpu_device *adev)
>>   {
>> -       struct amdgpu_ih_ring *ih = &adev->irq.ih;
>> +       struct amdgpu_ih_ring *ih;
>>          int ret = 0;
>> -       int rb_bufsz;
>>          u32 ih_rb_cntl, ih_doorbell_rtpr;
>>          u32 tmp;
>>
>> @@ -97,26 +147,15 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>>
>>          adev->nbio_funcs->ih_control(adev);
>>
>> -       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
>> +       ih = &adev->irq.ih;
>>          /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
>> -       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
>> -       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
>> -                    (adev->irq.ih.gpu_addr >> 40) & 0xff);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
>> -                                  ih->use_bus_addr ? 1 : 4);
>> -       rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
>> -       /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
>> -       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
>> -
>> -       if (adev->irq.msi_enabled)
>> -               ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM, 1);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
>>
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
>> +       ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
>> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
>> +                                  !!adev->irq.msi_enabled);
>>          WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
>>
>>          /* set the writeback address whether it's enabled or not */
>> @@ -131,18 +170,49 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>>
>>          ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
>>          if (adev->irq.ih.use_doorbell) {
>> -               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
>> -                                                OFFSET, adev->irq.ih.doorbell_index);
>> -               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
>> +               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
>> +                                                IH_DOORBELL_RPTR, OFFSET,
>> +                                                adev->irq.ih.doorbell_index);
>> +               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
>> +                                                IH_DOORBELL_RPTR,
>>                                                   ENABLE, 1);
>>          } else {
>> -               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
>> +               ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
>> +                                                IH_DOORBELL_RPTR,
>>                                                   ENABLE, 0);
>>          }
>>          WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
>>          adev->nbio_funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell,
>>                                              adev->irq.ih.doorbell_index);
>>
>> +       ih = &adev->irq.ih1;
>> +       /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
>> +                    (ih->gpu_addr >> 40) & 0xff);
>> +
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
>> +       ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
>> +
>> +       /* set rptr, wptr to 0 */
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
>> +
>> +       ih = &adev->irq.ih2;
>> +       /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
>> +                    (ih->gpu_addr >> 40) & 0xff);
>> +
>> +       ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
>> +       ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
>> +
>> +       /* set rptr, wptr to 0 */
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
>> +       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
>> +
>>          tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
>>          tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
>>                              CLIENT18_IS_STORM_CLIENT, 1);
>> @@ -290,6 +360,15 @@ static int vega10_ih_sw_init(void *handle)
>>          if (r)
>>                  return r;
>>
>> +       r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
>> +       if (r)
>> +               return r;
>> +
>> +       r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
>> +       if (r)
>> +               return r;
>> +
>> +       /* TODO add doorbell for IH1 & IH2 as well */
>>          adev->irq.ih.use_doorbell = true;
>>          adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
>>
>> @@ -303,6 +382,8 @@ static int vega10_ih_sw_fini(void *handle)
>>          struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>>
>>          amdgpu_irq_fini(adev);
>> +       amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
>> +       amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
>>          amdgpu_ih_ring_fini(adev, &adev->irq.ih);
>>
>>          return 0;
>> --
>> 2.17.1
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 04/11] drm/amdgpu: move IV prescreening into the GMC code
       [not found]     ` <20181130123558.14898-4-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:05       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:05 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> The GMC/VM subsystem is causing the faults, so move the handling here as
> well.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  |  2 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |  4 --
>  drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 13 ----
>  drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 13 ----
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 59 ++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 13 ----
>  drivers/gpu/drm/amd/amdgpu/si_ih.c      | 14 -----
>  drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 13 ----
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 82 -------------------------
>  9 files changed, 59 insertions(+), 154 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> index 9ce8c93ec19b..f877bb78d10a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> @@ -51,14 +51,12 @@ struct amdgpu_ih_ring {
>  struct amdgpu_ih_funcs {
>         /* ring read/write ptr handling, called from interrupt context */
>         u32 (*get_wptr)(struct amdgpu_device *adev);
> -       bool (*prescreen_iv)(struct amdgpu_device *adev);
>         void (*decode_iv)(struct amdgpu_device *adev,
>                           struct amdgpu_iv_entry *entry);
>         void (*set_rptr)(struct amdgpu_device *adev);
>  };
>
>  #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
> -#define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev))
>  #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
>  #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index 6db4c58ddc13..318874952bc2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -145,10 +145,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
>         u32 ring_index = ih->rptr >> 2;
>         struct amdgpu_iv_entry entry;
>
> -       /* Prescreening of high-frequency interrupts */
> -       if (!amdgpu_ih_prescreen_iv(adev))
> -               return;
> -
>         entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>         amdgpu_ih_decode_iv(adev, &entry);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> index 3e6c8c4067cb..8a8b4967a101 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> @@ -228,18 +228,6 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
>   * [127:96] - reserved
>   */
>
> -/**
> - * cik_ih_prescreen_iv - prescreen an interrupt vector
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Returns true if the interrupt vector should be further processed.
> - */
> -static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)
> -{
> -       return true;
> -}
> -
>   /**
>   * cik_ih_decode_iv - decode an interrupt vector
>   *
> @@ -445,7 +433,6 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = {
>
>  static const struct amdgpu_ih_funcs cik_ih_funcs = {
>         .get_wptr = cik_ih_get_wptr,
> -       .prescreen_iv = cik_ih_prescreen_iv,
>         .decode_iv = cik_ih_decode_iv,
>         .set_rptr = cik_ih_set_rptr
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> index 447b3cbc47e5..9d3ea298e116 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> @@ -207,18 +207,6 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
>         return (wptr & adev->irq.ih.ptr_mask);
>  }
>
> -/**
> - * cz_ih_prescreen_iv - prescreen an interrupt vector
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Returns true if the interrupt vector should be further processed.
> - */
> -static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)
> -{
> -       return true;
> -}
> -
>  /**
>   * cz_ih_decode_iv - decode an interrupt vector
>   *
> @@ -426,7 +414,6 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = {
>
>  static const struct amdgpu_ih_funcs cz_ih_funcs = {
>         .get_wptr = cz_ih_get_wptr,
> -       .prescreen_iv = cz_ih_prescreen_iv,
>         .decode_iv = cz_ih_decode_iv,
>         .set_rptr = cz_ih_set_rptr
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index e329a23e1f99..8995fca47efb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -244,6 +244,62 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
>         return 0;
>  }
>
> +/**
> + * vega10_ih_prescreen_iv - prescreen an interrupt vector
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Returns true if the interrupt vector should be further processed.
> + */
> +static bool gmc_v9_0_prescreen_iv(struct amdgpu_device *adev,
> +                                 struct amdgpu_iv_entry *entry,
> +                                 uint64_t addr)
> +{
> +       struct amdgpu_vm *vm;
> +       u64 key;
> +       int r;
> +
> +       /* No PASID, can't identify faulting process */
> +       if (!entry->pasid)
> +               return true;
> +
> +       /* Not a retry fault */
> +       if (!(entry->src_data[1] & 0x80))
> +               return true;
> +
> +       /* Track retry faults in per-VM fault FIFO. */
> +       spin_lock(&adev->vm_manager.pasid_lock);
> +       vm = idr_find(&adev->vm_manager.pasid_idr, entry->pasid);
> +       if (!vm) {
> +               /* VM not found, process it normally */
> +               spin_unlock(&adev->vm_manager.pasid_lock);
> +               return true;
> +       }
> +
> +       key = AMDGPU_VM_FAULT(entry->pasid, addr);
> +       r = amdgpu_vm_add_fault(vm->fault_hash, key);
> +
> +       /* Hash table is full or the fault is already being processed,
> +        * ignore further page faults
> +        */
> +       if (r != 0) {
> +               spin_unlock(&adev->vm_manager.pasid_lock);
> +               return false;
> +       }
> +       /* No locking required with single writer and single reader */
> +       r = kfifo_put(&vm->faults, key);
> +       if (!r) {
> +               /* FIFO is full. Ignore it until there is space */
> +               amdgpu_vm_clear_fault(vm->fault_hash, key);
> +               spin_unlock(&adev->vm_manager.pasid_lock);
> +               return false;
> +       }
> +
> +       spin_unlock(&adev->vm_manager.pasid_lock);
> +       /* It's the first fault for this address, process it normally */
> +       return true;
> +}
> +
>  static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
>                                 struct amdgpu_irq_src *source,
>                                 struct amdgpu_iv_entry *entry)
> @@ -255,6 +311,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
>         addr = (u64)entry->src_data[0] << 12;
>         addr |= ((u64)entry->src_data[1] & 0xf) << 44;
>
> +       if (!gmc_v9_0_prescreen_iv(adev, entry, addr))
> +               return 1; /* This also prevents sending it to KFD */
> +
>         if (!amdgpu_sriov_vf(adev)) {
>                 status = RREG32(hub->vm_l2_pro_fault_status);
>                 WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
> diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> index 2b94a6d1550e..a3984d10b604 100644
> --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> @@ -207,18 +207,6 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
>         return (wptr & adev->irq.ih.ptr_mask);
>  }
>
> -/**
> - * iceland_ih_prescreen_iv - prescreen an interrupt vector
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Returns true if the interrupt vector should be further processed.
> - */
> -static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)
> -{
> -       return true;
> -}
> -
>  /**
>   * iceland_ih_decode_iv - decode an interrupt vector
>   *
> @@ -424,7 +412,6 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = {
>
>  static const struct amdgpu_ih_funcs iceland_ih_funcs = {
>         .get_wptr = iceland_ih_get_wptr,
> -       .prescreen_iv = iceland_ih_prescreen_iv,
>         .decode_iv = iceland_ih_decode_iv,
>         .set_rptr = iceland_ih_set_rptr
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
> index b3d7d9f83202..2938fb9f17cc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
> @@ -118,19 +118,6 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev)
>         return (wptr & adev->irq.ih.ptr_mask);
>  }
>
> -/**
> - * si_ih_prescreen_iv - prescreen an interrupt vector
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Returns true if the interrupt vector should be further processed.
> - */
> -static bool si_ih_prescreen_iv(struct amdgpu_device *adev)
> -{
> -       /* Process all interrupts */
> -       return true;
> -}
> -
>  static void si_ih_decode_iv(struct amdgpu_device *adev,
>                              struct amdgpu_iv_entry *entry)
>  {
> @@ -301,7 +288,6 @@ static const struct amd_ip_funcs si_ih_ip_funcs = {
>
>  static const struct amdgpu_ih_funcs si_ih_funcs = {
>         .get_wptr = si_ih_get_wptr,
> -       .prescreen_iv = si_ih_prescreen_iv,
>         .decode_iv = si_ih_decode_iv,
>         .set_rptr = si_ih_set_rptr
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> index 9d7b43da6acc..15da06ddeb75 100644
> --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> @@ -218,18 +218,6 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
>         return (wptr & adev->irq.ih.ptr_mask);
>  }
>
> -/**
> - * tonga_ih_prescreen_iv - prescreen an interrupt vector
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Returns true if the interrupt vector should be further processed.
> - */
> -static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)
> -{
> -       return true;
> -}
> -
>  /**
>   * tonga_ih_decode_iv - decode an interrupt vector
>   *
> @@ -490,7 +478,6 @@ static const struct amd_ip_funcs tonga_ih_ip_funcs = {
>
>  static const struct amdgpu_ih_funcs tonga_ih_funcs = {
>         .get_wptr = tonga_ih_get_wptr,
> -       .prescreen_iv = tonga_ih_prescreen_iv,
>         .decode_iv = tonga_ih_decode_iv,
>         .set_rptr = tonga_ih_set_rptr
>  };
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index b49290bcf109..2c250b01a903 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -219,87 +219,6 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
>         return (wptr & adev->irq.ih.ptr_mask);
>  }
>
> -/**
> - * vega10_ih_prescreen_iv - prescreen an interrupt vector
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Returns true if the interrupt vector should be further processed.
> - */
> -static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
> -{
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> -       u32 dw0, dw3, dw4, dw5;
> -       u16 pasid;
> -       u64 addr, key;
> -       struct amdgpu_vm *vm;
> -       int r;
> -
> -       dw0 = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw3 = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> -       dw4 = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]);
> -       dw5 = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]);
> -
> -       /* Filter retry page faults, let only the first one pass. If
> -        * there are too many outstanding faults, ignore them until
> -        * some faults get cleared.
> -        */
> -       switch (dw0 & 0xff) {
> -       case SOC15_IH_CLIENTID_VMC:
> -       case SOC15_IH_CLIENTID_UTCL2:
> -               break;
> -       default:
> -               /* Not a VM fault */
> -               return true;
> -       }
> -
> -       pasid = dw3 & 0xffff;
> -       /* No PASID, can't identify faulting process */
> -       if (!pasid)
> -               return true;
> -
> -       /* Not a retry fault */
> -       if (!(dw5 & 0x80))
> -               return true;
> -
> -       /* Track retry faults in per-VM fault FIFO. */
> -       spin_lock(&adev->vm_manager.pasid_lock);
> -       vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
> -       addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12);
> -       key = AMDGPU_VM_FAULT(pasid, addr);
> -       if (!vm) {
> -               /* VM not found, process it normally */
> -               spin_unlock(&adev->vm_manager.pasid_lock);
> -               return true;
> -       } else {
> -               r = amdgpu_vm_add_fault(vm->fault_hash, key);
> -
> -               /* Hash table is full or the fault is already being processed,
> -                * ignore further page faults
> -                */
> -               if (r != 0) {
> -                       spin_unlock(&adev->vm_manager.pasid_lock);
> -                       goto ignore_iv;
> -               }
> -       }
> -       /* No locking required with single writer and single reader */
> -       r = kfifo_put(&vm->faults, key);
> -       if (!r) {
> -               /* FIFO is full. Ignore it until there is space */
> -               amdgpu_vm_clear_fault(vm->fault_hash, key);
> -               spin_unlock(&adev->vm_manager.pasid_lock);
> -               goto ignore_iv;
> -       }
> -
> -       spin_unlock(&adev->vm_manager.pasid_lock);
> -       /* It's the first fault for this address, process it normally */
> -       return true;
> -
> -ignore_iv:
> -       adev->irq.ih.rptr += 32;
> -       return false;
> -}
> -
>  /**
>   * vega10_ih_decode_iv - decode an interrupt vector
>   *
> @@ -484,7 +403,6 @@ const struct amd_ip_funcs vega10_ih_ip_funcs = {
>
>  static const struct amdgpu_ih_funcs vega10_ih_funcs = {
>         .get_wptr = vega10_ih_get_wptr,
> -       .prescreen_iv = vega10_ih_prescreen_iv,
>         .decode_iv = vega10_ih_decode_iv,
>         .set_rptr = vega10_ih_set_rptr
>  };
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 05/11] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2
       [not found]     ` <20181130123558.14898-5-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:09       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:09 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> Let's start to support multiple rings.
>
> v2: decode IV is needed as well
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c  |  6 +--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  | 13 +++---
>  drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 29 +++++++------
>  drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 31 +++++++-------
>  drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 29 +++++++------
>  drivers/gpu/drm/amd/amdgpu/si_ih.c      | 31 +++++++-------
>  drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 43 ++++++++++---------
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c  | 56 +++++++++++++------------
>  8 files changed, 128 insertions(+), 110 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> index 8af67f649660..fb8dd6179926 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> @@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>         if (!ih->enabled || adev->shutdown)
>                 return IRQ_NONE;
>
> -       wptr = amdgpu_ih_get_wptr(adev);
> +       wptr = amdgpu_ih_get_wptr(adev, ih);
>
>  restart_ih:
>         /* is somebody else already processing irqs? */
> @@ -154,11 +154,11 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>                 ih->rptr &= ih->ptr_mask;
>         }
>
> -       amdgpu_ih_set_rptr(adev);
> +       amdgpu_ih_set_rptr(adev, ih);
>         atomic_set(&ih->lock, 0);
>
>         /* make sure wptr hasn't changed while processing */
> -       wptr = amdgpu_ih_get_wptr(adev);
> +       wptr = amdgpu_ih_get_wptr(adev, ih);
>         if (wptr != ih->rptr)
>                 goto restart_ih;
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> index f877bb78d10a..d810fd73d574 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> @@ -50,15 +50,16 @@ struct amdgpu_ih_ring {
>  /* provided by the ih block */
>  struct amdgpu_ih_funcs {
>         /* ring read/write ptr handling, called from interrupt context */
> -       u32 (*get_wptr)(struct amdgpu_device *adev);
> -       void (*decode_iv)(struct amdgpu_device *adev,
> +       u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
> +       void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>                           struct amdgpu_iv_entry *entry);
> -       void (*set_rptr)(struct amdgpu_device *adev);
> +       void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
>  };
>
> -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
> -#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
> -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
> +#define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih))
> +#define amdgpu_ih_decode_iv(adev, iv) \
> +       (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv))
> +#define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih))
>

Could simplify the interface and skip the adev pointer.  Just hang the
adev off the ih if we need it.  Either way:
Acked-by: Alex Deucher <alexander.deucher@amd.com>


>  int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>                         unsigned ring_size, bool use_bus_addr);
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> index 8a8b4967a101..884aa9b81e86 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> @@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device *adev)
>   * Used by cik_irq_process().
>   * Returns the value of the wptr.
>   */
> -static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
> +static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
> +                          struct amdgpu_ih_ring *ih)
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
> +       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
>
>         if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
>                 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
> @@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
>                  * this should allow us to catchup.
>                  */
>                 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
> -                       wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
> -               adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
> +                        wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
> +               ih->rptr = (wptr + 16) & ih->ptr_mask;
>                 tmp = RREG32(mmIH_RB_CNTL);
>                 tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
>                 WREG32(mmIH_RB_CNTL, tmp);
>         }
> -       return (wptr & adev->irq.ih.ptr_mask);
> +       return (wptr & ih->ptr_mask);
>  }
>
>  /*        CIK IV Ring
> @@ -237,16 +238,17 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
>   * position and also advance the position.
>   */
>  static void cik_ih_decode_iv(struct amdgpu_device *adev,
> +                            struct amdgpu_ih_ring *ih,
>                              struct amdgpu_iv_entry *entry)
>  {
>         /* wptr/rptr are in bytes! */
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> +       u32 ring_index = ih->rptr >> 2;
>         uint32_t dw[4];
>
> -       dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
> -       dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
> -       dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> +       dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
> +       dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
> +       dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
> +       dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
>
>         entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
>         entry->src_id = dw[0] & 0xff;
> @@ -256,7 +258,7 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
>         entry->pasid = (dw[2] >> 16) & 0xffff;
>
>         /* wptr/rptr are in bytes! */
> -       adev->irq.ih.rptr += 16;
> +       ih->rptr += 16;
>  }
>
>  /**
> @@ -266,9 +268,10 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
>   *
>   * Set the IH ring buffer rptr.
>   */
> -static void cik_ih_set_rptr(struct amdgpu_device *adev)
> +static void cik_ih_set_rptr(struct amdgpu_device *adev,
> +                           struct amdgpu_ih_ring *ih)
>  {
> -       WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
> +       WREG32(mmIH_RB_RPTR, ih->rptr);
>  }
>
>  static int cik_ih_early_init(void *handle)
> diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> index 9d3ea298e116..c59eed041fb5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> @@ -185,11 +185,12 @@ static void cz_ih_irq_disable(struct amdgpu_device *adev)
>   * Used by cz_irq_process(VI).
>   * Returns the value of the wptr.
>   */
> -static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
> +static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
> +                         struct amdgpu_ih_ring *ih)
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
> +       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> @@ -198,13 +199,13 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
>                  * this should allow us to catchup.
>                  */
>                 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
> -                       wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
> -               adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
> +                       wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
> +               ih->rptr = (wptr + 16) & ih->ptr_mask;
>                 tmp = RREG32(mmIH_RB_CNTL);
>                 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
>                 WREG32(mmIH_RB_CNTL, tmp);
>         }
> -       return (wptr & adev->irq.ih.ptr_mask);
> +       return (wptr & ih->ptr_mask);
>  }
>
>  /**
> @@ -216,16 +217,17 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
>   * position and also advance the position.
>   */
>  static void cz_ih_decode_iv(struct amdgpu_device *adev,
> -                                struct amdgpu_iv_entry *entry)
> +                           struct amdgpu_ih_ring *ih,
> +                           struct amdgpu_iv_entry *entry)
>  {
>         /* wptr/rptr are in bytes! */
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> +       u32 ring_index = ih->rptr >> 2;
>         uint32_t dw[4];
>
> -       dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
> -       dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
> -       dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> +       dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
> +       dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
> +       dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
> +       dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
>
>         entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
>         entry->src_id = dw[0] & 0xff;
> @@ -235,7 +237,7 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
>         entry->pasid = (dw[2] >> 16) & 0xffff;
>
>         /* wptr/rptr are in bytes! */
> -       adev->irq.ih.rptr += 16;
> +       ih->rptr += 16;
>  }
>
>  /**
> @@ -245,9 +247,10 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
>   *
>   * Set the IH ring buffer rptr.
>   */
> -static void cz_ih_set_rptr(struct amdgpu_device *adev)
> +static void cz_ih_set_rptr(struct amdgpu_device *adev,
> +                          struct amdgpu_ih_ring *ih)
>  {
> -       WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
> +       WREG32(mmIH_RB_RPTR, ih->rptr);
>  }
>
>  static int cz_ih_early_init(void *handle)
> diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> index a3984d10b604..f006ed509db3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> @@ -185,11 +185,12 @@ static void iceland_ih_irq_disable(struct amdgpu_device *adev)
>   * Used by cz_irq_process(VI).
>   * Returns the value of the wptr.
>   */
> -static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
> +static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
> +                              struct amdgpu_ih_ring *ih)
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
> +       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> @@ -198,13 +199,13 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
>                  * this should allow us to catchup.
>                  */
>                 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
> -                       wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
> -               adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
> +                        wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
> +               ih->rptr = (wptr + 16) & ih->ptr_mask;
>                 tmp = RREG32(mmIH_RB_CNTL);
>                 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
>                 WREG32(mmIH_RB_CNTL, tmp);
>         }
> -       return (wptr & adev->irq.ih.ptr_mask);
> +       return (wptr & ih->ptr_mask);
>  }
>
>  /**
> @@ -216,16 +217,17 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
>   * position and also advance the position.
>   */
>  static void iceland_ih_decode_iv(struct amdgpu_device *adev,
> +                                struct amdgpu_ih_ring *ih,
>                                  struct amdgpu_iv_entry *entry)
>  {
>         /* wptr/rptr are in bytes! */
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> +       u32 ring_index = ih->rptr >> 2;
>         uint32_t dw[4];
>
> -       dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
> -       dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
> -       dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> +       dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
> +       dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
> +       dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
> +       dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
>
>         entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
>         entry->src_id = dw[0] & 0xff;
> @@ -235,7 +237,7 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
>         entry->pasid = (dw[2] >> 16) & 0xffff;
>
>         /* wptr/rptr are in bytes! */
> -       adev->irq.ih.rptr += 16;
> +       ih->rptr += 16;
>  }
>
>  /**
> @@ -245,9 +247,10 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
>   *
>   * Set the IH ring buffer rptr.
>   */
> -static void iceland_ih_set_rptr(struct amdgpu_device *adev)
> +static void iceland_ih_set_rptr(struct amdgpu_device *adev,
> +                               struct amdgpu_ih_ring *ih)
>  {
> -       WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
> +       WREG32(mmIH_RB_RPTR, ih->rptr);
>  }
>
>  static int iceland_ih_early_init(void *handle)
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_ih.c b/drivers/gpu/drm/amd/amdgpu/si_ih.c
> index 2938fb9f17cc..5cabc9687f76 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_ih.c
> @@ -100,34 +100,36 @@ static void si_ih_irq_disable(struct amdgpu_device *adev)
>         mdelay(1);
>  }
>
> -static u32 si_ih_get_wptr(struct amdgpu_device *adev)
> +static u32 si_ih_get_wptr(struct amdgpu_device *adev,
> +                         struct amdgpu_ih_ring *ih)
>  {
>         u32 wptr, tmp;
>
> -       wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
> +       wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
>
>         if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
>                 wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
>                 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
> -                       wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
> -               adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
> +                       wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
> +               ih->rptr = (wptr + 16) & ih->ptr_mask;
>                 tmp = RREG32(IH_RB_CNTL);
>                 tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK;
>                 WREG32(IH_RB_CNTL, tmp);
>         }
> -       return (wptr & adev->irq.ih.ptr_mask);
> +       return (wptr & ih->ptr_mask);
>  }
>
>  static void si_ih_decode_iv(struct amdgpu_device *adev,
> -                            struct amdgpu_iv_entry *entry)
> +                           struct amdgpu_ih_ring *ih,
> +                           struct amdgpu_iv_entry *entry)
>  {
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> +       u32 ring_index = ih->rptr >> 2;
>         uint32_t dw[4];
>
> -       dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
> -       dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
> -       dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> +       dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
> +       dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
> +       dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
> +       dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
>
>         entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
>         entry->src_id = dw[0] & 0xff;
> @@ -135,12 +137,13 @@ static void si_ih_decode_iv(struct amdgpu_device *adev,
>         entry->ring_id = dw[2] & 0xff;
>         entry->vmid = (dw[2] >> 8) & 0xff;
>
> -       adev->irq.ih.rptr += 16;
> +       ih->rptr += 16;
>  }
>
> -static void si_ih_set_rptr(struct amdgpu_device *adev)
> +static void si_ih_set_rptr(struct amdgpu_device *adev,
> +                          struct amdgpu_ih_ring *ih)
>  {
> -       WREG32(IH_RB_RPTR, adev->irq.ih.rptr);
> +       WREG32(IH_RB_RPTR, ih->rptr);
>  }
>
>  static int si_ih_early_init(void *handle)
> diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> index 15da06ddeb75..30e3911dedb5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> @@ -193,14 +193,15 @@ static void tonga_ih_irq_disable(struct amdgpu_device *adev)
>   * Used by cz_irq_process(VI).
>   * Returns the value of the wptr.
>   */
> -static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
> +static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
> +                            struct amdgpu_ih_ring *ih)
>  {
>         u32 wptr, tmp;
>
>         if (adev->irq.ih.use_bus_addr)
> -               wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]);
> +               wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
>         else
> -               wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
> +               wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> @@ -209,13 +210,13 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
>                  * this should allow us to catchup.
>                  */
>                 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
> -                       wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
> -               adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
> +                        wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
> +               ih->rptr = (wptr + 16) & ih->ptr_mask;
>                 tmp = RREG32(mmIH_RB_CNTL);
>                 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
>                 WREG32(mmIH_RB_CNTL, tmp);
>         }
> -       return (wptr & adev->irq.ih.ptr_mask);
> +       return (wptr & ih->ptr_mask);
>  }
>
>  /**
> @@ -227,16 +228,17 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
>   * position and also advance the position.
>   */
>  static void tonga_ih_decode_iv(struct amdgpu_device *adev,
> -                                struct amdgpu_iv_entry *entry)
> +                              struct amdgpu_ih_ring *ih,
> +                              struct amdgpu_iv_entry *entry)
>  {
>         /* wptr/rptr are in bytes! */
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> +       u32 ring_index = ih->rptr >> 2;
>         uint32_t dw[4];
>
> -       dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
> -       dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
> -       dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> +       dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
> +       dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
> +       dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
> +       dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
>
>         entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
>         entry->src_id = dw[0] & 0xff;
> @@ -246,7 +248,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
>         entry->pasid = (dw[2] >> 16) & 0xffff;
>
>         /* wptr/rptr are in bytes! */
> -       adev->irq.ih.rptr += 16;
> +       ih->rptr += 16;
>  }
>
>  /**
> @@ -256,17 +258,18 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
>   *
>   * Set the IH ring buffer rptr.
>   */
> -static void tonga_ih_set_rptr(struct amdgpu_device *adev)
> +static void tonga_ih_set_rptr(struct amdgpu_device *adev,
> +                             struct amdgpu_ih_ring *ih)
>  {
> -       if (adev->irq.ih.use_doorbell) {
> +       if (ih->use_doorbell) {
>                 /* XXX check if swapping is necessary on BE */
> -               if (adev->irq.ih.use_bus_addr)
> -                       adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
> +               if (ih->use_bus_addr)
> +                       ih->ring[ih->rptr_offs] = ih->rptr;
>                 else
> -                       adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
> -               WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr);
> +                       adev->wb.wb[ih->rptr_offs] = ih->rptr;
> +               WDOORBELL32(ih->doorbell_index, ih->rptr);
>         } else {
> -               WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
> +               WREG32(mmIH_RB_RPTR, ih->rptr);
>         }
>  }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index 2c250b01a903..28b0e9a6cc42 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -191,14 +191,15 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev)
>   * ring buffer overflow and deal with it.
>   * Returns the value of the wptr.
>   */
> -static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
> +static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
> +                             struct amdgpu_ih_ring *ih)
>  {
>         u32 wptr, tmp;
>
> -       if (adev->irq.ih.use_bus_addr)
> -               wptr = le32_to_cpu(adev->irq.ih.ring[adev->irq.ih.wptr_offs]);
> +       if (ih->use_bus_addr)
> +               wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
>         else
> -               wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
> +               wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
>
>         if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
>                 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
> @@ -207,16 +208,16 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
>                  * from the last not overwritten vector (wptr + 32). Hopefully
>                  * this should allow us to catchup.
>                  */
> -               tmp = (wptr + 32) & adev->irq.ih.ptr_mask;
> +               tmp = (wptr + 32) & ih->ptr_mask;
>                 dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
> -                       wptr, adev->irq.ih.rptr, tmp);
> -               adev->irq.ih.rptr = tmp;
> +                        wptr, ih->rptr, tmp);
> +               ih->rptr = tmp;
>
>                 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
>                 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
>                 WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp);
>         }
> -       return (wptr & adev->irq.ih.ptr_mask);
> +       return (wptr & ih->ptr_mask);
>  }
>
>  /**
> @@ -228,20 +229,21 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
>   * position and also advance the position.
>   */
>  static void vega10_ih_decode_iv(struct amdgpu_device *adev,
> -                                struct amdgpu_iv_entry *entry)
> +                               struct amdgpu_ih_ring *ih,
> +                               struct amdgpu_iv_entry *entry)
>  {
>         /* wptr/rptr are in bytes! */
> -       u32 ring_index = adev->irq.ih.rptr >> 2;
> +       u32 ring_index = ih->rptr >> 2;
>         uint32_t dw[8];
>
> -       dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
> -       dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
> -       dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
> -       dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
> -       dw[4] = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]);
> -       dw[5] = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]);
> -       dw[6] = le32_to_cpu(adev->irq.ih.ring[ring_index + 6]);
> -       dw[7] = le32_to_cpu(adev->irq.ih.ring[ring_index + 7]);
> +       dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
> +       dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
> +       dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
> +       dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
> +       dw[4] = le32_to_cpu(ih->ring[ring_index + 4]);
> +       dw[5] = le32_to_cpu(ih->ring[ring_index + 5]);
> +       dw[6] = le32_to_cpu(ih->ring[ring_index + 6]);
> +       dw[7] = le32_to_cpu(ih->ring[ring_index + 7]);
>
>         entry->client_id = dw[0] & 0xff;
>         entry->src_id = (dw[0] >> 8) & 0xff;
> @@ -257,9 +259,8 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
>         entry->src_data[2] = dw[6];
>         entry->src_data[3] = dw[7];
>
> -
>         /* wptr/rptr are in bytes! */
> -       adev->irq.ih.rptr += 32;
> +       ih->rptr += 32;
>  }
>
>  /**
> @@ -269,17 +270,18 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
>   *
>   * Set the IH ring buffer rptr.
>   */
> -static void vega10_ih_set_rptr(struct amdgpu_device *adev)
> +static void vega10_ih_set_rptr(struct amdgpu_device *adev,
> +                              struct amdgpu_ih_ring *ih)
>  {
> -       if (adev->irq.ih.use_doorbell) {
> +       if (ih->use_doorbell) {
>                 /* XXX check if swapping is necessary on BE */
> -               if (adev->irq.ih.use_bus_addr)
> -                       adev->irq.ih.ring[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
> +               if (ih->use_bus_addr)
> +                       ih->ring[ih->rptr_offs] = ih->rptr;
>                 else
> -                       adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
> -               WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr);
> +                       adev->wb.wb[ih->rptr_offs] = ih->rptr;
> +               WDOORBELL32(ih->doorbell_index, ih->rptr);
>         } else {
> -               WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, adev->irq.ih.rptr);
> +               WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
>         }
>  }
>
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 09/11] drm/amdgpu: add support for processing IH ring 1 & 2
       [not found]     ` <20181130123558.14898-9-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:10       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:10 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> Previously we only added the ring buffer memory, now add the handling as
> well.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 33 +++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |  4 ++-
>  2 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index 127ed7de841d..64ec92bd74fb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -176,6 +176,36 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
>         return ret;
>  }
>
> +/**
> + * amdgpu_irq_handle_ih1 - kick of processing for IH1
> + *
> + * @work: work structure in struct amdgpu_irq
> + *
> + * Kick of processing IH ring 1.
> + */
> +static void amdgpu_irq_handle_ih1(struct work_struct *work)
> +{
> +       struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
> +                                                 irq.ih1_work);
> +
> +       amdgpu_ih_process(adev, &adev->irq.ih1, amdgpu_irq_callback);
> +}
> +
> +/**
> + * amdgpu_irq_handle_ih2 - kick of processing for IH2
> + *
> + * @work: work structure in struct amdgpu_irq
> + *
> + * Kick of processing IH ring 2.
> + */
> +static void amdgpu_irq_handle_ih2(struct work_struct *work)
> +{
> +       struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
> +                                                 irq.ih2_work);
> +
> +       amdgpu_ih_process(adev, &adev->irq.ih2, amdgpu_irq_callback);
> +}
> +
>  /**
>   * amdgpu_msi_ok - check whether MSI functionality is enabled
>   *
> @@ -240,6 +270,9 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
>                                 amdgpu_hotplug_work_func);
>         }
>
> +       INIT_WORK(&adev->irq.ih1_work, amdgpu_irq_handle_ih1);
> +       INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
> +
>         adev->irq.installed = true;
>         r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq);
>         if (r) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> index 7e06fa64321a..c27decfda494 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> @@ -89,7 +89,9 @@ struct amdgpu_irq {
>
>         /* interrupt rings */
>         struct amdgpu_ih_ring           ih, ih1, ih2;
> -       const struct amdgpu_ih_funcs    *ih_funcs;
> +       const struct amdgpu_ih_funcs    *ih_funcs;
> +       struct work_struct              ih1_work, ih2_work;
> +       struct amdgpu_irq_src           self_irq;
>
>         /* gen irq stuff */
>         struct irq_domain               *domain; /* GPU irq controller domain */
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 10/11] drm/amdgpu: add support for self irq on Vega10
       [not found]     ` <20181130123558.14898-10-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:11       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:11 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> This finally enables processing of ring 1 & 2.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 68 ++++++++++++++++++++++++--
>  1 file changed, 63 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index 562fd036bb9e..f5c5ea628fdf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -258,7 +258,7 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev)
>  static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
>                               struct amdgpu_ih_ring *ih)
>  {
> -       u32 wptr, tmp;
> +       u32 wptr, reg, tmp;
>
>         wptr = le32_to_cpu(*ih->wptr_cpu);
>
> @@ -274,9 +274,18 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
>                          wptr, ih->rptr, tmp);
>                 ih->rptr = tmp;
>
> -               tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
> +               if (ih == &adev->irq.ih)
> +                       reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
> +               else if (ih == &adev->irq.ih1)
> +                       reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
> +               else if (ih == &adev->irq.ih2)
> +                       reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
> +               else
> +                       BUG();
> +
> +               tmp = RREG32_NO_KIQ(reg);
>                 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
> -               WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp);
> +               WREG32_NO_KIQ(reg, tmp);
>         }
>         return (wptr & ih->ptr_mask);
>  }
> @@ -338,9 +347,52 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev,
>                 /* XXX check if swapping is necessary on BE */
>                 *ih->rptr_cpu = ih->rptr;
>                 WDOORBELL32(ih->doorbell_index, ih->rptr);
> -       } else {
> +       } else if (ih == &adev->irq.ih) {
>                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
> +       } else if (ih == &adev->irq.ih1) {
> +               WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
> +       } else if (ih == &adev->irq.ih2) {
> +               WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
> +       }
> +}
> +
> +/**
> + * vega10_ih_self_irq - dispatch work for ring 1 and 2
> + *
> + * @adev: amdgpu_device pointer
> + * @source: irq source
> + * @entry: IV with WPTR update
> + *
> + * Update the WPTR from the IV and schedule work to handle the entries.
> + */
> +static int vega10_ih_self_irq(struct amdgpu_device *adev,
> +                             struct amdgpu_irq_src *source,
> +                             struct amdgpu_iv_entry *entry)
> +{
> +       uint32_t wptr = cpu_to_le32(entry->src_data[0]);
> +
> +       switch (entry->ring_id) {
> +       case 1:
> +               *adev->irq.ih1.wptr_cpu = wptr;
> +               schedule_work(&adev->irq.ih1_work);
> +               break;
> +       case 2:
> +               *adev->irq.ih2.wptr_cpu = wptr;
> +               schedule_work(&adev->irq.ih2_work);
> +               break;
> +       default: break;
>         }
> +       return 0;
> +}
> +
> +static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = {
> +       .process = vega10_ih_self_irq,
> +};
> +
> +static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
> +{
> +       adev->irq.self_irq.num_types = 0;
> +       adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs;
>  }
>
>  static int vega10_ih_early_init(void *handle)
> @@ -348,13 +400,19 @@ static int vega10_ih_early_init(void *handle)
>         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>
>         vega10_ih_set_interrupt_funcs(adev);
> +       vega10_ih_set_self_irq_funcs(adev);
>         return 0;
>  }
>
>  static int vega10_ih_sw_init(void *handle)
>  {
> -       int r;
>         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +       int r;
> +
> +       r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
> +                             &adev->irq.self_irq);
> +       if (r)
> +               return r;
>
>         r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true);
>         if (r)
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 11/11] drm/amdgpu: disable IH ring 1 & 2 WPTR overflow on Vega10
       [not found]     ` <20181130123558.14898-11-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-11-30 16:11       ` Alex Deucher
  0 siblings, 0 replies; 32+ messages in thread
From: Alex Deucher @ 2018-11-30 16:11 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx list

On Fri, Nov 30, 2018 at 7:36 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> That should add back pressure on the client.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index f5c5ea628fdf..dd7f52f08fd7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -193,6 +193,8 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>
>         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
>         ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
> +                                  WPTR_OVERFLOW_ENABLE, 0);
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
>
>         /* set rptr, wptr to 0 */
> @@ -207,6 +209,8 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
>
>         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
>         ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
> +       ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
> +                                  WPTR_OVERFLOW_ENABLE, 0);
>         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
>
>         /* set rptr, wptr to 0 */
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]         ` <CADnq5_OipWaH0=BMMmzJMu-gUKZt-L=nG4Dkt2GWQgMnCKxG1w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2018-11-30 16:31           ` Kuehling, Felix
       [not found]             ` <DM5PR12MB17078A9132DCA1AD4920300192D30-2J9CzHegvk9TCtO+SvGBKwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  0 siblings, 1 reply; 32+ messages in thread
From: Kuehling, Felix @ 2018-11-30 16:31 UTC (permalink / raw)
  To: Alex Deucher, Christian König; +Cc: amd-gfx list

Won't this break VM fault handling in KFD? I don't see a way with the current code that you can leave some VM faults for KFD to process. If we could consider VM faults with VMIDs 8-15 as not handled in amdgpu and leave them for KFD to process, then this could work.

As far as I can tell, the only code path that leave IRQs unhandled and passes them to KFD prints an error message in the kernel log. We can't have the kernel log flooded with error messages every time there are IRQs for KFD. We can get extremely high frequency interrupts for HSA signals.

Regards,
  Felix

-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
Sent: Friday, November 30, 2018 10:03 AM
To: Christian König <ckoenig.leichtzumerken@gmail.com>
Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>
Subject: Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2

On Fri, Nov 30, 2018 at 7:36 AM Christian König <ckoenig.leichtzumerken@gmail.com> wrote:
>
> This allows us to filter out VM faults in the GMC code.
>
> v2: don't filter out all faults
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 
> +++++++++++++++----------
>  1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index 6b6524f04ce0..6db4c58ddc13 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
>         if (!amdgpu_ih_prescreen_iv(adev))
>                 return;
>
> -       /* Before dispatching irq to IP blocks, send it to amdkfd */
> -       amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
> -
>         entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>         amdgpu_ih_decode_iv(adev, &entry);
>
> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>         unsigned client_id = entry->client_id;
>         unsigned src_id = entry->src_id;
>         struct amdgpu_irq_src *src;
> +       bool handled = false;
>         int r;
>
>         trace_amdgpu_iv(entry);
>
>         if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
> -               DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
> +               DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>                 return;
>         }
>
>         if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
> -               DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
> +               DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>                 return;
>         }
>
>         if (adev->irq.virq[src_id]) {
>                 generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
> -       } else {
> -               if (!adev->irq.client[client_id].sources) {
> -                       DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
> -                                 client_id, src_id);
> -                       return;
> -               }
> +               return;
> +       }
>
> +       if (!adev->irq.client[client_id].sources) {
> +               DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
> +                         client_id, src_id);
> +               return;
> +       } else {
>                 src = adev->irq.client[client_id].sources[src_id];
>                 if (!src) {
>                         DRM_DEBUG("Unhandled interrupt src_id: %d\n", 
> src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>                 }
>
>                 r = src->funcs->process(adev, src, entry);
> -               if (r)
> +               if (r < 0)
>                         DRM_ERROR("error processing interrupt (%d)\n", 
> r);
> +               else if (r)
> +                       handled = true;
>         }
> +
> +       /* Send it to amdkfd as well if it isn't already handled */
> +       if (!handled)
> +               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>  }
>
>  /**
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]     ` <20181130123558.14898-2-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 16:02       ` Alex Deucher
@ 2018-11-30 20:55       ` Zeng, Oak
       [not found]         ` <BN6PR12MB1651C628F04CBC8AD670590A80D30-/b2+HYfkarRSqX7PDniLCgdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  1 sibling, 1 reply; 32+ messages in thread
From: Zeng, Oak @ 2018-11-30 20:55 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

See comment [Oak]

Thanks,
Oak

-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Christian König
Sent: Friday, November 30, 2018 7:36 AM
To: amd-gfx@lists.freedesktop.org
Subject: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2

This allows us to filter out VM faults in the GMC code.

v2: don't filter out all faults

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 +++++++++++++++----------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 6b6524f04ce0..6db4c58ddc13 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
 	if (!amdgpu_ih_prescreen_iv(adev))
 		return;
 
-	/* Before dispatching irq to IP blocks, send it to amdkfd */
-	amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
-
 	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
 	amdgpu_ih_decode_iv(adev, &entry);
 
@@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
 	unsigned client_id = entry->client_id;
 	unsigned src_id = entry->src_id;
 	struct amdgpu_irq_src *src;
+	bool handled = false;
 	int r;
 
 	trace_amdgpu_iv(entry);
 
 	if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
-		DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
+		DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
 		return;
 	}
 
 	if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
-		DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
+		DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
 		return;
 	}
 
 	if (adev->irq.virq[src_id]) {
 		generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
-	} else {
-		if (!adev->irq.client[client_id].sources) {
-			DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
-				  client_id, src_id);
-			return;
-		}
+		return;
+	}
 
+	if (!adev->irq.client[client_id].sources) {
+		DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
+			  client_id, src_id);
+		return;
+	} else {
[Oak]: you probably don't need a else because the return in above if. 
 		src = adev->irq.client[client_id].sources[src_id];
 		if (!src) {
 			DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
 		}
 
 		r = src->funcs->process(adev, src, entry);
-		if (r)
+		if (r < 0)
 			DRM_ERROR("error processing interrupt (%d)\n", r);
+		else if (r)
+			handled = true;
 	}
+
+	/* Send it to amdkfd as well if it isn't already handled */
+	if (!handled)
[Oak]: Kfd cares about followed interrupt source/client. How can we guarantee that those are not handled by registered interrupt handler at amdgpu level?
		source_id == SOC15_INTSRC_CP_END_OF_PIPE ||
		source_id == SOC15_INTSRC_SDMA_TRAP ||
		source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG ||
		source_id == SOC15_INTSRC_CP_BAD_OPCODE ||
		client_id == SOC15_IH_CLIENTID_VMC ||
		client_id == SOC15_IH_CLIENTID_UTCL2;

To completely avoid this, we should remove the amdgpu_amdkfd_interrupt function. Instead, kfd interrupt handling functions should be splitted and registered to adev->irq.client[].sources[]

+		amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
 }
 
 /**
--
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* RE: [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling
       [not found]     ` <20181130123558.14898-3-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-11-30 16:04       ` Alex Deucher
@ 2018-11-30 21:07       ` Zeng, Oak
       [not found]         ` <BN6PR12MB1651C10E3977C786DE29BB1980D30-/b2+HYfkarRSqX7PDniLCgdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  1 sibling, 1 reply; 32+ messages in thread
From: Zeng, Oak @ 2018-11-30 21:07 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

The credit was used to limit vm (retry) fault to be processed in each VM. If this is removed, it is possible that you get flooded interrupt storm.

Even though you claimed from the commit message that, printk_ratelimit is a better solution, I didn't see you implement it in this patch. Are you planning a future patch?

Thanks,
Oak

-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Christian König
Sent: Friday, November 30, 2018 7:36 AM
To: amd-gfx@lists.freedesktop.org
Subject: [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling

printk_ratelimit() is much better suited to limit the number of reported VM faults.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 37 -------------------------  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  5 ----
 drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 18 +-----------
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c  |  7 ++---
 7 files changed, 6 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 2acb9838913e..a2f149da83f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3057,7 +3057,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	}
 
 	INIT_KFIFO(vm->faults);
-	vm->fault_credit = 16;
 
 	return 0;
 
@@ -3269,42 +3268,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 		amdgpu_vmid_free_reserved(adev, vm, i);  }
 
-/**
- * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID
- *
- * @adev: amdgpu_device pointer
- * @pasid: PASID do identify the VM
- *
- * This function is expected to be called in interrupt context.
- *
- * Returns:
- * True if there was fault credit, false otherwise
- */
-bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
-				  unsigned int pasid)
-{
-	struct amdgpu_vm *vm;
-
-	spin_lock(&adev->vm_manager.pasid_lock);
-	vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
-	if (!vm) {
-		/* VM not found, can't track fault credit */
-		spin_unlock(&adev->vm_manager.pasid_lock);
-		return true;
-	}
-
-	/* No lock needed. only accessed by IRQ handler */
-	if (!vm->fault_credit) {
-		/* Too many faults in this VM */
-		spin_unlock(&adev->vm_manager.pasid_lock);
-		return false;
-	}
-
-	vm->fault_credit--;
-	spin_unlock(&adev->vm_manager.pasid_lock);
-	return true;
-}
-
 /**
  * amdgpu_vm_manager_init - init the VM manager
  *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 2a8898d19c8b..e8dcfd59fc93 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -229,9 +229,6 @@ struct amdgpu_vm {
 	/* Up to 128 pending retry page faults */
 	DECLARE_KFIFO(faults, u64, 128);
 
-	/* Limit non-retry fault storms */
-	unsigned int		fault_credit;
-
 	/* Points to the KFD process VM info */
 	struct amdkfd_process_info *process_info;
 
@@ -299,8 +296,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,  int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);  void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);  void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
-				  unsigned int pasid);
 void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
 			 struct list_head *validated,
 			 struct amdgpu_bo_list_entry *entry); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
index b5775c6a857b..3e6c8c4067cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
@@ -237,23 +237,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)  {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
  /**
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
index df5ac4d85a00..447b3cbc47e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
@@ -216,23 +216,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)  {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
index cf0fc61aebe6..2b94a6d1550e 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
@@ -216,23 +216,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)  {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
index dcdbb4d72472..9d7b43da6acc 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
@@ -227,23 +227,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
  */
 static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)  {
-	u32 ring_index = adev->irq.ih.rptr >> 2;
-	u16 pasid;
-
-	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
-	case 146:
-	case 147:
-		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
-		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
-			return true;
-		break;
-	default:
-		/* Not a VM fault */
-		return true;
-	}
-
-	adev->irq.ih.rptr += 16;
-	return false;
+	return true;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index d84b687240d1..b49290bcf109 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -258,12 +258,9 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
 	if (!pasid)
 		return true;
 
-	/* Not a retry fault, check fault credit */
-	if (!(dw5 & 0x80)) {
-		if (!amdgpu_vm_pasid_fault_credit(adev, pasid))
-			goto ignore_iv;
+	/* Not a retry fault */
+	if (!(dw5 & 0x80))
 		return true;
-	}
 
 	/* Track retry faults in per-VM fault FIFO. */
 	spin_lock(&adev->vm_manager.pasid_lock);
--
2.17.1

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

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling
       [not found]         ` <BN6PR12MB1651C10E3977C786DE29BB1980D30-/b2+HYfkarRSqX7PDniLCgdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2018-12-01 13:59           ` Christian König
  0 siblings, 0 replies; 32+ messages in thread
From: Christian König @ 2018-12-01 13:59 UTC (permalink / raw)
  To: Zeng, Oak, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This code was never used for retry faults, but only for non-retry faults 
and on HW generations older than GFX9.

Those handling where always protected by calls to "printk_ratelimit()" 
to prevent flooding the system log.

So the handling was never necessary to begin with,
Christian.

Am 30.11.18 um 22:07 schrieb Zeng, Oak:
> The credit was used to limit vm (retry) fault to be processed in each VM. If this is removed, it is possible that you get flooded interrupt storm.
>
> Even though you claimed from the commit message that, printk_ratelimit is a better solution, I didn't see you implement it in this patch. Are you planning a future patch?
>
> Thanks,
> Oak
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Christian König
> Sent: Friday, November 30, 2018 7:36 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling
>
> printk_ratelimit() is much better suited to limit the number of reported VM faults.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 37 -------------------------  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  5 ----
>   drivers/gpu/drm/amd/amdgpu/cik_ih.c     | 18 +-----------
>   drivers/gpu/drm/amd/amdgpu/cz_ih.c      | 18 +-----------
>   drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 18 +-----------
>   drivers/gpu/drm/amd/amdgpu/tonga_ih.c   | 18 +-----------
>   drivers/gpu/drm/amd/amdgpu/vega10_ih.c  |  7 ++---
>   7 files changed, 6 insertions(+), 115 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 2acb9838913e..a2f149da83f8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -3057,7 +3057,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
>   	}
>   
>   	INIT_KFIFO(vm->faults);
> -	vm->fault_credit = 16;
>   
>   	return 0;
>   
> @@ -3269,42 +3268,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
>   		amdgpu_vmid_free_reserved(adev, vm, i);  }
>   
> -/**
> - * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID
> - *
> - * @adev: amdgpu_device pointer
> - * @pasid: PASID do identify the VM
> - *
> - * This function is expected to be called in interrupt context.
> - *
> - * Returns:
> - * True if there was fault credit, false otherwise
> - */
> -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
> -				  unsigned int pasid)
> -{
> -	struct amdgpu_vm *vm;
> -
> -	spin_lock(&adev->vm_manager.pasid_lock);
> -	vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
> -	if (!vm) {
> -		/* VM not found, can't track fault credit */
> -		spin_unlock(&adev->vm_manager.pasid_lock);
> -		return true;
> -	}
> -
> -	/* No lock needed. only accessed by IRQ handler */
> -	if (!vm->fault_credit) {
> -		/* Too many faults in this VM */
> -		spin_unlock(&adev->vm_manager.pasid_lock);
> -		return false;
> -	}
> -
> -	vm->fault_credit--;
> -	spin_unlock(&adev->vm_manager.pasid_lock);
> -	return true;
> -}
> -
>   /**
>    * amdgpu_vm_manager_init - init the VM manager
>    *
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index 2a8898d19c8b..e8dcfd59fc93 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -229,9 +229,6 @@ struct amdgpu_vm {
>   	/* Up to 128 pending retry page faults */
>   	DECLARE_KFIFO(faults, u64, 128);
>   
> -	/* Limit non-retry fault storms */
> -	unsigned int		fault_credit;
> -
>   	/* Points to the KFD process VM info */
>   	struct amdkfd_process_info *process_info;
>   
> @@ -299,8 +296,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,  int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid);  void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);  void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
> -				  unsigned int pasid);
>   void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
>   			 struct list_head *validated,
>   			 struct amdgpu_bo_list_entry *entry); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> index b5775c6a857b..3e6c8c4067cb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c
> @@ -237,23 +237,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
>    */
>   static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)  {
> -	u32 ring_index = adev->irq.ih.rptr >> 2;
> -	u16 pasid;
> -
> -	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -	case 146:
> -	case 147:
> -		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -			return true;
> -		break;
> -	default:
> -		/* Not a VM fault */
> -		return true;
> -	}
> -
> -	adev->irq.ih.rptr += 16;
> -	return false;
> +	return true;
>   }
>   
>    /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> index df5ac4d85a00..447b3cbc47e5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c
> @@ -216,23 +216,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
>    */
>   static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)  {
> -	u32 ring_index = adev->irq.ih.rptr >> 2;
> -	u16 pasid;
> -
> -	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -	case 146:
> -	case 147:
> -		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -			return true;
> -		break;
> -	default:
> -		/* Not a VM fault */
> -		return true;
> -	}
> -
> -	adev->irq.ih.rptr += 16;
> -	return false;
> +	return true;
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> index cf0fc61aebe6..2b94a6d1550e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
> @@ -216,23 +216,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
>    */
>   static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)  {
> -	u32 ring_index = adev->irq.ih.rptr >> 2;
> -	u16 pasid;
> -
> -	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -	case 146:
> -	case 147:
> -		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -			return true;
> -		break;
> -	default:
> -		/* Not a VM fault */
> -		return true;
> -	}
> -
> -	adev->irq.ih.rptr += 16;
> -	return false;
> +	return true;
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> index dcdbb4d72472..9d7b43da6acc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/tonga_ih.c
> @@ -227,23 +227,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
>    */
>   static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)  {
> -	u32 ring_index = adev->irq.ih.rptr >> 2;
> -	u16 pasid;
> -
> -	switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
> -	case 146:
> -	case 147:
> -		pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
> -		if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
> -			return true;
> -		break;
> -	default:
> -		/* Not a VM fault */
> -		return true;
> -	}
> -
> -	adev->irq.ih.rptr += 16;
> -	return false;
> +	return true;
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index d84b687240d1..b49290bcf109 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -258,12 +258,9 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
>   	if (!pasid)
>   		return true;
>   
> -	/* Not a retry fault, check fault credit */
> -	if (!(dw5 & 0x80)) {
> -		if (!amdgpu_vm_pasid_fault_credit(adev, pasid))
> -			goto ignore_iv;
> +	/* Not a retry fault */
> +	if (!(dw5 & 0x80))
>   		return true;
> -	}
>   
>   	/* Track retry faults in per-VM fault FIFO. */
>   	spin_lock(&adev->vm_manager.pasid_lock);
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]             ` <DM5PR12MB17078A9132DCA1AD4920300192D30-2J9CzHegvk9TCtO+SvGBKwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2018-12-01 14:11               ` Christian König
       [not found]                 ` <b2792f9c-127a-b738-9e11-400525b00ed2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-12-01 14:11 UTC (permalink / raw)
  To: Kuehling, Felix, Alex Deucher; +Cc: amd-gfx list

> Won't this break VM fault handling in KFD?
No, we still send all VM faults to KFD after processing them. Only 
filtered retries are not send to the KFD any more.

> As far as I can tell, the only code path that leave IRQs unhandled and passes them to KFD prints an error message in the kernel log. We can't have the kernel log flooded with error messages every time there are IRQs for KFD. We can get extremely high frequency interrupts for HSA signals.
Since the KFD didn't filtered the faults this would have a been a 
problem before as well.

So I'm pretty sure that we already have registered handlers for all 
interrupts the KFD is interested in as well.

Regards,
Christian.

Am 30.11.18 um 17:31 schrieb Kuehling, Felix:
> Won't this break VM fault handling in KFD? I don't see a way with the current code that you can leave some VM faults for KFD to process. If we could consider VM faults with VMIDs 8-15 as not handled in amdgpu and leave them for KFD to process, then this could work.
>
> As far as I can tell, the only code path that leave IRQs unhandled and passes them to KFD prints an error message in the kernel log. We can't have the kernel log flooded with error messages every time there are IRQs for KFD. We can get extremely high frequency interrupts for HSA signals.
>
> Regards,
>    Felix
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Alex Deucher
> Sent: Friday, November 30, 2018 10:03 AM
> To: Christian König <ckoenig.leichtzumerken@gmail.com>
> Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>
> Subject: Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
>
> On Fri, Nov 30, 2018 at 7:36 AM Christian König <ckoenig.leichtzumerken@gmail.com> wrote:
>> This allows us to filter out VM faults in the GMC code.
>>
>> v2: don't filter out all faults
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
> Acked-by: Alex Deucher <alexander.deucher@amd.com>
>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29
>> +++++++++++++++----------
>>   1 file changed, 17 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> index 6b6524f04ce0..6db4c58ddc13 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
>>          if (!amdgpu_ih_prescreen_iv(adev))
>>                  return;
>>
>> -       /* Before dispatching irq to IP blocks, send it to amdkfd */
>> -       amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
>> -
>>          entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>>          amdgpu_ih_decode_iv(adev, &entry);
>>
>> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>>          unsigned client_id = entry->client_id;
>>          unsigned src_id = entry->src_id;
>>          struct amdgpu_irq_src *src;
>> +       bool handled = false;
>>          int r;
>>
>>          trace_amdgpu_iv(entry);
>>
>>          if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
>> -               DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
>> +               DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>>                  return;
>>          }
>>
>>          if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
>> -               DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
>> +               DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>>                  return;
>>          }
>>
>>          if (adev->irq.virq[src_id]) {
>>                  generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
>> -       } else {
>> -               if (!adev->irq.client[client_id].sources) {
>> -                       DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
>> -                                 client_id, src_id);
>> -                       return;
>> -               }
>> +               return;
>> +       }
>>
>> +       if (!adev->irq.client[client_id].sources) {
>> +               DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
>> +                         client_id, src_id);
>> +               return;
>> +       } else {
>>                  src = adev->irq.client[client_id].sources[src_id];
>>                  if (!src) {
>>                          DRM_DEBUG("Unhandled interrupt src_id: %d\n",
>> src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>>                  }
>>
>>                  r = src->funcs->process(adev, src, entry);
>> -               if (r)
>> +               if (r < 0)
>>                          DRM_ERROR("error processing interrupt (%d)\n",
>> r);
>> +               else if (r)
>> +                       handled = true;
>>          }
>> +
>> +       /* Send it to amdkfd as well if it isn't already handled */
>> +       if (!handled)
>> +               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>>   }
>>
>>   /**
>> --
>> 2.17.1
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]         ` <BN6PR12MB1651C628F04CBC8AD670590A80D30-/b2+HYfkarRSqX7PDniLCgdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2018-12-01 14:16           ` Christian König
  0 siblings, 0 replies; 32+ messages in thread
From: Christian König @ 2018-12-01 14:16 UTC (permalink / raw)
  To: Zeng, Oak, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Am 30.11.18 um 21:55 schrieb Zeng, Oak:
> See comment [Oak]
>
> Thanks,
> Oak
>
> -----Original Message-----
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Christian König
> Sent: Friday, November 30, 2018 7:36 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
>
> This allows us to filter out VM faults in the GMC code.
>
> v2: don't filter out all faults
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 +++++++++++++++----------
>   1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index 6b6524f04ce0..6db4c58ddc13 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev,
>   	if (!amdgpu_ih_prescreen_iv(adev))
>   		return;
>   
> -	/* Before dispatching irq to IP blocks, send it to amdkfd */
> -	amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
> -
>   	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>   	amdgpu_ih_decode_iv(adev, &entry);
>   
> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>   	unsigned client_id = entry->client_id;
>   	unsigned src_id = entry->src_id;
>   	struct amdgpu_irq_src *src;
> +	bool handled = false;
>   	int r;
>   
>   	trace_amdgpu_iv(entry);
>   
>   	if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
> -		DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
> +		DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>   		return;
>   	}
>   
>   	if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
> -		DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
> +		DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>   		return;
>   	}
>   
>   	if (adev->irq.virq[src_id]) {
>   		generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
> -	} else {
> -		if (!adev->irq.client[client_id].sources) {
> -			DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
> -				  client_id, src_id);
> -			return;
> -		}
> +		return;
> +	}
>   
> +	if (!adev->irq.client[client_id].sources) {
> +		DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
> +			  client_id, src_id);
> +		return;
> +	} else {
> [Oak]: you probably don't need a else because the return in above if.
Ah, crap! Thanks for pointing this out, it is a copy&paste error.
>   
>   		src = adev->irq.client[client_id].sources[src_id];
>   		if (!src) {
>   			DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
>   		}
>   
>   		r = src->funcs->process(adev, src, entry);
> -		if (r)
> +		if (r < 0)
>   			DRM_ERROR("error processing interrupt (%d)\n", r);
> +		else if (r)
> +			handled = true;
>   	}
> +
> +	/* Send it to amdkfd as well if it isn't already handled */
> +	if (!handled)
> [Oak]: Kfd cares about followed interrupt source/client. How can we guarantee that those are not handled by registered interrupt handler at amdgpu level?
> 		source_id == SOC15_INTSRC_CP_END_OF_PIPE ||
> 		source_id == SOC15_INTSRC_SDMA_TRAP ||
> 		source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG ||
> 		source_id == SOC15_INTSRC_CP_BAD_OPCODE ||
> 		client_id == SOC15_IH_CLIENTID_VMC ||
> 		client_id == SOC15_IH_CLIENTID_UTCL2;

Well the whole idea is that we filter out some of the IVs so that KFD 
does not see them any more.

>
> To completely avoid this, we should remove the amdgpu_amdkfd_interrupt function. Instead, kfd interrupt handling functions should be splitted and registered to adev->irq.client[].sources[]

Yeah, completely agree. But I wasn't sure which events the KFD actually 
needs, so the filtering I added for now was made to avoid problems for now.

In the long term we should indeed remove the dispatching from the kfd 
interrupt handling and move everything into the amdgpu per IP handlers.

Regards,
Christian.

>
> +		amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>   }
>   
>   /**
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]                 ` <b2792f9c-127a-b738-9e11-400525b00ed2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2018-12-03 16:31                   ` Kuehling, Felix
       [not found]                     ` <2c58d93f-7f41-9511-b3f8-2a5f89eff6c9-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 32+ messages in thread
From: Kuehling, Felix @ 2018-12-03 16:31 UTC (permalink / raw)
  To: Koenig, Christian, Alex Deucher; +Cc: amd-gfx list


On 2018-12-01 9:11 a.m., Christian König wrote:
>> Won't this break VM fault handling in KFD?
> No, we still send all VM faults to KFD after processing them. Only
> filtered retries are not send to the KFD any more.

OK, I missed that src->funcs->process returning 0 means "not handled",
>0 means "handled". Currently I don't see any interrupt processing
callbacks returning >0. I think that gets added in patch 4.


>
>> As far as I can tell, the only code path that leave IRQs unhandled
>> and passes them to KFD prints an error message in the kernel log. We
>> can't have the kernel log flooded with error messages every time
>> there are IRQs for KFD. We can get extremely high frequency
>> interrupts for HSA signals.
> Since the KFD didn't filtered the faults this would have a been a
> problem before as well.

I missed that r == 0 means not handled without being an error.


>
> So I'm pretty sure that we already have registered handlers for all
> interrupts the KFD is interested in as well.

No. As far as I can tell, you're missing these two:

GFX_9_0__SRCID__CP_BAD_OPCODE_ERROR (183)
GFX_9_0__SRCID__SQ_INTERRUPT_ID (239)

239 is used for signaling events from shaders and can be very frequent.
Triggering an error message on those interrupts would be bad.

Regards,
  Felix


>
> Regards,
> Christian.
>
> Am 30.11.18 um 17:31 schrieb Kuehling, Felix:
>> Won't this break VM fault handling in KFD? I don't see a way with the
>> current code that you can leave some VM faults for KFD to process. If
>> we could consider VM faults with VMIDs 8-15 as not handled in amdgpu
>> and leave them for KFD to process, then this could work.
>>
>> As far as I can tell, the only code path that leave IRQs unhandled
>> and passes them to KFD prints an error message in the kernel log. We
>> can't have the kernel log flooded with error messages every time
>> there are IRQs for KFD. We can get extremely high frequency
>> interrupts for HSA signals.
>>
>> Regards,
>>    Felix
>>
>> -----Original Message-----
>> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of
>> Alex Deucher
>> Sent: Friday, November 30, 2018 10:03 AM
>> To: Christian König <ckoenig.leichtzumerken@gmail.com>
>> Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>
>> Subject: Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after
>> processing them v2
>>
>> On Fri, Nov 30, 2018 at 7:36 AM Christian König
>> <ckoenig.leichtzumerken@gmail.com> wrote:
>>> This allows us to filter out VM faults in the GMC code.
>>>
>>> v2: don't filter out all faults
>>>
>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> Acked-by: Alex Deucher <alexander.deucher@amd.com>
>>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29
>>> +++++++++++++++----------
>>>   1 file changed, 17 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> index 6b6524f04ce0..6db4c58ddc13 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct
>>> amdgpu_device *adev,
>>>          if (!amdgpu_ih_prescreen_iv(adev))
>>>                  return;
>>>
>>> -       /* Before dispatching irq to IP blocks, send it to amdkfd */
>>> -       amdgpu_amdkfd_interrupt(adev, (const void *)
>>> &ih->ring[ring_index]);
>>> -
>>>          entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>>>          amdgpu_ih_decode_iv(adev, &entry);
>>>
>>> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device
>>> *adev,
>>>          unsigned client_id = entry->client_id;
>>>          unsigned src_id = entry->src_id;
>>>          struct amdgpu_irq_src *src;
>>> +       bool handled = false;
>>>          int r;
>>>
>>>          trace_amdgpu_iv(entry);
>>>
>>>          if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
>>> -               DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
>>> +               DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>>>                  return;
>>>          }
>>>
>>>          if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
>>> -               DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
>>> +               DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>>>                  return;
>>>          }
>>>
>>>          if (adev->irq.virq[src_id]) {
>>>                 
>>> generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
>>> -       } else {
>>> -               if (!adev->irq.client[client_id].sources) {
>>> -                       DRM_DEBUG("Unregistered interrupt client_id:
>>> %d src_id: %d\n",
>>> -                                 client_id, src_id);
>>> -                       return;
>>> -               }
>>> +               return;
>>> +       }
>>>
>>> +       if (!adev->irq.client[client_id].sources) {
>>> +               DRM_DEBUG("Unregistered interrupt client_id: %d
>>> src_id: %d\n",
>>> +                         client_id, src_id);
>>> +               return;
>>> +       } else {
>>>                  src = adev->irq.client[client_id].sources[src_id];
>>>                  if (!src) {
>>>                          DRM_DEBUG("Unhandled interrupt src_id: %d\n",
>>> src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct
>>> amdgpu_device *adev,
>>>                  }
>>>
>>>                  r = src->funcs->process(adev, src, entry);
>>> -               if (r)
>>> +               if (r < 0)
>>>                          DRM_ERROR("error processing interrupt (%d)\n",
>>> r);
>>> +               else if (r)
>>> +                       handled = true;
>>>          }
>>> +
>>> +       /* Send it to amdkfd as well if it isn't already handled */
>>> +       if (!handled)
>>> +               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>>>   }
>>>
>>>   /**
>>> -- 
>>> 2.17.1
>>>
>>> _______________________________________________
>>> amd-gfx mailing list
>>> amd-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]                     ` <2c58d93f-7f41-9511-b3f8-2a5f89eff6c9-5C7GfCeVMHo@public.gmane.org>
@ 2018-12-03 16:35                       ` Christian König
       [not found]                         ` <842543c4-f4ed-bff9-eaf5-2b8f8085ed81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 32+ messages in thread
From: Christian König @ 2018-12-03 16:35 UTC (permalink / raw)
  To: Kuehling, Felix, Koenig, Christian, Alex Deucher; +Cc: amd-gfx list

> No. As far as I can tell, you're missing these two:
>
> GFX_9_0__SRCID__CP_BAD_OPCODE_ERROR (183)
> GFX_9_0__SRCID__SQ_INTERRUPT_ID (239)
>
> 239 is used for signaling events from shaders and can be very frequent.
> Triggering an error message on those interrupts would be bad.

Mhm, then why didn't those trigger a message before?

As far as I can see we actually didn't changed the handling for that.

Christian.

Am 03.12.18 um 17:31 schrieb Kuehling, Felix:
> On 2018-12-01 9:11 a.m., Christian König wrote:
>>> Won't this break VM fault handling in KFD?
>> No, we still send all VM faults to KFD after processing them. Only
>> filtered retries are not send to the KFD any more.
> OK, I missed that src->funcs->process returning 0 means "not handled",
>> 0 means "handled". Currently I don't see any interrupt processing
> callbacks returning >0. I think that gets added in patch 4.
>
>
>>> As far as I can tell, the only code path that leave IRQs unhandled
>>> and passes them to KFD prints an error message in the kernel log. We
>>> can't have the kernel log flooded with error messages every time
>>> there are IRQs for KFD. We can get extremely high frequency
>>> interrupts for HSA signals.
>> Since the KFD didn't filtered the faults this would have a been a
>> problem before as well.
> I missed that r == 0 means not handled without being an error.
>
>
>> So I'm pretty sure that we already have registered handlers for all
>> interrupts the KFD is interested in as well.
> No. As far as I can tell, you're missing these two:
>
> GFX_9_0__SRCID__CP_BAD_OPCODE_ERROR (183)
> GFX_9_0__SRCID__SQ_INTERRUPT_ID (239)
>
> 239 is used for signaling events from shaders and can be very frequent.
> Triggering an error message on those interrupts would be bad.
>
> Regards,
>    Felix
>
>
>> Regards,
>> Christian.
>>
>> Am 30.11.18 um 17:31 schrieb Kuehling, Felix:
>>> Won't this break VM fault handling in KFD? I don't see a way with the
>>> current code that you can leave some VM faults for KFD to process. If
>>> we could consider VM faults with VMIDs 8-15 as not handled in amdgpu
>>> and leave them for KFD to process, then this could work.
>>>
>>> As far as I can tell, the only code path that leave IRQs unhandled
>>> and passes them to KFD prints an error message in the kernel log. We
>>> can't have the kernel log flooded with error messages every time
>>> there are IRQs for KFD. We can get extremely high frequency
>>> interrupts for HSA signals.
>>>
>>> Regards,
>>>     Felix
>>>
>>> -----Original Message-----
>>> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of
>>> Alex Deucher
>>> Sent: Friday, November 30, 2018 10:03 AM
>>> To: Christian König <ckoenig.leichtzumerken@gmail.com>
>>> Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>
>>> Subject: Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after
>>> processing them v2
>>>
>>> On Fri, Nov 30, 2018 at 7:36 AM Christian König
>>> <ckoenig.leichtzumerken@gmail.com> wrote:
>>>> This allows us to filter out VM faults in the GMC code.
>>>>
>>>> v2: don't filter out all faults
>>>>
>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>> Acked-by: Alex Deucher <alexander.deucher@amd.com>
>>>
>>>> ---
>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29
>>>> +++++++++++++++----------
>>>>    1 file changed, 17 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>> index 6b6524f04ce0..6db4c58ddc13 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct
>>>> amdgpu_device *adev,
>>>>           if (!amdgpu_ih_prescreen_iv(adev))
>>>>                   return;
>>>>
>>>> -       /* Before dispatching irq to IP blocks, send it to amdkfd */
>>>> -       amdgpu_amdkfd_interrupt(adev, (const void *)
>>>> &ih->ring[ring_index]);
>>>> -
>>>>           entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>>>>           amdgpu_ih_decode_iv(adev, &entry);
>>>>
>>>> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device
>>>> *adev,
>>>>           unsigned client_id = entry->client_id;
>>>>           unsigned src_id = entry->src_id;
>>>>           struct amdgpu_irq_src *src;
>>>> +       bool handled = false;
>>>>           int r;
>>>>
>>>>           trace_amdgpu_iv(entry);
>>>>
>>>>           if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
>>>> -               DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
>>>> +               DRM_ERROR("Invalid client_id in IV: %d\n", client_id);
>>>>                   return;
>>>>           }
>>>>
>>>>           if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
>>>> -               DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
>>>> +               DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>>>>                   return;
>>>>           }
>>>>
>>>>           if (adev->irq.virq[src_id]) {
>>>>                  
>>>> generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
>>>> -       } else {
>>>> -               if (!adev->irq.client[client_id].sources) {
>>>> -                       DRM_DEBUG("Unregistered interrupt client_id:
>>>> %d src_id: %d\n",
>>>> -                                 client_id, src_id);
>>>> -                       return;
>>>> -               }
>>>> +               return;
>>>> +       }
>>>>
>>>> +       if (!adev->irq.client[client_id].sources) {
>>>> +               DRM_DEBUG("Unregistered interrupt client_id: %d
>>>> src_id: %d\n",
>>>> +                         client_id, src_id);
>>>> +               return;
>>>> +       } else {
>>>>                   src = adev->irq.client[client_id].sources[src_id];
>>>>                   if (!src) {
>>>>                           DRM_DEBUG("Unhandled interrupt src_id: %d\n",
>>>> src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct
>>>> amdgpu_device *adev,
>>>>                   }
>>>>
>>>>                   r = src->funcs->process(adev, src, entry);
>>>> -               if (r)
>>>> +               if (r < 0)
>>>>                           DRM_ERROR("error processing interrupt (%d)\n",
>>>> r);
>>>> +               else if (r)
>>>> +                       handled = true;
>>>>           }
>>>> +
>>>> +       /* Send it to amdkfd as well if it isn't already handled */
>>>> +       if (!handled)
>>>> +               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>>>>    }
>>>>
>>>>    /**
>>>> -- 
>>>> 2.17.1
>>>>
>>>> _______________________________________________
>>>> amd-gfx mailing list
>>>> amd-gfx@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>>> _______________________________________________
>>> amd-gfx mailing list
>>> amd-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2
       [not found]                         ` <842543c4-f4ed-bff9-eaf5-2b8f8085ed81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2018-12-03 16:38                           ` Koenig, Christian
  0 siblings, 0 replies; 32+ messages in thread
From: Koenig, Christian @ 2018-12-03 16:38 UTC (permalink / raw)
  To: Kuehling, Felix, Alex Deucher; +Cc: amd-gfx list

Ah! Never mind, now I see it what you mean!

I accidentally added my debug change DRM_DEBUG->DRM_ERROR to this patch 
as well.

Sorry for the noise,
Christian.

Am 03.12.18 um 17:35 schrieb Christian König:
>> No. As far as I can tell, you're missing these two:
>>
>> GFX_9_0__SRCID__CP_BAD_OPCODE_ERROR (183)
>> GFX_9_0__SRCID__SQ_INTERRUPT_ID (239)
>>
>> 239 is used for signaling events from shaders and can be very frequent.
>> Triggering an error message on those interrupts would be bad.
>
> Mhm, then why didn't those trigger a message before?
>
> As far as I can see we actually didn't changed the handling for that.
>
> Christian.
>
> Am 03.12.18 um 17:31 schrieb Kuehling, Felix:
>> On 2018-12-01 9:11 a.m., Christian König wrote:
>>>> Won't this break VM fault handling in KFD?
>>> No, we still send all VM faults to KFD after processing them. Only
>>> filtered retries are not send to the KFD any more.
>> OK, I missed that src->funcs->process returning 0 means "not handled",
>>> 0 means "handled". Currently I don't see any interrupt processing
>> callbacks returning >0. I think that gets added in patch 4.
>>
>>
>>>> As far as I can tell, the only code path that leave IRQs unhandled
>>>> and passes them to KFD prints an error message in the kernel log. We
>>>> can't have the kernel log flooded with error messages every time
>>>> there are IRQs for KFD. We can get extremely high frequency
>>>> interrupts for HSA signals.
>>> Since the KFD didn't filtered the faults this would have a been a
>>> problem before as well.
>> I missed that r == 0 means not handled without being an error.
>>
>>
>>> So I'm pretty sure that we already have registered handlers for all
>>> interrupts the KFD is interested in as well.
>> No. As far as I can tell, you're missing these two:
>>
>> GFX_9_0__SRCID__CP_BAD_OPCODE_ERROR (183)
>> GFX_9_0__SRCID__SQ_INTERRUPT_ID (239)
>>
>> 239 is used for signaling events from shaders and can be very frequent.
>> Triggering an error message on those interrupts would be bad.
>>
>> Regards,
>>    Felix
>>
>>
>>> Regards,
>>> Christian.
>>>
>>> Am 30.11.18 um 17:31 schrieb Kuehling, Felix:
>>>> Won't this break VM fault handling in KFD? I don't see a way with the
>>>> current code that you can leave some VM faults for KFD to process. If
>>>> we could consider VM faults with VMIDs 8-15 as not handled in amdgpu
>>>> and leave them for KFD to process, then this could work.
>>>>
>>>> As far as I can tell, the only code path that leave IRQs unhandled
>>>> and passes them to KFD prints an error message in the kernel log. We
>>>> can't have the kernel log flooded with error messages every time
>>>> there are IRQs for KFD. We can get extremely high frequency
>>>> interrupts for HSA signals.
>>>>
>>>> Regards,
>>>>     Felix
>>>>
>>>> -----Original Message-----
>>>> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of
>>>> Alex Deucher
>>>> Sent: Friday, November 30, 2018 10:03 AM
>>>> To: Christian König <ckoenig.leichtzumerken@gmail.com>
>>>> Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>
>>>> Subject: Re: [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after
>>>> processing them v2
>>>>
>>>> On Fri, Nov 30, 2018 at 7:36 AM Christian König
>>>> <ckoenig.leichtzumerken@gmail.com> wrote:
>>>>> This allows us to filter out VM faults in the GMC code.
>>>>>
>>>>> v2: don't filter out all faults
>>>>>
>>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>>> Acked-by: Alex Deucher <alexander.deucher@amd.com>
>>>>
>>>>> ---
>>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29
>>>>> +++++++++++++++----------
>>>>>    1 file changed, 17 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>>> index 6b6524f04ce0..6db4c58ddc13 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>>>> @@ -149,9 +149,6 @@ static void amdgpu_irq_callback(struct
>>>>> amdgpu_device *adev,
>>>>>           if (!amdgpu_ih_prescreen_iv(adev))
>>>>>                   return;
>>>>>
>>>>> -       /* Before dispatching irq to IP blocks, send it to amdkfd */
>>>>> -       amdgpu_amdkfd_interrupt(adev, (const void *)
>>>>> &ih->ring[ring_index]);
>>>>> -
>>>>>           entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
>>>>>           amdgpu_ih_decode_iv(adev, &entry);
>>>>>
>>>>> @@ -371,29 +368,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device
>>>>> *adev,
>>>>>           unsigned client_id = entry->client_id;
>>>>>           unsigned src_id = entry->src_id;
>>>>>           struct amdgpu_irq_src *src;
>>>>> +       bool handled = false;
>>>>>           int r;
>>>>>
>>>>>           trace_amdgpu_iv(entry);
>>>>>
>>>>>           if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
>>>>> -               DRM_DEBUG("Invalid client_id in IV: %d\n", 
>>>>> client_id);
>>>>> +               DRM_ERROR("Invalid client_id in IV: %d\n", 
>>>>> client_id);
>>>>>                   return;
>>>>>           }
>>>>>
>>>>>           if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) {
>>>>> -               DRM_DEBUG("Invalid src_id in IV: %d\n", src_id);
>>>>> +               DRM_ERROR("Invalid src_id in IV: %d\n", src_id);
>>>>>                   return;
>>>>>           }
>>>>>
>>>>>           if (adev->irq.virq[src_id]) {
>>>>> generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
>>>>> -       } else {
>>>>> -               if (!adev->irq.client[client_id].sources) {
>>>>> -                       DRM_DEBUG("Unregistered interrupt client_id:
>>>>> %d src_id: %d\n",
>>>>> -                                 client_id, src_id);
>>>>> -                       return;
>>>>> -               }
>>>>> +               return;
>>>>> +       }
>>>>>
>>>>> +       if (!adev->irq.client[client_id].sources) {
>>>>> +               DRM_DEBUG("Unregistered interrupt client_id: %d
>>>>> src_id: %d\n",
>>>>> +                         client_id, src_id);
>>>>> +               return;
>>>>> +       } else {
>>>>>                   src = adev->irq.client[client_id].sources[src_id];
>>>>>                   if (!src) {
>>>>>                           DRM_DEBUG("Unhandled interrupt src_id: 
>>>>> %d\n",
>>>>> src_id); @@ -401,9 +400,15 @@ void amdgpu_irq_dispatch(struct
>>>>> amdgpu_device *adev,
>>>>>                   }
>>>>>
>>>>>                   r = src->funcs->process(adev, src, entry);
>>>>> -               if (r)
>>>>> +               if (r < 0)
>>>>>                           DRM_ERROR("error processing interrupt 
>>>>> (%d)\n",
>>>>> r);
>>>>> +               else if (r)
>>>>> +                       handled = true;
>>>>>           }
>>>>> +
>>>>> +       /* Send it to amdkfd as well if it isn't already handled */
>>>>> +       if (!handled)
>>>>> +               amdgpu_amdkfd_interrupt(adev, entry->iv_entry);
>>>>>    }
>>>>>
>>>>>    /**
>>>>> -- 
>>>>> 2.17.1
>>>>>
>>>>> _______________________________________________
>>>>> amd-gfx mailing list
>>>>> amd-gfx@lists.freedesktop.org
>>>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>>>> _______________________________________________
>>>> amd-gfx mailing list
>>>> amd-gfx@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>

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

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2018-12-03 16:38 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-30 12:35 [PATCH 01/11] drm/amdgpu: add missing error handling Christian König
     [not found] ` <20181130123558.14898-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 12:35   ` [PATCH 02/11] drm/amdgpu: send IVs to the KFD only after processing them v2 Christian König
     [not found]     ` <20181130123558.14898-2-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:02       ` Alex Deucher
     [not found]         ` <CADnq5_OipWaH0=BMMmzJMu-gUKZt-L=nG4Dkt2GWQgMnCKxG1w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-11-30 16:31           ` Kuehling, Felix
     [not found]             ` <DM5PR12MB17078A9132DCA1AD4920300192D30-2J9CzHegvk9TCtO+SvGBKwdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2018-12-01 14:11               ` Christian König
     [not found]                 ` <b2792f9c-127a-b738-9e11-400525b00ed2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2018-12-03 16:31                   ` Kuehling, Felix
     [not found]                     ` <2c58d93f-7f41-9511-b3f8-2a5f89eff6c9-5C7GfCeVMHo@public.gmane.org>
2018-12-03 16:35                       ` Christian König
     [not found]                         ` <842543c4-f4ed-bff9-eaf5-2b8f8085ed81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2018-12-03 16:38                           ` Koenig, Christian
2018-11-30 20:55       ` Zeng, Oak
     [not found]         ` <BN6PR12MB1651C628F04CBC8AD670590A80D30-/b2+HYfkarRSqX7PDniLCgdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2018-12-01 14:16           ` Christian König
2018-11-30 12:35   ` [PATCH 03/11] drm/amdgpu: remove VM fault_credit handling Christian König
     [not found]     ` <20181130123558.14898-3-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:04       ` Alex Deucher
2018-11-30 21:07       ` Zeng, Oak
     [not found]         ` <BN6PR12MB1651C10E3977C786DE29BB1980D30-/b2+HYfkarRSqX7PDniLCgdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2018-12-01 13:59           ` Christian König
2018-11-30 12:35   ` [PATCH 04/11] drm/amdgpu: move IV prescreening into the GMC code Christian König
     [not found]     ` <20181130123558.14898-4-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:05       ` Alex Deucher
2018-11-30 12:35   ` [PATCH 05/11] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2 Christian König
     [not found]     ` <20181130123558.14898-5-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:09       ` Alex Deucher
2018-11-30 12:35   ` [PATCH 06/11] drm/amdgpu: simplify IH programming Christian König
     [not found]     ` <20181130123558.14898-6-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 15:45       ` Alex Deucher
2018-11-30 12:35   ` [PATCH 07/11] drm/amdgpu: enable IH ring 1 and ring 2 v2 Christian König
     [not found]     ` <20181130123558.14898-7-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:01       ` Alex Deucher
     [not found]         ` <CADnq5_MwEqFZsPcgtkpL9vQKLEjqUev51QKtak9nEweNZ5Q7_Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-11-30 16:04           ` Christian König
2018-11-30 12:35   ` [PATCH 08/11] drm/amdgpu: add the IH to the IV trace Christian König
     [not found]     ` <20181130123558.14898-8-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:01       ` Alex Deucher
2018-11-30 12:35   ` [PATCH 09/11] drm/amdgpu: add support for processing IH ring 1 & 2 Christian König
     [not found]     ` <20181130123558.14898-9-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:10       ` Alex Deucher
2018-11-30 12:35   ` [PATCH 10/11] drm/amdgpu: add support for self irq on Vega10 Christian König
     [not found]     ` <20181130123558.14898-10-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:11       ` Alex Deucher
2018-11-30 12:35   ` [PATCH 11/11] drm/amdgpu: disable IH ring 1 & 2 WPTR overflow " Christian König
     [not found]     ` <20181130123558.14898-11-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-11-30 16:11       ` Alex Deucher
2018-11-30 15:41   ` [PATCH 01/11] drm/amdgpu: add missing error handling Alex Deucher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.