diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/drm_gem.c | 39 | 
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index aa89d4b0b4c..3b64d0ef199 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -124,6 +124,31 @@ drm_gem_destroy(struct drm_device *dev)  }  /** + * Initialize an already allocate GEM object of the specified size with + * shmfs backing store. + */ +int drm_gem_object_init(struct drm_device *dev, +			struct drm_gem_object *obj, size_t size) +{ +	BUG_ON((size & (PAGE_SIZE - 1)) != 0); + +	obj->dev = dev; +	obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); +	if (IS_ERR(obj->filp)) +		return -ENOMEM; + +	kref_init(&obj->refcount); +	kref_init(&obj->handlecount); +	obj->size = size; + +	atomic_inc(&dev->object_count); +	atomic_add(obj->size, &dev->object_memory); + +	return 0; +} +EXPORT_SYMBOL(drm_gem_object_init); + +/**   * Allocate a GEM object of the specified size with shmfs backing store   */  struct drm_gem_object * @@ -131,28 +156,22 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)  {  	struct drm_gem_object *obj; -	BUG_ON((size & (PAGE_SIZE - 1)) != 0); -  	obj = kzalloc(sizeof(*obj), GFP_KERNEL);  	if (!obj)  		goto free; -	obj->dev = dev; -	obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); -	if (IS_ERR(obj->filp)) +	if (drm_gem_object_init(dev, obj, size) != 0)  		goto free; -	kref_init(&obj->refcount); -	kref_init(&obj->handlecount); -	obj->size = size;  	if (dev->driver->gem_init_object != NULL &&  	    dev->driver->gem_init_object(obj) != 0) {  		goto fput;  	} -	atomic_inc(&dev->object_count); -	atomic_add(obj->size, &dev->object_memory);  	return obj;  fput: +	/* Object_init mangles the global counters - readjust them. */ +	atomic_dec(&dev->object_count); +	atomic_sub(obj->size, &dev->object_memory);  	fput(obj->filp);  free:  	kfree(obj);  |