static int
drm_gem_handle_delete(struct drm_file *filp, int handle)
{
+ struct drm_device *dev;
struct drm_gem_object *obj;
/* This is gross. The idr system doesn't let us try a delete and
spin_unlock(&filp->table_lock);
return -EINVAL;
}
+ dev = obj->dev;
/* Release reference and decrement refcount. */
idr_remove(&filp->object_idr, handle);
spin_unlock(&filp->table_lock);
+ mutex_lock(&dev->struct_mutex);
drm_gem_object_handle_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
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;
if (obj == NULL)
return -EINVAL;
+ mutex_lock(&dev->struct_mutex);
if (dev->driver->gem_set_domain) {
ret = dev->driver->gem_set_domain(obj,
DRM_GEM_DOMAIN_CPU,
0);
if (ret) {
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
}
}
args->size, &offset);
if (read != args->size) {
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
if (read < 0)
return read;
else
}
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
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;
if (obj == NULL)
return -EINVAL;
+ mutex_lock(&dev->struct_mutex);
if (dev->driver->gem_set_domain) {
ret = dev->driver->gem_set_domain(obj,
DRM_GEM_DOMAIN_CPU,
DRM_GEM_DOMAIN_CPU);
if (ret) {
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
}
}
if (written != args->size) {
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
if (written < 0)
return written;
else
args->size);
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
goto again;
if (ret != 0) {
+ mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
}
return -ENOENT;
ret = drm_gem_handle_create(file_priv, obj, &handle);
+ mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
if (ret)
return ret;
if (obj == NULL)
return -EINVAL;
+ mutex_lock(&dev->struct_mutex);
if (dev->driver->gem_set_domain) {
ret = dev->driver->gem_set_domain(obj,
args->read_domains,
ret = 0;
}
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
}
void
drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
{
+ mutex_lock(&dev->struct_mutex);
idr_for_each(&file_private->object_idr,
&drm_gem_object_release_handle, NULL);
idr_destroy(&file_private->object_idr);
+ mutex_unlock(&dev->struct_mutex);
}
/**
struct drm_gem_object *obj = (struct drm_gem_object *) kref;
struct drm_device *dev = obj->dev;
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+
if (dev->driver->gem_free_object != NULL)
dev->driver->gem_free_object(obj);
.ioctls = i915_ioctls,
.gem_init_object = i915_gem_init_object,
.gem_free_object = i915_gem_free_object,
- .gem_set_domain = i915_gem_set_domain_ioctl,
+ .gem_set_domain = i915_gem_set_domain,
.gem_flush_pwrite = i915_gem_flush_pwrite,
.fops = {
.owner = THIS_MODULE,
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_init *args = data;
+ mutex_lock(&dev->struct_mutex);
+
if (args->gtt_start >= args->gtt_end ||
(args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
- (args->gtt_end & (PAGE_SIZE - 1)) != 0)
+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
+ mutex_unlock(&dev->struct_mutex);
return -EINVAL;
+ }
drm_memrange_init(&dev_priv->mm.gtt_space, args->gtt_start,
args->gtt_end - args->gtt_start);
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
struct drm_i915_gem_object *obj_priv, *last_priv = NULL;
int ret = 0;
+ mutex_lock(&dev->struct_mutex);
while (ring->space + 1024 < dev_priv->ring.Size &&
!list_empty(&dev_priv->mm.active_list)) {
obj_priv = list_first_entry(&dev_priv->mm.active_list,
last_priv = obj_priv;
i915_kernel_lost_context(dev);
}
+ mutex_unlock(&dev->struct_mutex);
return ret;
}
goto err;
}
+ mutex_lock(&dev->struct_mutex);
/* Look up object handles and perform the relocations */
for (i = 0; i < args->buffer_count; i++) {
object_list[i] = drm_gem_object_lookup(dev, file_priv,
for (i = 0; i < args->buffer_count; i++)
drm_gem_object_unreference(object_list[i]);
}
+ mutex_unlock(&dev->struct_mutex);
+
drm_free(object_list, sizeof(*object_list) * args->buffer_count,
DRM_MEM_DRIVER);
drm_free(validate_list, sizeof(*validate_list) * args->buffer_count,
struct drm_i915_gem_object *obj_priv;
int ret;
+ mutex_lock(&dev->struct_mutex);
+
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL) {
DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
args->handle);
+ mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
"i915_gem_pin_ioctl(): %d\n",
ret);
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
}
}
obj_priv->pin_count++;
args->offset = obj_priv->gtt_offset;
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
+ mutex_lock(&dev->struct_mutex);
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (obj == NULL) {
DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
args->handle);
+ mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
obj_priv = obj->driver_private;
obj_priv->pin_count--;
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
}
int
-i915_gem_set_domain_ioctl(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain)
+i915_gem_set_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain)
{
+ struct drm_device *dev = obj->dev;
+
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+
i915_gem_object_set_domain(obj, read_domains, write_domain);
i915_gem_dev_set_domain(obj->dev);
+
return 0;
}
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ mutex_lock(&dev->struct_mutex);
+
/* Assume that the chip has been idled at this point. Just pull them
* off the execution list and unref them. Since this is the last
* close, this is also the last ref and they'll go away.
obj_priv->obj->write_domain = 0;
drm_gem_object_unreference(obj_priv->obj);
}
+
+ mutex_unlock(&dev->struct_mutex);
}
struct drm_file *file_priv);
int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_free_object(struct drm_gem_object *obj);
-int i915_gem_set_domain_ioctl (struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain);
+int i915_gem_set_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain);
int i915_gem_flush_pwrite(struct drm_gem_object *obj,
uint64_t offset, uint64_t size);
void i915_gem_lastclose(struct drm_device *dev);