From 2655005762b8915d5f44d1d1ee7e6c2eb34841d7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 11 Jun 2008 14:42:40 -0700 Subject: [gem] Move potentially device-specific ioctls to the intel driver. This is the create (may want location flags), pread/pwrite/mmap (performance tuning hints), and set_domain (will 32 bits be enough for everyone?) ioctls. Left in the generic set are just flink/open/close. The 2D driver must be updated for this change, and API but not ABI is broken for 3D. The driver version is bumped to mark this. --- linux-core/drm_gem.c | 231 +-------------------------------------------------- 1 file changed, 2 insertions(+), 229 deletions(-) (limited to 'linux-core/drm_gem.c') diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c index a8ecaf76..47b55434 100644 --- a/linux-core/drm_gem.c +++ b/linux-core/drm_gem.c @@ -99,15 +99,6 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) kref_init(&obj->refcount); kref_init(&obj->handlecount); obj->size = size; - - /* - * We've just allocated pages from the kernel, - * so they've just been written by the CPU with - * zeros. They'll need to be clflushed before we - * use them with the GPU. - */ - obj->write_domain = DRM_GEM_DOMAIN_CPU; - obj->read_domains = DRM_GEM_DOMAIN_CPU; if (dev->driver->gem_init_object != NULL && dev->driver->gem_init_object(obj) != 0) { fput(obj->filp); @@ -163,7 +154,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle) * to the object, which includes a regular reference count. Callers * will likely want to dereference the object afterwards. */ -static int +int drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, int *handlep) @@ -191,6 +182,7 @@ again: drm_gem_object_handle_reference(obj); return 0; } +EXPORT_SYMBOL(drm_gem_handle_create); /** Returns a reference to the object named by the handle. */ struct drm_gem_object * @@ -216,40 +208,6 @@ drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, } EXPORT_SYMBOL(drm_gem_object_lookup); -/** - * Creates a new mm object and returns a handle to it. - */ -int -drm_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_create *args = data; - struct drm_gem_object *obj; - int handle, ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - args->size = roundup(args->size, PAGE_SIZE); - - /* Allocate the new object */ - obj = drm_gem_object_alloc(dev, args->size); - if (obj == NULL) - return -ENOMEM; - - ret = drm_gem_handle_create(file_priv, obj, &handle); - mutex_lock(&dev->struct_mutex); - drm_gem_object_handle_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - if (ret) - return ret; - - args->handle = handle; - - return 0; -} - /** * Releases the handle to an mm object. */ @@ -268,158 +226,6 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, return ret; } -/** - * Reads data from the object referenced by handle. - * - * On error, the contents of *data are undefined. - */ -int -drm_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_pread *args = data; - struct drm_gem_object *obj; - ssize_t read; - loff_t offset; - 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; - - mutex_lock(&dev->struct_mutex); - if (dev->driver->gem_set_domain) { - ret = dev->driver->gem_set_domain(obj, file_priv, - DRM_GEM_DOMAIN_CPU, - 0); - if (ret) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } - } - offset = args->offset; - - read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr, - args->size, &offset); - if (read != args->size) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - if (read < 0) - return read; - else - return -EINVAL; - } - - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Maps the contents of an object, returning the address it is mapped - * into. - * - * While the mapping holds a reference on the contents of the object, it doesn't - * imply a ref on the object itself. - */ -int -drm_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_mmap *args = data; - struct drm_gem_object *obj; - loff_t offset; - unsigned long addr; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EINVAL; - - offset = args->offset; - - down_write(¤t->mm->mmap_sem); - addr = do_mmap(obj->filp, 0, args->size, - PROT_READ | PROT_WRITE, MAP_SHARED, - args->offset); - up_write(¤t->mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - if (IS_ERR((void *)addr)) - return addr; - - args->addr_ptr = (uint64_t) addr; - - return 0; -} - -/** - * Writes data to the object referenced by handle. - * - * On error, the contents of the buffer that were to be modified are undefined. - */ -int -drm_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_pwrite *args = data; - struct drm_gem_object *obj; - ssize_t written; - loff_t offset; - 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; - - mutex_lock(&dev->struct_mutex); - if (dev->driver->gem_set_domain) { - ret = dev->driver->gem_set_domain(obj, file_priv, - DRM_GEM_DOMAIN_CPU, - DRM_GEM_DOMAIN_CPU); - if (ret) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } - } - offset = args->offset; - - written = vfs_write(obj->filp, - (char __user *)(uintptr_t) args->data_ptr, - args->size, &offset); - - if (written != args->size) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - if (written < 0) - return written; - else - return -EINVAL; - } - - if (dev->driver->gem_flush_pwrite) - dev->driver->gem_flush_pwrite(obj, - args->offset, - args->size); - - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - /** * Create a global name for an object, returning the name. * @@ -511,39 +317,6 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, return 0; } -/** - * Called when user space prepares to use an object - */ -int -drm_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_set_domain *args = 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; - - mutex_lock(&dev->struct_mutex); - if (dev->driver->gem_set_domain) { - ret = dev->driver->gem_set_domain(obj, file_priv, - args->read_domains, - args->write_domain); - } else { - obj->read_domains = args->read_domains; - obj->write_domain = args->write_domain; - ret = 0; - } - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; -} - /** * Called at device open time, sets up the structure for handling refcounting * of mm objects. -- cgit v1.2.3 From 217beb9c8de01417ac6219b54bd25046da6d4c7a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Jun 2008 15:43:02 -0700 Subject: [intel-gem] add gtt and pin counts to /proc/dri/*/gem_objects Not quite portable, but these are useful for intel. Some more general mechanism could be done... --- linux-core/drm_gem.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'linux-core/drm_gem.c') diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c index 47b55434..434155b3 100644 --- a/linux-core/drm_gem.c +++ b/linux-core/drm_gem.c @@ -74,6 +74,11 @@ 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); + atomic_set(&dev->object_memory, 0); + atomic_set(&dev->pin_count, 0); + atomic_set(&dev->pin_memory, 0); + atomic_set(&dev->gtt_count, 0); + atomic_set(&dev->gtt_memory, 0); return 0; } @@ -106,6 +111,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) return NULL; } atomic_inc(&dev->object_count); + atomic_add(obj->size, &dev->object_memory); return obj; } EXPORT_SYMBOL(drm_gem_object_alloc); @@ -376,6 +382,7 @@ drm_gem_object_free(struct kref *kref) fput(obj->filp); atomic_dec(&dev->object_count); + atomic_sub(obj->size, &dev->object_memory); kfree(obj); } EXPORT_SYMBOL(drm_gem_object_free); -- cgit v1.2.3