All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/12] drm/amdgpu: add missing error handling
@ 2018-09-26 13:53 Christian König
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 f35d7a554ad5..2420ae90047e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -959,6 +959,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.14.1

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

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

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

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

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 +++++++++++++++++------------
 drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   |  2 +-
 5 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 52c17f6219a7..8f0bc3f2e163 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -166,9 +166,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);
 
@@ -392,29 +389,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);
@@ -422,9 +421,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);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index e1c2b4e9c7b2..d65bfbe21f56 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -1132,7 +1132,7 @@ static int gmc_v6_0_process_interrupt(struct amdgpu_device *adev,
 		gmc_v6_0_vm_decode_fault(adev, status, addr, 0);
 	}
 
-	return 0;
+	return 1;
 }
 
 static int gmc_v6_0_set_clockgating_state(void *handle,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 910c4ce19cb3..ca8b34bab261 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -1325,7 +1325,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,
 		atomic_set(&adev->gmc.vm_fault_info_updated, 1);
 	}
 
-	return 0;
+	return 1;
 }
 
 static int gmc_v7_0_set_clockgating_state(void *handle,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 1d3265c97b70..f7547a7776a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -1487,7 +1487,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
 		atomic_set(&adev->gmc.vm_fault_info_updated, 1);
 	}
 
-	return 0;
+	return 1;
 }
 
 static void fiji_update_mc_medium_grain_clock_gating(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 2420ae90047e..729a2c230f91 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -279,7 +279,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
 				status);
 	}
 
-	return 0;
+	return 1;
 }
 
 static const struct amdgpu_irq_src_funcs gmc_v9_0_irq_funcs = {
-- 
2.14.1

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

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

* [PATCH 03/12] drm/amdgpu: remove VM fault_credit handling
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-09-26 13:53   ` [PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-26 13:53   ` [PATCH 04/12] drm/amdgpu: move IV prescreening into the GMC code Christian König
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 6904d794d60a..570150ceeb16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3052,7 +3052,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	}
 
 	INIT_KFIFO(vm->faults);
-	vm->fault_credit = 16;
 
 	return 0;
 
@@ -3262,42 +3261,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 3abffd06b5c7..9be687d31684 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 a99f71797aa3..0f50bef87163 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.14.1

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

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

* [PATCH 04/12] drm/amdgpu: move IV prescreening into the GMC code
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-09-26 13:53   ` [PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them Christian König
  2018-09-26 13:53   ` [PATCH 03/12] drm/amdgpu: remove VM fault_credit handling Christian König
@ 2018-09-26 13:53   ` Christian König
       [not found]     ` <20180926135330.2218-4-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-09-26 13:53   ` [PATCH 05/12] drm/amdgpu: remove IV prescreening Christian König
                     ` (8 subsequent siblings)
  11 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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/gmc_v9_0.c  | 59 +++++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 69 ----------------------------------
 2 files changed, 59 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 729a2c230f91..f8d69ab85fc3 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;
