diff options
author | Keith Packard <keithp@keithp.com> | 2008-05-02 16:34:16 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2008-05-02 16:34:16 -0700 |
commit | ab3549d1336fc6c08581a9fd14a83513649d9187 (patch) | |
tree | d267f50992fa987d8aca0aa19d2af015134c8cc9 /linux-core/drm_gem.c | |
parent | 39e20bcd5f4bf9fedac80188fda2e9fcab2f0360 (diff) |
Add a bit of /proc/dri/*/gem support. Clean up some refcount/pagelock issues.
Track named objects in /proc/dri/0/gem_names.
Track total object count in /proc/dri/0/gem_objects.
Initialize device gem data.
return -ENODEV for gem ioctls if the driver doesn't support gem.
Call unlock_page when unbinding from gtt.
Add numerous misssing calls to drm_gem_object_unreference.
Diffstat (limited to 'linux-core/drm_gem.c')
-rw-r--r-- | linux-core/drm_gem.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c index 2e963f20..db12f9a6 100644 --- a/linux-core/drm_gem.c +++ b/linux-core/drm_gem.c @@ -64,6 +64,22 @@ * up at a later data, and as our interface with shmfs for memory allocation. */ +/** + * Initialize the GEM device fields + */ + +int +drm_gem_init (struct drm_device *dev) +{ + spin_lock_init (&dev->object_name_lock); + idr_init (&dev->object_name_idr); + atomic_set (&dev->object_count, 0); + return 0; +} + +/** + * Allocate a GEM object of the specified size with shmfs backing store + */ static struct drm_gem_object * drm_gem_object_alloc(struct drm_device *dev, size_t size) { @@ -90,6 +106,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) kfree(obj); return NULL; } + atomic_inc (&dev->object_count); return obj; } @@ -145,10 +162,9 @@ drm_gem_handle_create (struct drm_file *file_priv, */ again: /* ensure there is space available to allocate a handle */ - if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) { - kfree(obj); + if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) return -ENOMEM; - } + /* do the allocation under our spinlock */ spin_lock (&file_priv->table_lock); ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep); @@ -198,6 +214,9 @@ drm_gem_alloc_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *obj; int handle, ret; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + /* Round requested size up to page size */ args->size = (args->size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); @@ -227,6 +246,9 @@ drm_gem_unreference_ioctl(struct drm_device *dev, void *data, struct drm_gem_unreference *args = data; int ret; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + ret = drm_gem_handle_delete(file_priv, args->handle); return ret; @@ -246,6 +268,9 @@ drm_gem_pread_ioctl(struct drm_device *dev, void *data, ssize_t read; loff_t offset; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; @@ -282,6 +307,9 @@ drm_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *obj; loff_t offset; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; @@ -313,6 +341,9 @@ drm_gem_pwrite_ioctl(struct drm_device *dev, void *data, ssize_t written; loff_t offset; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; @@ -348,6 +379,9 @@ drm_gem_name_ioctl(struct drm_device *dev, void *data, struct drm_gem_object *obj; int ret; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; @@ -396,6 +430,9 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, int ret; int handle; + if (!(dev->driver->driver_features & DRIVER_GEM)) + return -ENODEV; + spin_lock (&dev->object_name_lock); obj = idr_find (&dev->object_name_idr, (int) args->name); if (obj) @@ -423,6 +460,7 @@ void drm_gem_open(struct drm_device *dev, struct drm_file *file_private) { idr_init(&file_private->object_idr); + spin_lock_init (&file_private->table_lock); } /** Called at device close to release the file's handle references on objects. */ @@ -464,7 +502,7 @@ drm_gem_object_free (struct kref *kref) dev->driver->gem_free_object(obj); fput(obj->filp); - + atomic_dec (&dev->object_count); kfree(obj); } EXPORT_SYMBOL(drm_gem_object_free); |