RE: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
> -Original Message- > From: Koenig, Christian > Sent: Wednesday, September 26, 2018 4:58 PM > To: Huang, Ray > Cc: amd-gfx@lists.freedesktop.org > Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c > > Am 26.09.2018 um 10:52 schrieb Huang, Ray: > >> -Original Message- > >> From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] > >> Sent: Tuesday, September 25, 2018 7:01 PM > >> To: Huang, Ray > >> Cc: amd-gfx@lists.freedesktop.org > >> Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c > >> > >> Am 25.09.2018 um 12:28 schrieb Huang Rui: > >>> On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: > >>>> Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. > >>>> > >>>> Signed-off-by: Christian König > >>> Reviewed-by: Huang Rui > >>> > >>> Will we have multiple interrupt rings in new asic? > >> Vega already has 3 of them, we just haven't activated the other yet. > >> > > Good to know. I just took a look at the spec. IH ring 1 is used for request > > log > and IH ring 2 is used for translation & invalidation log. > > They are to support the page migration feature. Do you plan to work on it? > > Yes, actually the IH is able to route any IV to any ring based on the client > ID, > e.g. who is sending the IV. > > So I'm currently looking into routing the VM faults to ring 2 as well. > That should allow us to better handle them and avoid overwhelming the CPU > with an interrupt storm in case of page faults. I see, thanks for explanation Thanks, Ray > > Regards, > Christian. > > > > > Thanks, > > Ray > > > >> Christian. > >> > >>> Thanks, > >>> Ray > >>> > >>>> --- > >>>>drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 > ++--- > >> --- > >>>>drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- > >>>>drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- > >>>>drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- > >>>>drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- > >>>>drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- > >>>>drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- > >>>>drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- > >>>>drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- > >>>>9 files changed, 84 insertions(+), 102 deletions(-) > >>>> > >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >>>> index 4ed86218cef3..15fb0f9738ab 100644 > >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >>>> @@ -26,44 +26,20 @@ > >>>>#include "amdgpu_ih.h" > >>>>#include "amdgpu_amdkfd.h" > >>>> > >>>> -/** > >>>> - * amdgpu_ih_ring_alloc - allocate memory for the IH ring > >>>> - * > >>>> - * @adev: amdgpu_device pointer > >>>> - * > >>>> - * Allocate a ring buffer for the interrupt controller. > >>>> - * Returns 0 for success, errors for failure. > >>>> - */ > >>>> -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ > >>>> -int r; > >>>> - > >>>> -/* Allocate ring buffer */ > >>>> -if (adev->irq.ih.ring_obj == NULL) { > >>>> -r = amdgpu_bo_create_kernel(adev, > >>>> adev->irq.ih.ring_size, > >>>> -PAGE_SIZE, > >> AMDGPU_GEM_DOMAIN_GTT, > >>>> -&adev->irq.ih.ring_obj, > >>>> -&adev->irq.ih.gpu_addr, > >>>> -(void > >>>> **)&adev->irq.ih.ring); > >>>> -if (r) { > >>>> -DRM_ERROR("amdgpu: failed to create ih ring > >>>> buffer > >> (%d).\n", r); > >>>> -return r; > >>>> -} > >>>> -} > >>>> -return 0; > >>>>
Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
Am 26.09.2018 um 10:52 schrieb Huang, Ray: -Original Message- From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] Sent: Tuesday, September 25, 2018 7:01 PM To: Huang, Ray Cc: amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c Am 25.09.2018 um 12:28 schrieb Huang Rui: On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. Signed-off-by: Christian König Reviewed-by: Huang Rui Will we have multiple interrupt rings in new asic? Vega already has 3 of them, we just haven't activated the other yet. Good to know. I just took a look at the spec. IH ring 1 is used for request log and IH ring 2 is used for translation & invalidation log. They are to support the page migration feature. Do you plan to work on it? Yes, actually the IH is able to route any IV to any ring based on the client ID, e.g. who is sending the IV. So I'm currently looking into routing the VM faults to ring 2 as well. That should allow us to better handle them and avoid overwhelming the CPU with an interrupt storm in case of page faults. Regards, Christian. Thanks, Ray Christian. Thanks, Ray --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 ++--- --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- 9 files changed, 84 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 4ed86218cef3..15fb0f9738ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -26,44 +26,20 @@ #include "amdgpu_ih.h" #include "amdgpu_amdkfd.h" -/** - * amdgpu_ih_ring_alloc - allocate memory for the IH ring - * - * @adev: amdgpu_device pointer - * - * Allocate a ring buffer for the interrupt controller. - * Returns 0 for success, errors for failure. - */ -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ - int r; - - /* Allocate ring buffer */ - if (adev->irq.ih.ring_obj == NULL) { - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, - &adev->irq.ih.ring_obj, - &adev->irq.ih.gpu_addr, - (void **)&adev->irq.ih.ring); - if (r) { - DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r); - return r; - } - } - return 0; -} - /** * amdgpu_ih_ring_init - initialize the IH state * * @adev: amdgpu_device pointer + * @ih: ih ring to initialize + * @ring_size: ring size to allocate + * @use_bus_addr: true when we can use dma_alloc_coherent * * Initializes the IH state and allocates a buffer * for the IH ring buffer. * Returns 0 for success, errors for failure. */ -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, - bool use_bus_addr) +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, + unsigned ring_size, bool use_bus_addr) { u32 rb_bufsz; int r; @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, /* Align ring size */ rb_bufsz = order_base_2(ring_size / 4); ring_size = (1 << rb_bufsz) * 4; - adev->irq.ih.ring_size = ring_size; - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; - adev->irq.ih.rptr = 0; - adev->irq.ih.use_bus_addr = use_bus_addr; - - if (adev->irq.ih.use_bus_addr) { - if (!adev->irq.ih.ring) { - /* add 8 bytes for the rptr/wptr shadows and -* add them to the end of the ring allocation. -*/ - adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, -adev- irq.ih.ring_size + 8, -&adev- irq.ih.rb_dma_addr); - if (adev->irq.ih.ring == NULL) - return -ENOMEM; - memset((void *)adev->irq.ih.ring, 0, adev- irq.ih.ring_size + 8); - adev->irq.ih.wptr_offs = (
RE: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
> -Original Message- > From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] > Sent: Tuesday, September 25, 2018 7:01 PM > To: Huang, Ray > Cc: amd-gfx@lists.freedesktop.org > Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c > > Am 25.09.2018 um 12:28 schrieb Huang Rui: > > On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: > >> Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. > >> > >> Signed-off-by: Christian König > > Reviewed-by: Huang Rui > > > > Will we have multiple interrupt rings in new asic? > > Vega already has 3 of them, we just haven't activated the other yet. > Good to know. I just took a look at the spec. IH ring 1 is used for request log and IH ring 2 is used for translation & invalidation log. They are to support the page migration feature. Do you plan to work on it? Thanks, Ray > Christian. > > > > > Thanks, > > Ray > > > >> --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 ++--- > --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- > >> drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- > >> 9 files changed, 84 insertions(+), 102 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> index 4ed86218cef3..15fb0f9738ab 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> @@ -26,44 +26,20 @@ > >> #include "amdgpu_ih.h" > >> #include "amdgpu_amdkfd.h" > >> > >> -/** > >> - * amdgpu_ih_ring_alloc - allocate memory for the IH ring > >> - * > >> - * @adev: amdgpu_device pointer > >> - * > >> - * Allocate a ring buffer for the interrupt controller. > >> - * Returns 0 for success, errors for failure. > >> - */ > >> -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ > >> - int r; > >> - > >> - /* Allocate ring buffer */ > >> - if (adev->irq.ih.ring_obj == NULL) { > >> - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, > >> - PAGE_SIZE, > AMDGPU_GEM_DOMAIN_GTT, > >> - &adev->irq.ih.ring_obj, > >> - &adev->irq.ih.gpu_addr, > >> - (void **)&adev->irq.ih.ring); > >> - if (r) { > >> - DRM_ERROR("amdgpu: failed to create ih ring buffer > (%d).\n", r); > >> - return r; > >> - } > >> - } > >> - return 0; > >> -} > >> - > >> /** > >>* amdgpu_ih_ring_init - initialize the IH state > >>* > >>* @adev: amdgpu_device pointer > >> + * @ih: ih ring to initialize > >> + * @ring_size: ring size to allocate > >> + * @use_bus_addr: true when we can use dma_alloc_coherent > >>* > >>* Initializes the IH state and allocates a buffer > >>* for the IH ring buffer. > >>* Returns 0 for success, errors for failure. > >>*/ > >> -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned > ring_size, > >> - bool use_bus_addr) > >> +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct > amdgpu_ih_ring *ih, > >> + unsigned ring_size, bool use_bus_addr) > >> { > >>u32 rb_bufsz; > >>int r; > >> @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device > *adev, unsigned ring_size, > >>/* Align ring size */ > >>rb_bufsz = order_base_2(ring_size / 4); > >>ring_size = (1 << rb_bufsz) * 4; > >> - adev->irq.ih.ring_size = ring_size; > >> - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; > >> - adev->irq.ih.rptr = 0; > >> - adev->irq.ih.use_bus_addr = use_bus_addr; > >> - > >> - if (adev->irq.ih.use_bus_addr) { > >> -
Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
Am 25.09.2018 um 12:28 schrieb Huang Rui: On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. Signed-off-by: Christian König Reviewed-by: Huang Rui Will we have multiple interrupt rings in new asic? Vega already has 3 of them, we just haven't activated the other yet. Christian. Thanks, Ray --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- 9 files changed, 84 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 4ed86218cef3..15fb0f9738ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -26,44 +26,20 @@ #include "amdgpu_ih.h" #include "amdgpu_amdkfd.h" -/** - * amdgpu_ih_ring_alloc - allocate memory for the IH ring - * - * @adev: amdgpu_device pointer - * - * Allocate a ring buffer for the interrupt controller. - * Returns 0 for success, errors for failure. - */ -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ - int r; - - /* Allocate ring buffer */ - if (adev->irq.ih.ring_obj == NULL) { - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, - &adev->irq.ih.ring_obj, - &adev->irq.ih.gpu_addr, - (void **)&adev->irq.ih.ring); - if (r) { - DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r); - return r; - } - } - return 0; -} - /** * amdgpu_ih_ring_init - initialize the IH state * * @adev: amdgpu_device pointer + * @ih: ih ring to initialize + * @ring_size: ring size to allocate + * @use_bus_addr: true when we can use dma_alloc_coherent * * Initializes the IH state and allocates a buffer * for the IH ring buffer. * Returns 0 for success, errors for failure. */ -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, - bool use_bus_addr) +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, + unsigned ring_size, bool use_bus_addr) { u32 rb_bufsz; int r; @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, /* Align ring size */ rb_bufsz = order_base_2(ring_size / 4); ring_size = (1 << rb_bufsz) * 4; - adev->irq.ih.ring_size = ring_size; - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; - adev->irq.ih.rptr = 0; - adev->irq.ih.use_bus_addr = use_bus_addr; - - if (adev->irq.ih.use_bus_addr) { - if (!adev->irq.ih.ring) { - /* add 8 bytes for the rptr/wptr shadows and -* add them to the end of the ring allocation. -*/ - adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, - adev->irq.ih.ring_size + 8, - &adev->irq.ih.rb_dma_addr); - if (adev->irq.ih.ring == NULL) - return -ENOMEM; - memset((void *)adev->irq.ih.ring, 0, adev->irq.ih.ring_size + 8); - adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + 0; - adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + 1; - } - return 0; + ih->ring_size = ring_size; + ih->ptr_mask = ih->ring_size - 1; + ih->rptr = 0; + ih->use_bus_addr = use_bus_addr; + + if (use_bus_addr) { + if (ih->ring) + return 0; + + /* add 8 bytes for the rptr/wptr shadows and +* 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); + 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; } else { - r = amdgpu_devi
Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: > Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. > > Signed-off-by: Christian König Reviewed-by: Huang Rui Will we have multiple interrupt rings in new asic? Thanks, Ray > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 > ++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- > 9 files changed, 84 insertions(+), 102 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 4ed86218cef3..15fb0f9738ab 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -26,44 +26,20 @@ > #include "amdgpu_ih.h" > #include "amdgpu_amdkfd.h" > > -/** > - * amdgpu_ih_ring_alloc - allocate memory for the IH ring > - * > - * @adev: amdgpu_device pointer > - * > - * Allocate a ring buffer for the interrupt controller. > - * Returns 0 for success, errors for failure. > - */ > -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) > -{ > - int r; > - > - /* Allocate ring buffer */ > - if (adev->irq.ih.ring_obj == NULL) { > - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, > - PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, > - &adev->irq.ih.ring_obj, > - &adev->irq.ih.gpu_addr, > - (void **)&adev->irq.ih.ring); > - if (r) { > - DRM_ERROR("amdgpu: failed to create ih ring buffer > (%d).\n", r); > - return r; > - } > - } > - return 0; > -} > - > /** > * amdgpu_ih_ring_init - initialize the IH state > * > * @adev: amdgpu_device pointer > + * @ih: ih ring to initialize > + * @ring_size: ring size to allocate > + * @use_bus_addr: true when we can use dma_alloc_coherent > * > * Initializes the IH state and allocates a buffer > * for the IH ring buffer. > * Returns 0 for success, errors for failure. > */ > -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, > - bool use_bus_addr) > +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring > *ih, > + unsigned ring_size, bool use_bus_addr) > { > u32 rb_bufsz; > int r; > @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, > unsigned ring_size, > /* Align ring size */ > rb_bufsz = order_base_2(ring_size / 4); > ring_size = (1 << rb_bufsz) * 4; > - adev->irq.ih.ring_size = ring_size; > - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; > - adev->irq.ih.rptr = 0; > - adev->irq.ih.use_bus_addr = use_bus_addr; > - > - if (adev->irq.ih.use_bus_addr) { > - if (!adev->irq.ih.ring) { > - /* add 8 bytes for the rptr/wptr shadows and > - * add them to the end of the ring allocation. > - */ > - adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, > - > adev->irq.ih.ring_size + 8, > - > &adev->irq.ih.rb_dma_addr); > - if (adev->irq.ih.ring == NULL) > - return -ENOMEM; > - memset((void *)adev->irq.ih.ring, 0, > adev->irq.ih.ring_size + 8); > - adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + > 0; > - adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + > 1; > - } > - return 0; > + ih->ring_size = ring_size; > + ih->ptr_mask = ih->ring_size - 1; > + ih->rptr = 0; > + ih->use_bus_addr = use_bus_addr; > + > + if (use_bus_addr) { > + if (ih->ring) > + return 0; > + > + /* add 8 bytes for the rptr/wptr shadows and > + * 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); > + 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; > } else { > - r = amdgpu_device_wb_get(adev, &adev
[PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- 9 files changed, 84 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 4ed86218cef3..15fb0f9738ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -26,44 +26,20 @@ #include "amdgpu_ih.h" #include "amdgpu_amdkfd.h" -/** - * amdgpu_ih_ring_alloc - allocate memory for the IH ring - * - * @adev: amdgpu_device pointer - * - * Allocate a ring buffer for the interrupt controller. - * Returns 0 for success, errors for failure. - */ -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ - int r; - - /* Allocate ring buffer */ - if (adev->irq.ih.ring_obj == NULL) { - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, - &adev->irq.ih.ring_obj, - &adev->irq.ih.gpu_addr, - (void **)&adev->irq.ih.ring); - if (r) { - DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r); - return r; - } - } - return 0; -} - /** * amdgpu_ih_ring_init - initialize the IH state * * @adev: amdgpu_device pointer + * @ih: ih ring to initialize + * @ring_size: ring size to allocate + * @use_bus_addr: true when we can use dma_alloc_coherent * * Initializes the IH state and allocates a buffer * for the IH ring buffer. * Returns 0 for success, errors for failure. */ -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, - bool use_bus_addr) +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, + unsigned ring_size, bool use_bus_addr) { u32 rb_bufsz; int r; @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, /* Align ring size */ rb_bufsz = order_base_2(ring_size / 4); ring_size = (1 << rb_bufsz) * 4; - adev->irq.ih.ring_size = ring_size; - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; - adev->irq.ih.rptr = 0; - adev->irq.ih.use_bus_addr = use_bus_addr; - - if (adev->irq.ih.use_bus_addr) { - if (!adev->irq.ih.ring) { - /* add 8 bytes for the rptr/wptr shadows and -* add them to the end of the ring allocation. -*/ - adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, - adev->irq.ih.ring_size + 8, - &adev->irq.ih.rb_dma_addr); - if (adev->irq.ih.ring == NULL) - return -ENOMEM; - memset((void *)adev->irq.ih.ring, 0, adev->irq.ih.ring_size + 8); - adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + 0; - adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + 1; - } - return 0; + ih->ring_size = ring_size; + ih->ptr_mask = ih->ring_size - 1; + ih->rptr = 0; + ih->use_bus_addr = use_bus_addr; + + if (use_bus_addr) { + if (ih->ring) + return 0; + + /* add 8 bytes for the rptr/wptr shadows and +* 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); + 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; } else { - r = amdgpu_device_wb_get(adev, &adev->irq.ih.wptr_offs); + r = amdgpu_device_wb_get(adev, &ih->wptr_offs); + if (r) + return r; + + r = amdgpu_device_wb_get(adev, &ih->rptr_offs); if (r) { - dev_err(adev->dev, "(%d) ih wptr_