+
 	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/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index 0f50bef87163..0f68a0cd1fbf 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -228,76 +228,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
  */
 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;
 }
 
 /**
-- 
2.14.1

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

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

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

Not used any more.

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/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  | 13 -------------
 8 files changed, 85 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 8f0bc3f2e163..613ee1b76b25 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -162,10 +162,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/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 9be687d31684..f64a0be3755c 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 0f68a0cd1fbf..49b9ecea09b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -219,18 +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)
-{
-	return true;
-}
-
 /**
  * vega10_ih_decode_iv - decode an interrupt vector
  *
@@ -415,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.14.1

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

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

* [PATCH 06/12] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (3 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 05/12] drm/amdgpu: remove IV prescreening Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-26 13:53   ` [PATCH 07/12] drm/amdgpu: simplify IH programming Christian König
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 f64a0be3755c..f035ac2a51c7 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 49b9ecea09b0..7f293d76aa6a 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.14.1

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

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

* [PATCH 07/12] drm/amdgpu: simplify IH programming
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (4 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 06/12] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2 Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-26 13:53   ` [PATCH 08/12] drm/amdgpu: enable IH ring 1 and ring 2 v2 Christian König
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 f035ac2a51c7..94242625450d 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 7f293d76aa6a..444f64e5092b 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) & 0xFF);
+	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) & 0xFF);
 
 	/* 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.14.1

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

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

* [PATCH 08/12] drm/amdgpu: enable IH ring 1 and ring 2 v2
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (5 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 07/12] drm/amdgpu: simplify IH programming Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-26 13:53   ` [PATCH 09/12] drm/amdgpu: add the IH to the IV trace Christian König
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 444f64e5092b..e6af9b4c3116 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 = AMDGPU_DOORBELL64_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.14.1

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

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

* [PATCH 09/12] drm/amdgpu: add the IH to the IV trace
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (6 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 08/12] drm/amdgpu: enable IH ring 1 and ring 2 v2 Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-26 13:53   ` [PATCH 10/12] drm/amdgpu: add support for processing IH ring 1 & 2 Christian König
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 613ee1b76b25..9d40ff27f0b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -165,6 +165,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);
 }
 
@@ -388,8 +390,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 e9bf70e2ac51..2d8f420104e5 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.14.1

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

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

* [PATCH 10/12] drm/amdgpu: add support for processing IH ring 1 & 2
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (7 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 09/12] drm/amdgpu: add the IH to the IV trace Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-26 13:53   ` [PATCH 11/12] drm/amdgpu: add support for self irq on Vega10 Christian König
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 | 32 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |  4 +++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 9d40ff27f0b5..2334e85b92f5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -193,6 +193,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
  *
@@ -258,6 +288,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 	}
 
 	INIT_WORK(&adev->reset_work, amdgpu_irq_reset_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);
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.14.1

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

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

* [PATCH 11/12] drm/amdgpu: add support for self irq on Vega10
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (8 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 10/12] drm/amdgpu: add support for processing IH ring 1 & 2 Christian König
@ 2018-09-26 13:53   ` Christian König
       [not found]     ` <20180926135330.2218-11-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-09-26 13:53   ` [PATCH 12/12] drm/amdgpu: disable IH ring 2 WPTR overflow " Christian König
  2018-09-27 10:00   ` [PATCH 01/12] drm/amdgpu: add missing error handling Huang Rui
  11 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 e6af9b4c3116..dd155a207fdd 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.14.1

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

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

* [PATCH 12/12] drm/amdgpu: disable IH ring 2 WPTR overflow on Vega10
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (9 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 11/12] drm/amdgpu: add support for self irq on Vega10 Christian König
@ 2018-09-26 13:53   ` Christian König
  2018-09-27 10:00   ` [PATCH 01/12] drm/amdgpu: add missing error handling Huang Rui
  11 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-26 13:53 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 | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index dd155a207fdd..c8525c29fc16 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -207,6 +207,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.14.1

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

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

* Re: [PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them
       [not found]     ` <20180926135330.2218-2-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-09-26 18:24       ` Jay Cornwall
       [not found]         ` <1537986270.3887323.1521702048.0DEA7A63-2RFepEojUI2N1INw9kWLP6GC3tUn3ZHUQQ4Iyu8u01E@public.gmane.org>
  0 siblings, 1 reply; 22+ messages in thread
From: Jay Cornwall @ 2018-09-26 18:24 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Sep 26, 2018, at 08:53, Christian König wrote:
> This allows us to filter out VM faults in the GMC code.
> 
> Signed-off-by: Christian König <christian.koenig@amd.com>

The KFD needs to receive notification of unhandled VM faults; when demand paging is disabled or the address is not pageable. It propagates this to the UMD (ROC runtime or the ROC debugger).

Does this patch change that behavior?
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

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

On Wed, Sep 26, 2018 at 9:54 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>
> ---
>  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 e6af9b4c3116..dd155a207fdd 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();

Copy paste typo?

Alex

> +
> +               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.14.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] 22+ messages in thread

* Re: [PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them
       [not found]         ` <1537986270.3887323.1521702048.0DEA7A63-2RFepEojUI2N1INw9kWLP6GC3tUn3ZHUQQ4Iyu8u01E@public.gmane.org>
@ 2018-09-27  9:32           ` Christian König
  0 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-09-27  9:32 UTC (permalink / raw)
  To: Jay Cornwall, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Am 26.09.2018 um 20:24 schrieb Jay Cornwall:
> On Wed, Sep 26, 2018, at 08:53, Christian König wrote:
>> This allows us to filter out VM faults in the GMC code.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
> The KFD needs to receive notification of unhandled VM faults; when demand paging is disabled or the address is not pageable. It propagates this to the UMD (ROC runtime or the ROC debugger).
>
> Does this patch change that behavior?

Potentially yes. We have some code in the GMC handling for this, but I'm 
actually not sure if that is the used path.

Thanks for the comment, I will take that into account and only block 
forwarding to the KFD if the GMC really filtered the request.

Christian.

> _______________________________________________
> 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] 22+ messages in thread

* Re: [PATCH 01/12] drm/amdgpu: add missing error handling
       [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (10 preceding siblings ...)
  2018-09-26 13:53   ` [PATCH 12/12] drm/amdgpu: disable IH ring 2 WPTR overflow " Christian König
@ 2018-09-27 10:00   ` Huang Rui
  2018-09-27 11:25     ` Christian König
  11 siblings, 1 reply; 22+ messages in thread
From: Huang Rui @ 2018-09-27 10:00 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Sep 26, 2018 at 03:53:19PM +0200, Christian König wrote:
> 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 f35d7a554ad5..2420ae90047e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -959,6 +959,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);
>  

We should tear down the client source that allocated by the
SOC15_IH_CLIENTID_VMC (the last one) if it (the second one) gets failed.

Thanks,
Ray

> -- 
> 2.14.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] 22+ messages in thread

* Re: [PATCH 05/12] drm/amdgpu: remove IV prescreening
       [not found]     ` <20180926135330.2218-5-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-09-27 10:28       ` Huang Rui
  0 siblings, 0 replies; 22+ messages in thread
From: Huang Rui @ 2018-09-27 10:28 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Wed, Sep 26, 2018 at 03:53:23PM +0200, Christian König wrote:
> Not used any more.
> 
> Signed-off-by: Christian König <christian.koenig@amd.com>

This patch should be merged to patch 3, that totally remove prescreen_iv
interface.

Thanks,
Ray

> ---
>  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/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  | 13 -------------
>  8 files changed, 85 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 8f0bc3f2e163..613ee1b76b25 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -162,10 +162,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/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 9be687d31684..f64a0be3755c 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 0f68a0cd1fbf..49b9ecea09b0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -219,18 +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)
> -{
> -	return true;
> -}
> -
>  /**
>   * vega10_ih_decode_iv - decode an interrupt vector
>   *
> @@ -415,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.14.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] 22+ messages in thread

* Re: [PATCH 01/12] drm/amdgpu: add missing error handling
  2018-09-27 10:00   ` [PATCH 01/12] drm/amdgpu: add missing error handling Huang Rui
@ 2018-09-27 11:25     ` Christian König
       [not found]       ` <e3ab66c9-41b1-c0cd-8f72-07f4eebff70b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2018-09-27 11:25 UTC (permalink / raw)
  To: Huang Rui; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Am 27.09.2018 um 12:00 schrieb Huang Rui:
> On Wed, Sep 26, 2018 at 03:53:19PM +0200, Christian König wrote:
>> 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 f35d7a554ad5..2420ae90047e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> @@ -959,6 +959,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);
>>   
> We should tear down the client source that allocated by the
> SOC15_IH_CLIENTID_VMC (the last one) if it (the second one) gets failed.

There is no such thing as a teardown. amdgpu_irq_add_id() registers the 
irq callback for the clientid/srcid combination, but there isn't an 
unregister function.

Christian.

>
> Thanks,
> Ray
>
>> -- 
>> 2.14.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] 22+ messages in thread

* RE: [PATCH 01/12] drm/amdgpu: add missing error handling
       [not found]       ` <e3ab66c9-41b1-c0cd-8f72-07f4eebff70b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2018-09-28  7:36         ` Huang, Ray
       [not found]           ` <BY2PR12MB0040E69C83DAC1B5136F95E4ECEC0-K//h7OWB4q7Zvl48JdS6+wdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  0 siblings, 1 reply; 22+ messages in thread
From: Huang, Ray @ 2018-09-28  7:36 UTC (permalink / raw)
  To: Koenig, Christian; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: Christian König [mailto:ckoenig.leichtzumerken@gmail.com]
> Sent: Thursday, September 27, 2018 7:26 PM
> To: Huang, Ray <Ray.Huang@amd.com>
> Cc: amd-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 01/12] drm/amdgpu: add missing error handling
> 
> Am 27.09.2018 um 12:00 schrieb Huang Rui:
> > On Wed, Sep 26, 2018 at 03:53:19PM +0200, Christian König wrote:
> >> 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 f35d7a554ad5..2420ae90047e 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> >> @@ -959,6 +959,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);
> >>
> > We should tear down the client source that allocated by the
> > SOC15_IH_CLIENTID_VMC (the last one) if it (the second one) gets failed.
> 
> There is no such thing as a teardown. amdgpu_irq_add_id() registers the irq
> callback for the clientid/srcid combination, but there isn't an unregister
> function.

Actually, I see we will allocate the sources that register at the specific client.

adev->irq.client[client_id].sources = kcalloc(AMDGPU_MAX_IRQ_SRC_ID, sizeof(struct amdgpu_irq_src *), GFP_KERNEL);

While CLIENTID_UTCL2 add_id get failed, need we free the sources that allocated by CLIENTID_VMC? Otherwise, it looks a minor memory leak here for me.

Thanks,
Ray

> 
> Christian.
> 
> >
> > Thanks,
> > Ray
> >
> >> --
> >> 2.14.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] 22+ messages in thread

* Re: [PATCH 01/12] drm/amdgpu: add missing error handling
       [not found]           ` <BY2PR12MB0040E69C83DAC1B5136F95E4ECEC0-K//h7OWB4q7Zvl48JdS6+wdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2018-10-03 14:25             ` Christian König
  0 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-10-03 14:25 UTC (permalink / raw)
  To: Huang, Ray, Koenig, Christian; +Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Am 28.09.2018 um 09:36 schrieb Huang, Ray:
>> -----Original Message-----
>> From: Christian König [mailto:ckoenig.leichtzumerken@gmail.com]
>> Sent: Thursday, September 27, 2018 7:26 PM
>> To: Huang, Ray <Ray.Huang@amd.com>
>> Cc: amd-gfx@lists.freedesktop.org
>> Subject: Re: [PATCH 01/12] drm/amdgpu: add missing error handling
>>
>> Am 27.09.2018 um 12:00 schrieb Huang Rui:
>>> On Wed, Sep 26, 2018 at 03:53:19PM +0200, Christian König wrote:
>>>> 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 f35d7a554ad5..2420ae90047e 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>>>> @@ -959,6 +959,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);
>>>>
>>> We should tear down the client source that allocated by the
>>> SOC15_IH_CLIENTID_VMC (the last one) if it (the second one) gets failed.
>> There is no such thing as a teardown. amdgpu_irq_add_id() registers the irq
>> callback for the clientid/srcid combination, but there isn't an unregister
>> function.
> Actually, I see we will allocate the sources that register at the specific client.
>
> adev->irq.client[client_id].sources = kcalloc(AMDGPU_MAX_IRQ_SRC_ID, sizeof(struct amdgpu_irq_src *), GFP_KERNEL);
>
> While CLIENTID_UTCL2 add_id get failed, need we free the sources that allocated by CLIENTID_VMC? Otherwise, it looks a minor memory leak here for me.

No, freeing of that is done in amdgpu_irq_fini().

Christian.

>
> Thanks,
> Ray
>
>> Christian.
>>
>>> Thanks,
>>> Ray
>>>
>>>> --
>>>> 2.14.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] 22+ messages in thread

* Re: [PATCH 04/12] drm/amdgpu: move IV prescreening into the GMC code
       [not found]     ` <20180926135330.2218-4-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-10-09 23:46       ` Felix Kuehling
       [not found]         ` <dcf7fd50-e453-8a9d-cdaa-c452d4716e9a-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 22+ messages in thread
From: Felix Kuehling @ 2018-10-09 23:46 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

I realized that most of the code in gmc_v9_0_psescreen_iv is not
actually hardware-specific. If it was not prescreening, but using an
amdgpu_iv_entry that was already parsed, I think it could just be a
generic function for processing retry faults:

  * looking up the VM of a fault
  * storing retry faults in a per-VM fifo
  * dropping faults that have already been seen

In other words, it's just a generic top half interrupt handler for retry
faults while the bottom half (worker thread) would use the per-VM FIFOs
to handle those pending retry faults.

Regards,
  Felix


On 2018-09-26 09:53 AM, Christian König 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>
> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  | 59 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 69 ----------------------------------
>  2 files changed, 59 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index 729a2c230f91..f8d69ab85fc3 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;
> +
>  	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/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> index 0f50bef87163..0f68a0cd1fbf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
> @@ -228,76 +228,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
>   */
>  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;
>  }
>  
>  /**

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

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

* Re: [PATCH 04/12] drm/amdgpu: move IV prescreening into the GMC code
       [not found]         ` <dcf7fd50-e453-8a9d-cdaa-c452d4716e9a-5C7GfCeVMHo@public.gmane.org>
@ 2018-10-10  7:08           ` Christian König
  0 siblings, 0 replies; 22+ messages in thread
From: Christian König @ 2018-10-10  7:08 UTC (permalink / raw)
  To: Felix Kuehling, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Yeah, exactly my thinking.

Basically the long term goal is to move most of the reporting and 
handling of faults into amdgpu_gmc.c. Otherwise we would duplicate a lot 
of handling for future hw generations.

On the other hand if the approach with the second IH ring buffer works 
as expected we most likely won't need the pre-screening anymore at all. 
But that needs more work to be 100% sure.

Christian.

Am 10.10.2018 um 01:46 schrieb Felix Kuehling:
> I realized that most of the code in gmc_v9_0_psescreen_iv is not
> actually hardware-specific. If it was not prescreening, but using an
> amdgpu_iv_entry that was already parsed, I think it could just be a
> generic function for processing retry faults:
>
>    * looking up the VM of a fault
>    * storing retry faults in a per-VM fifo
>    * dropping faults that have already been seen
>
> In other words, it's just a generic top half interrupt handler for retry
> faults while the bottom half (worker thread) would use the per-VM FIFOs
> to handle those pending retry faults.
>
> Regards,
>    Felix
>
>
> On 2018-09-26 09:53 AM, Christian König 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>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  | 59 +++++++++++++++++++++++++++++
>>   drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 69 ----------------------------------
>>   2 files changed, 59 insertions(+), 69 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> index 729a2c230f91..f8d69ab85fc3 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;
>> +
>>   	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/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
>> index 0f50bef87163..0f68a0cd1fbf 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
>> @@ -228,76 +228,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
>>    */
>>   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;
>>   }
>>   
>>   /**

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

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

end of thread, other threads:[~2018-10-10  7:08 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-26 13:53 [PATCH 01/12] drm/amdgpu: add missing error handling Christian König
     [not found] ` <20180926135330.2218-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-09-26 13:53   ` [PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them Christian König
     [not found]     ` <20180926135330.2218-2-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-09-26 18:24       ` Jay Cornwall
     [not found]         ` <1537986270.3887323.1521702048.0DEA7A63-2RFepEojUI2N1INw9kWLP6GC3tUn3ZHUQQ4Iyu8u01E@public.gmane.org>
2018-09-27  9:32           ` Christian König
2018-09-26 13:53   ` [PATCH 03/12] drm/amdgpu: remove VM fault_credit handling Christian König
2018-09-26 13:53   ` [PATCH 04/12] drm/amdgpu: move IV prescreening into the GMC code Christian König
     [not found]     ` <20180926135330.2218-4-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-10-09 23:46       ` Felix Kuehling
     [not found]         ` <dcf7fd50-e453-8a9d-cdaa-c452d4716e9a-5C7GfCeVMHo@public.gmane.org>
2018-10-10  7:08           ` Christian König
2018-09-26 13:53   ` [PATCH 05/12] drm/amdgpu: remove IV prescreening Christian König
     [not found]     ` <20180926135330.2218-5-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-09-27 10:28       ` Huang Rui
2018-09-26 13:53   ` [PATCH 06/12] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2 Christian König
2018-09-26 13:53   ` [PATCH 07/12] drm/amdgpu: simplify IH programming Christian König
2018-09-26 13:53   ` [PATCH 08/12] drm/amdgpu: enable IH ring 1 and ring 2 v2 Christian König
2018-09-26 13:53   ` [PATCH 09/12] drm/amdgpu: add the IH to the IV trace Christian König
2018-09-26 13:53   ` [PATCH 10/12] drm/amdgpu: add support for processing IH ring 1 & 2 Christian König
2018-09-26 13:53   ` [PATCH 11/12] drm/amdgpu: add support for self irq on Vega10 Christian König
     [not found]     ` <20180926135330.2218-11-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-09-26 19:19       ` Alex Deucher
2018-09-26 13:53   ` [PATCH 12/12] drm/amdgpu: disable IH ring 2 WPTR overflow " Christian König
2018-09-27 10:00   ` [PATCH 01/12] drm/amdgpu: add missing error handling Huang Rui
2018-09-27 11:25     ` Christian König
     [not found]       ` <e3ab66c9-41b1-c0cd-8f72-07f4eebff70b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2018-09-28  7:36         ` Huang, Ray
     [not found]           ` <BY2PR12MB0040E69C83DAC1B5136F95E4ECEC0-K//h7OWB4q7Zvl48JdS6+wdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2018-10-03 14:25             ` Christian König

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.