[Intel-gfx] [PATCH 2/6] drm/i915: Support for creating Stolen memory backed objects

Ankitprasad Sharma ankitprasad.r.sharma at intel.com
Fri Dec 11 03:22:44 PST 2015


On Wed, 2015-12-09 at 14:06 +0000, Tvrtko Ursulin wrote:
> Hi,
> 
> On 09/12/15 12:46, ankitprasad.r.sharma at intel.com wrote:
> > From: Ankitprasad Sharma <ankitprasad.r.sharma at intel.com>
> >
> > Extend the drm_i915_gem_create structure to add support for
> > creating Stolen memory backed objects. Added a new flag through
> > which user can specify the preference to allocate the object from
> > stolen memory, which if set, an attempt will be made to allocate
> > the object from stolen memory subject to the availability of
> > free space in the stolen region.
> >
> > v2: Rebased to the latest drm-intel-nightly (Ankit)
> >
> > v3: Changed versioning of GEM_CREATE param, added new comments (Tvrtko)
> >
> > v4: Changed size from 32b to 64b to prevent userspace overflow (Tvrtko)
> > Corrected function arguments ordering (Chris)
> >
> > v5: Corrected function name (Chris)
> >
> > Testcase: igt/gem_stolen
> >
> > Signed-off-by: Ankitprasad Sharma <ankitprasad.r.sharma at intel.com>
> > Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> > ---
> >   drivers/gpu/drm/i915/i915_dma.c        |  3 +++
> >   drivers/gpu/drm/i915/i915_drv.h        |  2 +-
> >   drivers/gpu/drm/i915/i915_gem.c        | 30 +++++++++++++++++++++++++++---
> >   drivers/gpu/drm/i915/i915_gem_stolen.c |  4 ++--
> >   include/uapi/drm/i915_drm.h            | 16 ++++++++++++++++
> >   5 files changed, 49 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> > index ffcb9c6..6927c7e 100644
> > --- a/drivers/gpu/drm/i915/i915_dma.c
> > +++ b/drivers/gpu/drm/i915/i915_dma.c
> > @@ -170,6 +170,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
> >   	case I915_PARAM_HAS_RESOURCE_STREAMER:
> >   		value = HAS_RESOURCE_STREAMER(dev);
> >   		break;
> > +	case I915_PARAM_CREATE_VERSION:
> > +		value = 2;
> > +		break;
> >   	default:
> >   		DRM_DEBUG("Unknown parameter %d\n", param->param);
> >   		return -EINVAL;
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 8e554d3..d45274e 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -3213,7 +3213,7 @@ void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
> >   int i915_gem_init_stolen(struct drm_device *dev);
> >   void i915_gem_cleanup_stolen(struct drm_device *dev);
> >   struct drm_i915_gem_object *
> > -i915_gem_object_create_stolen(struct drm_device *dev, u32 size);
> > +i915_gem_object_create_stolen(struct drm_device *dev, u64 size);
> >   struct drm_i915_gem_object *
> >   i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
> >   					       u32 stolen_offset,
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index d57e850..296e63f 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -375,6 +375,7 @@ static int
> >   i915_gem_create(struct drm_file *file,
> >   		struct drm_device *dev,
> >   		uint64_t size,
> > +		uint32_t flags,
> >   		uint32_t *handle_p)
> >   {
> >   	struct drm_i915_gem_object *obj;
> > @@ -385,8 +386,31 @@ i915_gem_create(struct drm_file *file,
> >   	if (size == 0)
> >   		return -EINVAL;
> >
> > +	if (flags & __I915_CREATE_UNKNOWN_FLAGS)
> > +		return -EINVAL;
> > +
> >   	/* Allocate the new object */
> > -	obj = i915_gem_alloc_object(dev, size);
> > +	if (flags & I915_CREATE_PLACEMENT_STOLEN) {
> > +		mutex_lock(&dev->struct_mutex);
> > +		obj = i915_gem_object_create_stolen(dev, size);
> > +		if (!obj) {
> > +			mutex_unlock(&dev->struct_mutex);
> > +			return -ENOMEM;
> > +		}
> > +
> > +		/* Always clear fresh buffers before handing to userspace */
> > +		ret = i915_gem_object_clear(obj);
> > +		if (ret) {
> > +			drm_gem_object_unreference(&obj->base);
> > +			mutex_unlock(&dev->struct_mutex);
> > +			return ret;
> > +		}
> > +
> > +		mutex_unlock(&dev->struct_mutex);
> > +	} else {
> > +		obj = i915_gem_alloc_object(dev, size);
> > +	}
> > +
> >   	if (obj == NULL)
> >   		return -ENOMEM;
> >
> > @@ -409,7 +433,7 @@ i915_gem_dumb_create(struct drm_file *file,
> >   	args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
> >   	args->size = args->pitch * args->height;
> >   	return i915_gem_create(file, dev,
> > -			       args->size, &args->handle);
> > +			       args->size, 0, &args->handle);
> >   }
> >
> >   /**
> > @@ -422,7 +446,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
> >   	struct drm_i915_gem_create *args = data;
> >
> >   	return i915_gem_create(file, dev,
> > -			       args->size, &args->handle);
> > +			       args->size, args->flags, &args->handle);
> >   }
> >
> >   static inline int
> > diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> > index 598ed2f..b98a3bf 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> > @@ -583,7 +583,7 @@ cleanup:
> >   }
> >
> >   struct drm_i915_gem_object *
> > -i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
> > +i915_gem_object_create_stolen(struct drm_device *dev, u64 size)
> >   {
> >   	struct drm_i915_private *dev_priv = dev->dev_private;
> >   	struct drm_i915_gem_object *obj;
> > @@ -593,7 +593,7 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
> >   	if (!drm_mm_initialized(&dev_priv->mm.stolen))
> >   		return NULL;
> >
> > -	DRM_DEBUG_KMS("creating stolen object: size=%x\n", size);
> > +	DRM_DEBUG_KMS("creating stolen object: size=%llx\n", size);
> >   	if (size == 0)
> >   		return NULL;
> >
> > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > index 67cebe6..8e7e3a4 100644
> > --- a/include/uapi/drm/i915_drm.h
> > +++ b/include/uapi/drm/i915_drm.h
> > @@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {
> >   #define I915_PARAM_EU_TOTAL		 34
> >   #define I915_PARAM_HAS_GPU_RESET	 35
> >   #define I915_PARAM_HAS_RESOURCE_STREAMER 36
> > +#define I915_PARAM_CREATE_VERSION	 37
> >
> >   typedef struct drm_i915_getparam {
> >   	__s32 param;
> > @@ -455,6 +456,21 @@ struct drm_i915_gem_create {
> >   	 */
> >   	__u32 handle;
> >   	__u32 pad;
> > +	/**
> > +	 * Requested flags (currently used for placement
> > +	 * (which memory domain))
> > +	 *
> > +	 * You can request that the object be created from special memory
> > +	 * rather than regular system pages using this parameter. Such
> > +	 * irregular objects may have certain restrictions (such as CPU
> > +	 * access to a stolen object is verboten).
> > +	 *
> > +	 * This can be used in the future for other purposes too
> > +	 * e.g. specifying tiling/caching/madvise
> > +	 */
> > +	__u32 flags;
> > +#define I915_CREATE_PLACEMENT_STOLEN 	(1<<0) /* Cannot use CPU mmaps */
> > +#define __I915_CREATE_UNKNOWN_FLAGS	-(I915_CREATE_PLACEMENT_STOLEN << 1)
> 
> I've asked in another reply, now that userspace can create a stolen 
> object, what happens if it tries to use it for a batch buffer?
> 
> Can it end up in the relocate_entry_cpu with a batch buffer allocated 
> from stolen, which would then call i915_gem_object_get_page and crash?
Thanks for pointing it out.
Yes, this is definitely a possibility, if we allocate batchbuffers from
the stolen region. I have started working on that, to do
relocate_entry_stolen() if the object is allocated from stolen.
> 
> >   };
> >
> >   struct drm_i915_gem_pread {
> >
> 
> Regards,
> 
> Tvrtko
Thanks,
Ankit



More information about the Intel-gfx mailing list