[PATCH v3 3/8] drm/etnaviv: share a single cmdbuf suballoc region across all GPUs

Guido Günther agx at sigxcpu.org
Tue Aug 13 14:01:47 UTC 2019


Hi,
On Fri, Aug 09, 2019 at 02:04:19PM +0200, Lucas Stach wrote:
> There is no need for each GPU to have it's own cmdbuf suballocation
> region. Only allocate a single one for the the etnaviv virtual device
> and share it across all GPUs.
> 
> As the suballoc space is now potentially shared by more hardware jobs
> running in parallel, double its size to 512KB to avoid contention.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>

Reviewed-by: Guido Günther <agx at sigxcpu.org>

> ---
>  drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c     | 14 +++++++-------
>  drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h     |  4 ++--
>  drivers/gpu/drm/etnaviv/etnaviv_drv.c        | 19 +++++++++++++++----
>  drivers/gpu/drm/etnaviv/etnaviv_drv.h        |  2 ++
>  drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |  2 +-
>  drivers/gpu/drm/etnaviv/etnaviv_gpu.c        | 17 ++++-------------
>  drivers/gpu/drm/etnaviv/etnaviv_gpu.h        |  1 -
>  7 files changed, 31 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
> index e842d988edd4..b0babc0f7230 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
> @@ -13,13 +13,13 @@
>  #include "etnaviv_mmu.h"
>  #include "etnaviv_perfmon.h"
>  
> -#define SUBALLOC_SIZE		SZ_256K
> +#define SUBALLOC_SIZE		SZ_512K
>  #define SUBALLOC_GRANULE	SZ_4K
>  #define SUBALLOC_GRANULES	(SUBALLOC_SIZE / SUBALLOC_GRANULE)
>  
>  struct etnaviv_cmdbuf_suballoc {
>  	/* suballocated dma buffer properties */
> -	struct etnaviv_gpu *gpu;
> +	struct device *dev;
>  	void *vaddr;
>  	dma_addr_t paddr;
>  
> @@ -31,7 +31,7 @@ struct etnaviv_cmdbuf_suballoc {
>  };
>  
>  struct etnaviv_cmdbuf_suballoc *
> -etnaviv_cmdbuf_suballoc_new(struct etnaviv_gpu * gpu)
> +etnaviv_cmdbuf_suballoc_new(struct device *dev)
>  {
>  	struct etnaviv_cmdbuf_suballoc *suballoc;
>  	int ret;
> @@ -40,11 +40,11 @@ etnaviv_cmdbuf_suballoc_new(struct etnaviv_gpu * gpu)
>  	if (!suballoc)
>  		return ERR_PTR(-ENOMEM);
>  
> -	suballoc->gpu = gpu;
> +	suballoc->dev = dev;
>  	mutex_init(&suballoc->lock);
>  	init_waitqueue_head(&suballoc->free_event);
>  
> -	suballoc->vaddr = dma_alloc_wc(gpu->dev, SUBALLOC_SIZE,
> +	suballoc->vaddr = dma_alloc_wc(dev, SUBALLOC_SIZE,
>  				       &suballoc->paddr, GFP_KERNEL);
>  	if (!suballoc->vaddr) {
>  		ret = -ENOMEM;
> @@ -76,7 +76,7 @@ void etnaviv_cmdbuf_suballoc_unmap(struct etnaviv_iommu *mmu,
>  
>  void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc)
>  {
> -	dma_free_wc(suballoc->gpu->dev, SUBALLOC_SIZE, suballoc->vaddr,
> +	dma_free_wc(suballoc->dev, SUBALLOC_SIZE, suballoc->vaddr,
>  		    suballoc->paddr);
>  	kfree(suballoc);
>  }
> @@ -101,7 +101,7 @@ int etnaviv_cmdbuf_init(struct etnaviv_cmdbuf_suballoc *suballoc,
>  						       suballoc->free_space,
>  						       msecs_to_jiffies(10 * 1000));
>  		if (!ret) {
> -			dev_err(suballoc->gpu->dev,
> +			dev_err(suballoc->dev,
>  				"Timeout waiting for cmdbuf space\n");
>  			return -ETIMEDOUT;
>  		}
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h
> index 583f56bf011c..a28668e46e26 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.h
> @@ -8,7 +8,7 @@
>  
>  #include <linux/types.h>
>  
> -struct etnaviv_gpu;
> +struct device;
>  struct etnaviv_iommu;
>  struct etnaviv_vram_mapping;
>  struct etnaviv_cmdbuf_suballoc;
> @@ -25,7 +25,7 @@ struct etnaviv_cmdbuf {
>  };
>  
>  struct etnaviv_cmdbuf_suballoc *
> -etnaviv_cmdbuf_suballoc_new(struct etnaviv_gpu * gpu);
> +etnaviv_cmdbuf_suballoc_new(struct device *dev);
>  void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc);
>  int etnaviv_cmdbuf_suballoc_map(struct etnaviv_cmdbuf_suballoc *suballoc,
>  				struct etnaviv_iommu *mmu,
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> index 9d4404723489..5fa3aa7bdbc5 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> @@ -530,23 +530,32 @@ static int etnaviv_bind(struct device *dev)
>  	INIT_LIST_HEAD(&priv->gem_list);
>  	priv->num_gpus = 0;
>  
> +	priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
> +	if (IS_ERR(priv->cmdbuf_suballoc)) {
> +		dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
> +		ret = PTR_ERR(priv->cmdbuf_suballoc);
> +		goto out_free_priv;
> +	}
> +
>  	dev_set_drvdata(dev, drm);
>  
>  	ret = component_bind_all(dev, drm);
>  	if (ret < 0)
> -		goto out_bind;
> +		goto out_destroy_suballoc;
>  
>  	load_gpu(drm);
>  
>  	ret = drm_dev_register(drm, 0);
>  	if (ret)
> -		goto out_register;
> +		goto out_unbind;
>  
>  	return 0;
>  
> -out_register:
> +out_unbind:
>  	component_unbind_all(dev, drm);
> -out_bind:
> +out_destroy_suballoc:
> +	etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
> +out_free_priv:
>  	kfree(priv);
>  out_put:
>  	drm_dev_put(drm);
> @@ -565,6 +574,8 @@ static void etnaviv_unbind(struct device *dev)
>  
>  	dev->dma_parms = NULL;
>  
> +	etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
> +
>  	drm->dev_private = NULL;
>  	kfree(priv);
>  
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> index eabe394c4e25..e052d7db66ae 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
> @@ -36,6 +36,8 @@ struct etnaviv_drm_private {
>  	struct device_dma_parameters dma_parms;
>  	struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
>  
> +	struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
> +
>  	/* list of GEM objects: */
>  	struct mutex gem_lock;
>  	struct list_head gem_list;
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> index f535a627f297..3f4f6ab388de 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> @@ -496,7 +496,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
>  		goto err_submit_ww_acquire;
>  	}
>  
> -	ret = etnaviv_cmdbuf_init(gpu->cmdbuf_suballoc, &submit->cmdbuf,
> +	ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf,
>  				  ALIGN(args->stream_size, 8) + 8);
>  	if (ret)
>  		goto err_submit_objects;
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> index f00547b88a13..179bc6c544ca 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> @@ -693,6 +693,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
>  
>  int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
>  {
> +	struct etnaviv_drm_private *priv = gpu->drm->dev_private;
>  	int ret, i;
>  
>  	ret = pm_runtime_get_sync(gpu->dev);
> @@ -760,23 +761,16 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
>  		goto fail;
>  	}
>  
> -	gpu->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(gpu);
> -	if (IS_ERR(gpu->cmdbuf_suballoc)) {
> -		dev_err(gpu->dev, "Failed to create cmdbuf suballocator\n");
> -		ret = PTR_ERR(gpu->cmdbuf_suballoc);
> -		goto destroy_iommu;
> -	}
> -
> -	ret = etnaviv_cmdbuf_suballoc_map(gpu->cmdbuf_suballoc, gpu->mmu,
> +	ret = etnaviv_cmdbuf_suballoc_map(priv->cmdbuf_suballoc, gpu->mmu,
>  					  &gpu->cmdbuf_mapping,
>  					  gpu->memory_base);
>  	if (ret) {
>  		dev_err(gpu->dev, "failed to map cmdbuf suballoc\n");
> -		goto destroy_suballoc;
> +		goto destroy_iommu;
>  	}
>  
>  	/* Create buffer: */
> -	ret = etnaviv_cmdbuf_init(gpu->cmdbuf_suballoc, &gpu->buffer,
> +	ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
>  				  PAGE_SIZE);
>  	if (ret) {
>  		dev_err(gpu->dev, "could not create command buffer\n");
> @@ -815,8 +809,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
>  	etnaviv_cmdbuf_free(&gpu->buffer);
>  unmap_suballoc:
>  	etnaviv_cmdbuf_suballoc_unmap(gpu->mmu, &gpu->cmdbuf_mapping);
> -destroy_suballoc:
> -	etnaviv_cmdbuf_suballoc_destroy(gpu->cmdbuf_suballoc);
>  destroy_iommu:
>  	etnaviv_iommu_destroy(gpu->mmu);
>  fail:
> @@ -1692,7 +1684,6 @@ static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
>  	if (gpu->initialized) {
>  		etnaviv_cmdbuf_free(&gpu->buffer);
>  		etnaviv_cmdbuf_suballoc_unmap(gpu->mmu, &gpu->cmdbuf_mapping);
> -		etnaviv_cmdbuf_suballoc_destroy(gpu->cmdbuf_suballoc);
>  		etnaviv_iommu_destroy(gpu->mmu);
>  		gpu->initialized = false;
>  	}
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
> index 6a6add350d2d..933c8d016f11 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
> @@ -137,7 +137,6 @@ struct etnaviv_gpu {
>  	int irq;
>  
>  	struct etnaviv_iommu *mmu;
> -	struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
>  
>  	/* Power Control: */
>  	struct clk *clk_bus;
> -- 
> 2.20.1
> 
> _______________________________________________
> etnaviv mailing list
> etnaviv at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/etnaviv


More information about the dri-devel mailing list