[PATCH 4/9] drm/amdgpu: move more interrupt processing into amdgpu_irq.c

Huang Rui ray.huang at amd.com
Wed Sep 26 06:13:16 UTC 2018


On Mon, Sep 24, 2018 at 02:38:15PM +0200, Christian König wrote:
> Add a callback to amdgpu_ih_process to remove most of the IV logic.
> 
> Signed-off-by: Christian König <christian.koenig at amd.com>

Acked-by: Huang Rui <ray.huang at amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c  | 24 +++++-------------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h  |  4 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 31 ++++++++++++++++++++++++++++++-
>  3 files changed, 38 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> index 15fb0f9738ab..8af67f649660 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> @@ -24,7 +24,6 @@
>  #include <drm/drmP.h>
>  #include "amdgpu.h"
>  #include "amdgpu_ih.h"
> -#include "amdgpu_amdkfd.h"
>  
>  /**
>   * amdgpu_ih_ring_init - initialize the IH state
> @@ -129,9 +128,10 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
>   * Interrupt hander (VI), walk the IH ring.
>   * Returns irq process return code.
>   */
> -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
> +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
> +		      void (*callback)(struct amdgpu_device *adev,
> +				       struct amdgpu_ih_ring *ih))
>  {
> -	struct amdgpu_iv_entry entry;
>  	u32 wptr;
>  
>  	if (!ih->enabled || adev->shutdown)
> @@ -150,24 +150,10 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
>  	rmb();
>  
>  	while (ih->rptr != wptr) {
> -		u32 ring_index = ih->rptr >> 2;
> -
> -		/* Prescreening of high-frequency interrupts */
> -		if (!amdgpu_ih_prescreen_iv(adev)) {
> -			ih->rptr &= ih->ptr_mask;
> -			continue;
> -		}
> -
> -		/* 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);
> +		callback(adev, ih);
>  		ih->rptr &= ih->ptr_mask;
> -
> -		amdgpu_irq_dispatch(adev, &entry);
>  	}
> +
>  	amdgpu_ih_set_rptr(adev);
>  	atomic_set(&ih->lock, 0);
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> index 3e55f985005c..fd2bbaa20ab4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> @@ -85,6 +85,8 @@ struct amdgpu_ih_funcs {
>  int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
>  			unsigned ring_size, bool use_bus_addr);
>  void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
> -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
> +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
> +		      void (*callback)(struct amdgpu_device *adev,
> +				       struct amdgpu_ih_ring *ih));
>  
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index aaa8545e458a..2fca08e130b6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -51,6 +51,7 @@
>  #include "atom.h"
>  #include "amdgpu_connectors.h"
>  #include "amdgpu_trace.h"
> +#include "amdgpu_amdkfd.h"
>  
>  #include <linux/pm_runtime.h>
>  
> @@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
>  	spin_unlock_irqrestore(&adev->irq.lock, irqflags);
>  }
>  
> +/**
> + * amdgpu_irq_callback - callback from the IH ring
> + *
> + * @adev: amdgpu device pointer
> + * @ih: amdgpu ih ring
> + *
> + * Callback from IH ring processing to handle the entry at the current position
> + * and advance the read pointer.
> + */
> +static void amdgpu_irq_callback(struct amdgpu_device *adev,
> +				struct amdgpu_ih_ring *ih)
> +{
> +	u32 ring_index = ih->rptr >> 2;
> +	struct amdgpu_iv_entry entry;
> +
> +	/* Prescreening of high-frequency interrupts */
> +	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);
> +
> +	amdgpu_irq_dispatch(adev, &entry);
> +}
> +
>  /**
>   * amdgpu_irq_handler - IRQ handler
>   *
> @@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
>  	struct amdgpu_device *adev = dev->dev_private;
>  	irqreturn_t ret;
>  
> -	ret = amdgpu_ih_process(adev, &adev->irq.ih);
> +	ret = amdgpu_ih_process(adev, &adev->irq.ih, amdgpu_irq_callback);
>  	if (ret == IRQ_HANDLED)
>  		pm_runtime_mark_last_busy(dev->dev);
>  	return ret;
> -- 
> 2.14.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list