[v3,8/8] drm/omap: add OMAP_BO flags to affect buffer allocation

Jean-Jacques Hiblot jjhiblot at ti.com
Tue Oct 8 16:01:05 UTC 2019


On 07/10/2019 13:25, Jean-Jacques Hiblot wrote:
> From: Tomi Valkeinen <tomi.valkeinen at ti.com>
>
> On SoCs with DMM/TILER, we have two ways to allocate buffers: normal
> dma_alloc or via DMM (which basically functions as an IOMMU). DMM can
> map 128MB at a time, and we only map the DMM buffers when they are used
> (i.e. not at alloc time). If DMM is present, omapdrm always uses DMM.
>
> There are use cases that require lots of big buffers that are being used
> at the same time by different IPs. At the moment the userspace has a
> hard maximum of 128MB.
>
> This patch adds three new flags that can be used by the userspace to
> solve the situation:
>
> OMAP_BO_MEM_CONTIG: The driver will use dma_alloc to get the memory.
> This can be used to avoid DMM if the userspace knows it needs more than
> 128M of memory at the same time.
>
> OMAP_BO_MEM_DMM: The driver will use DMM to get the memory. There's not
> much use for this flag at the moment, as on platforms with DMM it is
> used by default, but it's here for completeness.
>
> OMAP_BO_MEM_PIN: The driver will pin the memory at alloc time, and keep
> it pinned. This can be used to 1) get an error at alloc time if DMM
> space is full, and 2) get rid of the constant pin/unpin operations which
> may have some effect on performance.
>
> If none of the flags are given, the behavior is the same as currently.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
> ---
>   drivers/gpu/drm/omapdrm/omap_gem.c | 54 ++++++++++++++++++++++++++++--
>   include/uapi/drm/omap_drm.h        |  9 +++++
>   2 files changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
> index e518d93ca6df..bf18dfe2b689 100644
> --- a/drivers/gpu/drm/omapdrm/omap_gem.c
> +++ b/drivers/gpu/drm/omapdrm/omap_gem.c
> @@ -1097,6 +1097,9 @@ void omap_gem_free_object(struct drm_gem_object *obj)
>   	list_del(&omap_obj->mm_list);
>   	mutex_unlock(&priv->list_lock);
>   
> +	if (omap_obj->flags & OMAP_BO_MEM_PIN)
> +		omap_gem_unpin_locked(obj);
> +
>   	/*
>   	 * We own the sole reference to the object at this point, but to keep
>   	 * lockdep happy, we must still take the omap_obj_lock to call
> @@ -1147,10 +1150,19 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags)
>   		return false;
>   	}
>   
> +	if ((flags & OMAP_BO_MEM_CONTIG) && (flags & OMAP_BO_MEM_DMM))
> +		return false;
> +
> +	if ((flags & OMAP_BO_MEM_DMM) && !priv->usergart)
> +		return false;
> +
>   	if (flags & OMAP_BO_TILED_MASK) {
>   		if (!priv->usergart)
>   			return false;
>   
> +		if (flags & OMAP_BO_MEM_CONTIG)
> +			return false;
> +
>   		switch (flags & OMAP_BO_TILED_MASK) {
>   		case OMAP_BO_TILED_8:
>   		case OMAP_BO_TILED_16:
> @@ -1165,7 +1177,34 @@ static bool omap_gem_validate_flags(struct drm_device *dev, u32 flags)
>   	return true;
>   }
>   
> -/* GEM buffer object constructor */
> +/**
> + * omap_gem_new() - Create a new GEM buffer
> + * @dev: The DRM device
> + * @gsize: The requested size for the GEM buffer. If the buffer is tiled
> + *         (2D buffer), the size is a pair of values: height and width
> + *         expressed in pixels. If the buffers is not tiled, it is expressed
> + *         in bytes.
> + * @flags: Flags give additionnal information about the allocation:
> + *         OMAP_BO_TILED_x: use the TILER (2D buffers). The TILER container
> + *              unit can be 8, 16 or 32 bits. Cache is always disabled for
> + *              tiled buffers.
> + *         OMAP_BO_SCANOUT: Scannout buffer, consummable by the DSS
> + *         OMAP_BO_CACHED: Buffer CPU caching mode: cached
> + *         OMAP_BO_WC: Buffer CPU caching mode: write-combined
> + *         OMAP_BO_UNCACHED: Buffer CPU caching mode: uncached
> + *         OMAP_BO_MEM_CONTIG: The driver will use dma_alloc to get the memory.
> + *              This can be used to avoid DMM if the userspace knows it needs
> + *              more than 128M of memory at the same time.
> + *         OMAP_BO_MEM_DMM: The driver will use DMM to get the memory. There's
> + *              not much use for this flag at the moment, as on platforms with
> + *              DMM it is used by default, but it's here for completeness.
> + *         OMAP_BO_MEM_PIN: The driver will pin the memory at alloc time, and
> + *              keep it pinned. This can be used to 1) get an error at alloc
> + *              time if DMM space is full, and 2) get rid of the constant
> + *              pin/unpin operations which may have some effect on performance.
> + *
> + * Return: The GEM buffer or NULL if the allocation failed
> + */
>   struct drm_gem_object *omap_gem_new(struct drm_device *dev,
>   		union omap_gem_size gsize, u32 flags)
>   {
> @@ -1193,7 +1232,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
>   		 */
>   		flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED);
>   		flags |= tiler_get_cpu_cache_flags();
> -	} else if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) {
> +	} else if ((flags & OMAP_BO_MEM_CONTIG) ||
> +		((flags & OMAP_BO_SCANOUT) && !priv->has_dmm)) {
>   		/*
>   		 * If we don't have DMM, we must allocate scanout buffers
>   		 * from contiguous DMA memory.
> @@ -1253,12 +1293,22 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
>   			goto err_release;
>   	}
>   
> +	if (flags & OMAP_BO_MEM_PIN) {
> +		ret = omap_gem_pin(obj, NULL);
> +		if (ret)
> +			goto err_free_dma;
> +	}
> +
>   	mutex_lock(&priv->list_lock);
>   	list_add(&omap_obj->mm_list, &priv->obj_list);
>   	mutex_unlock(&priv->list_lock);
>   
>   	return obj;
>   
> +err_free_dma:
> +	if (flags & OMAP_BO_MEM_DMA_API)
> +		dma_free_wc(dev->dev, size, omap_obj->vaddr,
> +			    omap_obj->dma_addr);
>   err_release:
>   	drm_gem_object_release(obj);
>   err_free:
> diff --git a/include/uapi/drm/omap_drm.h b/include/uapi/drm/omap_drm.h
> index 5a142fad473c..842d3180a442 100644
> --- a/include/uapi/drm/omap_drm.h
> +++ b/include/uapi/drm/omap_drm.h
> @@ -47,6 +47,15 @@ struct drm_omap_param {
>   #define OMAP_BO_UNCACHED	0x00000004
>   #define OMAP_BO_CACHE_MASK	0x00000006
>   
> +/* Force allocation from contiguous DMA memory */
> +#define OMAP_BO_MEM_CONTIG	0x00000008
> +
> +/* Force allocation via DMM */
> +#define OMAP_BO_MEM_DMM		0x00000010
> +
> +/* Pin the buffer when allocating and keep pinned */
> +#define OMAP_BO_MEM_PIN		0x00000020
> +
>   /* Use TILER for the buffer. The TILER container unit can be 8, 16 or 32 bits. */
>   #define OMAP_BO_TILED_8		0x00000100
>   #define OMAP_BO_TILED_16	0x00000200

I modified the patch to add comment following the kernel-doc style, so 
my Reviewed-by actually applies only to the code modifications, not the 
comment wording.

Reviewed-by: Jean-Jacques Hiblot <jjhiblot at ti.com>



More information about the dri-devel mailing list