[PATCH 1/2] drm/amdgpu: Enable IH retry CAM on GFX9
Felix Kuehling
felix.kuehling at amd.com
Mon Dec 12 22:44:17 UTC 2022
On 2022-12-12 12:10, Mukul Joshi wrote:
> This patch enables the IH retry CAM on GFX9 series cards. This
> retry filter is used to prevent sending lots of retry interrupts
> in a short span of time and overflowing the IH ring buffer. This
> will also help reduce CPU interrupt workload.
>
> Signed-off-by: Mukul Joshi <mukul.joshi at amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 2 +
> drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 51 ++++++++++++-------
> drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 2 +-
> drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 46 ++++++-----------
> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 4 +-
> .../asic_reg/oss/osssys_4_2_0_offset.h | 6 +++
> .../asic_reg/oss/osssys_4_2_0_sh_mask.h | 13 +++++
> 7 files changed, 75 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> index e9f2c11ea416..be243adf3e65 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
> @@ -98,6 +98,8 @@ struct amdgpu_irq {
> struct irq_domain *domain; /* GPU irq controller domain */
> unsigned virq[AMDGPU_MAX_IRQ_SRC_ID];
> uint32_t srbm_soft_reset;
> + u32 retry_cam_doorbell_index;
> + bool retry_cam_enabled;
> };
>
> void amdgpu_irq_disable_all(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 08d6cf79fb15..e5ab84f3e072 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -537,32 +537,49 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
> const char *mmhub_cid;
> const char *hub_name;
> u64 addr;
> + uint32_t cam_index = 0;
> + int ret;
>
> addr = (u64)entry->src_data[0] << 12;
> addr |= ((u64)entry->src_data[1] & 0xf) << 44;
>
> if (retry_fault) {
> - /* Returning 1 here also prevents sending the IV to the KFD */
> + if (adev->irq.retry_cam_enabled) {
> + /* Delegate it to a different ring if the hardware hasn't
> + * already done it.
> + */
> + if (entry->ih == &adev->irq.ih) {
> + amdgpu_irq_delegate(adev, entry, 8);
> + return 1;
> + }
> +
> + cam_index = entry->src_data[2] & 0x3ff;
>
> - /* Process it onyl if it's the first fault for this address */
> - if (entry->ih != &adev->irq.ih_soft &&
> - amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid,
> + ret = amdgpu_vm_handle_fault(adev, entry->pasid, addr, write_fault);
> + WDOORBELL32(adev->irq.retry_cam_doorbell_index, cam_index);
> + if (ret)
> + return 1;
> + } else {
> + /* Process it onyl if it's the first fault for this address */
> + if (entry->ih != &adev->irq.ih_soft &&
> + amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid,
> entry->timestamp))
> - return 1;
> + return 1;
>
> - /* Delegate it to a different ring if the hardware hasn't
> - * already done it.
> - */
> - if (entry->ih == &adev->irq.ih) {
> - amdgpu_irq_delegate(adev, entry, 8);
> - return 1;
> - }
> + /* Delegate it to a different ring if the hardware hasn't
> + * already done it.
> + */
> + if (entry->ih == &adev->irq.ih) {
> + amdgpu_irq_delegate(adev, entry, 8);
> + return 1;
> + }
>
> - /* Try to handle the recoverable page faults by filling page
> - * tables
> - */
> - if (amdgpu_vm_handle_fault(adev, entry->pasid, addr, write_fault))
> - return 1;
> + /* Try to handle the recoverable page faults by filling page
> + * tables
> + */
> + if (amdgpu_vm_handle_fault(adev, entry->pasid, addr, write_fault))
> + return 1;
> + }
> }
>
> if (!printk_ratelimit())
> diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> index 19455a725939..685abf57ffdd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
> @@ -238,7 +238,7 @@ static void nbio_v7_4_ih_doorbell_range(struct amdgpu_device *adev,
>
> if (use_doorbell) {
> ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
> - ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 4);
> + ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 8);
> } else
> ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 0);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
> index 1706081d054d..ed41f96b251f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
> @@ -251,36 +251,14 @@ static int vega20_ih_enable_ring(struct amdgpu_device *adev,
> return 0;
> }
>
> -/**
> - * vega20_ih_reroute_ih - reroute VMC/UTCL2 ih to an ih ring
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Reroute VMC and UMC interrupts on primary ih ring to
> - * ih ring 1 so they won't lose when bunches of page faults
> - * interrupts overwhelms the interrupt handler(VEGA20)
> - */
> -static void vega20_ih_reroute_ih(struct amdgpu_device *adev)
> +static uint32_t vega20_setup_retry_doorbell(u32 doorbell_index)
> {
> - uint32_t tmp;
> + u32 val = 0;
>
> - /* vega20 ih reroute will go through psp this
> - * function is used for newer asics starting arcturus
> - */
> - if (adev->ip_versions[OSSSYS_HWIP][0] >= IP_VERSION(4, 2, 1)) {
> - /* Reroute to IH ring 1 for VMC */
> - WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
> - tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
> - tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
> - tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
> - WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
> -
> - /* Reroute IH ring 1 for UTCL2 */
> - WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x1B);
> - tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
> - tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
> - WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
> - }
> + val = REG_SET_FIELD(val, IH_DOORBELL_RPTR, OFFSET, doorbell_index);
> + val = REG_SET_FIELD(val, IH_DOORBELL_RPTR, ENABLE, 1);
> +
> + return val;
> }
>
> /**
> @@ -332,8 +310,6 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
>
> for (i = 0; i < ARRAY_SIZE(ih); i++) {
> if (ih[i]->ring_size) {
> - if (i == 1)
> - vega20_ih_reroute_ih(adev);
> ret = vega20_ih_enable_ring(adev, ih[i]);
> if (ret)
> return ret;
> @@ -346,6 +322,16 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
>
> pci_set_master(adev->pdev);
>
> + /* Enable IH Retry CAM */
> + WREG32_FIELD15(OSSSYS, 0, IH_RETRY_INT_CAM_CNTL, ENABLE, 1);
> +
> + /* Allocate the doorbell for IH Retry CAM */
> + adev->irq.retry_cam_doorbell_index = (adev->doorbell_index.ih + 3) << 1;
> + WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RETRY_CAM,
> + vega20_setup_retry_doorbell(adev->irq.retry_cam_doorbell_index));
> +
> + adev->irq.retry_cam_enabled = true;
> +
> /* enable interrupts */
> ret = vega20_ih_toggle_interrupts(adev, true);
> if (ret)
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> index 2dc3b04064bd..747adad7e0d8 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> @@ -2162,7 +2162,9 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms)
> pr_debug("drain retry fault gpu %d svms %p\n", i, svms);
>
> amdgpu_ih_wait_on_checkpoint_process_ts(pdd->dev->adev,
> - &pdd->dev->adev->irq.ih1);
> + pdd->dev->adev->irq.retry_cam_enabled ?
> + &pdd->dev->adev->irq.ih_soft :
> + &pdd->dev->adev->irq.ih1);
> pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms);
> }
> if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain)
> diff --git a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h
> index bd129266ebfd..a84a7cfaf71e 100644
> --- a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h
> +++ b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_offset.h
> @@ -135,6 +135,8 @@
> #define mmIH_RB_WPTR_ADDR_LO_BASE_IDX 0
> #define mmIH_DOORBELL_RPTR 0x0087
> #define mmIH_DOORBELL_RPTR_BASE_IDX 0
> +#define mmIH_DOORBELL_RETRY_CAM 0x0088
> +#define mmIH_DOORBELL_RETRY_CAM_BASE_IDX 0
> #define mmIH_RB_CNTL_RING1 0x008c
> #define mmIH_RB_CNTL_RING1_BASE_IDX 0
> #define mmIH_RB_BASE_RING1 0x008d
> @@ -159,6 +161,8 @@
> #define mmIH_RB_WPTR_RING2_BASE_IDX 0
> #define mmIH_DOORBELL_RPTR_RING2 0x009f
> #define mmIH_DOORBELL_RPTR_RING2_BASE_IDX 0
> +#define mmIH_RETRY_CAM_ACK 0x00a4
> +#define mmIH_RETRY_CAM_ACK_BASE_IDX 0
> #define mmIH_VERSION 0x00a5
> #define mmIH_VERSION_BASE_IDX 0
> #define mmIH_CNTL 0x00c0
> @@ -235,6 +239,8 @@
> #define mmIH_MMHUB_ERROR_BASE_IDX 0
> #define mmIH_MEM_POWER_CTRL 0x00e8
> #define mmIH_MEM_POWER_CTRL_BASE_IDX 0
> +#define mmIH_RETRY_INT_CAM_CNTL 0x00e9
> +#define mmIH_RETRY_INT_CAM_CNTL_BASE_IDX 0
> #define mmIH_REGISTER_LAST_PART2 0x00ff
> #define mmIH_REGISTER_LAST_PART2_BASE_IDX 0
> #define mmSEM_CLK_CTRL 0x0100
> diff --git a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h
> index 3ea83ea9ce3a..a0cc5ecfa161 100644
> --- a/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h
> +++ b/drivers/gpu/drm/amd/include/asic_reg/oss/osssys_4_2_0_sh_mask.h
> @@ -349,6 +349,19 @@
> #define IH_DOORBELL_RPTR_RING2__ENABLE__SHIFT 0x1c
> #define IH_DOORBELL_RPTR_RING2__OFFSET_MASK 0x03FFFFFFL
> #define IH_DOORBELL_RPTR_RING2__ENABLE_MASK 0x10000000L
> +//IH_RETRY_INT_CAM_CNTL
> +#define IH_RETRY_INT_CAM_CNTL__CAM_SIZE__SHIFT 0x0
> +#define IH_RETRY_INT_CAM_CNTL__BACK_PRESSURE_SKID_VALUE__SHIFT 0x8
> +#define IH_RETRY_INT_CAM_CNTL__ENABLE__SHIFT 0x10
> +#define IH_RETRY_INT_CAM_CNTL__MM_BACK_PRESSURE_ENABLE__SHIFT 0x11
> +#define IH_RETRY_INT_CAM_CNTL__GC_BACK_PRESSURE_ENABLE__SHIFT 0x12
> +#define IH_RETRY_INT_CAM_CNTL__PER_VF_ENTRY_SIZE__SHIFT 0x14
> +#define IH_RETRY_INT_CAM_CNTL__CAM_SIZE_MASK 0x0000001FL
> +#define IH_RETRY_INT_CAM_CNTL__BACK_PRESSURE_SKID_VALUE_MASK 0x00003F00L
> +#define IH_RETRY_INT_CAM_CNTL__ENABLE_MASK 0x00010000L
> +#define IH_RETRY_INT_CAM_CNTL__MM_BACK_PRESSURE_ENABLE_MASK 0x00020000L
> +#define IH_RETRY_INT_CAM_CNTL__GC_BACK_PRESSURE_ENABLE_MASK 0x00040000L
> +#define IH_RETRY_INT_CAM_CNTL__PER_VF_ENTRY_SIZE_MASK 0x00300000L
> //IH_VERSION
> #define IH_VERSION__MINVER__SHIFT 0x0
> #define IH_VERSION__MAJVER__SHIFT 0x8
More information about the amd-gfx
mailing list