aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-09-25 06:22:51 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-25 07:23:12 -0400
commit76c1dec1979d9b552aab9600eb898ccec394fbbc (patch)
tree8e86c83b9b2bb10b556d153238cb4d6e4ca201d9
parent30dbf0c07ff4e3e21b827e2a9d6ff7eb34458819 (diff)
drm/i915: Make the mutex_lock interruptible on ioctl paths
... and combine it with the wedged completion handler. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c126
1 files changed, 84 insertions, 42 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a7283092c233..ac5bff85a4c7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -91,6 +91,26 @@ i915_gem_check_is_wedged(struct drm_device *dev)
91 return -EIO; 91 return -EIO;
92} 92}
93 93
94static int i915_mutex_lock_interruptible(struct drm_device *dev)
95{
96 struct drm_i915_private *dev_priv = dev->dev_private;
97 int ret;
98
99 ret = i915_gem_check_is_wedged(dev);
100 if (ret)
101 return ret;
102
103 ret = mutex_lock_interruptible(&dev->struct_mutex);
104 if (ret)
105 return ret;
106
107 if (atomic_read(&dev_priv->mm.wedged)) {
108 mutex_unlock(&dev->struct_mutex);
109 return -EAGAIN;
110 }
111
112 return 0;
113}
94 114
95static inline bool 115static inline bool
96i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) 116i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv)
@@ -299,7 +319,9 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
299 user_data = (char __user *) (uintptr_t) args->data_ptr; 319 user_data = (char __user *) (uintptr_t) args->data_ptr;
300 remain = args->size; 320 remain = args->size;
301 321
302 mutex_lock(&dev->struct_mutex); 322 ret = i915_mutex_lock_interruptible(dev);
323 if (ret)
324 return ret;
303 325
304 ret = i915_gem_object_get_pages(obj, 0); 326 ret = i915_gem_object_get_pages(obj, 0);
305 if (ret != 0) 327 if (ret != 0)
@@ -418,7 +440,9 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
418 440
419 do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); 441 do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
420 442
421 mutex_lock(&dev->struct_mutex); 443 ret = i915_mutex_lock_interruptible(dev);
444 if (ret)
445 goto fail_put_user_pages;
422 446
423 ret = i915_gem_object_get_pages_or_evict(obj); 447 ret = i915_gem_object_get_pages_or_evict(obj);
424 if (ret) 448 if (ret)
@@ -617,8 +641,10 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
617 if (!access_ok(VERIFY_READ, user_data, remain)) 641 if (!access_ok(VERIFY_READ, user_data, remain))
618 return -EFAULT; 642 return -EFAULT;
619 643
644 ret = i915_mutex_lock_interruptible(dev);
645 if (ret)
646 return ret;
620 647
621 mutex_lock(&dev->struct_mutex);
622 ret = i915_gem_object_pin(obj, 0); 648 ret = i915_gem_object_pin(obj, 0);
623 if (ret) { 649 if (ret) {
624 mutex_unlock(&dev->struct_mutex); 650 mutex_unlock(&dev->struct_mutex);
@@ -713,7 +739,10 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
713 goto out_unpin_pages; 739 goto out_unpin_pages;
714 } 740 }
715 741
716 mutex_lock(&dev->struct_mutex); 742 ret = i915_mutex_lock_interruptible(dev);
743 if (ret)
744 goto out_unpin_pages;
745
717 ret = i915_gem_object_pin(obj, 0); 746 ret = i915_gem_object_pin(obj, 0);
718 if (ret) 747 if (ret)
719 goto out_unlock; 748 goto out_unlock;
@@ -787,7 +816,9 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
787 user_data = (char __user *) (uintptr_t) args->data_ptr; 816 user_data = (char __user *) (uintptr_t) args->data_ptr;
788 remain = args->size; 817 remain = args->size;
789 818
790 mutex_lock(&dev->struct_mutex); 819 ret = i915_mutex_lock_interruptible(dev);
820 if (ret)
821 return ret;
791 822
792 ret = i915_gem_object_get_pages(obj, 0); 823 ret = i915_gem_object_get_pages(obj, 0);
793 if (ret != 0) 824 if (ret != 0)
@@ -883,7 +914,9 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
883 914
884 do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); 915 do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
885 916
886 mutex_lock(&dev->struct_mutex); 917 ret = i915_mutex_lock_interruptible(dev);
918 if (ret)
919 goto fail_put_user_pages;
887 920
888 ret = i915_gem_object_get_pages_or_evict(obj); 921 ret = i915_gem_object_get_pages_or_evict(obj);
889 if (ret) 922 if (ret)
@@ -1051,7 +1084,11 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1051 return -ENOENT; 1084 return -ENOENT;
1052 obj_priv = to_intel_bo(obj); 1085 obj_priv = to_intel_bo(obj);
1053 1086
1054 mutex_lock(&dev->struct_mutex); 1087 ret = i915_mutex_lock_interruptible(dev);
1088 if (ret) {
1089 drm_gem_object_unreference_unlocked(obj);
1090 return ret;
1091 }
1055 1092
1056 intel_mark_busy(dev, obj); 1093 intel_mark_busy(dev, obj);
1057 1094
@@ -1106,11 +1143,14 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1106 if (!(dev->driver->driver_features & DRIVER_GEM)) 1143 if (!(dev->driver->driver_features & DRIVER_GEM))
1107 return -ENODEV; 1144 return -ENODEV;
1108 1145
1109 mutex_lock(&dev->struct_mutex);
1110 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 1146 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1111 if (obj == NULL) { 1147 if (obj == NULL)
1112 mutex_unlock(&dev->struct_mutex);
1113 return -ENOENT; 1148 return -ENOENT;
1149
1150 ret = i915_mutex_lock_interruptible(dev);
1151 if (ret) {
1152 drm_gem_object_unreference_unlocked(obj);
1153 return ret;
1114 } 1154 }
1115 1155
1116#if WATCH_BUF 1156#if WATCH_BUF
@@ -1425,7 +1465,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1425 if (obj == NULL) 1465 if (obj == NULL)
1426 return -ENOENT; 1466 return -ENOENT;
1427 1467
1428 mutex_lock(&dev->struct_mutex); 1468 ret = i915_mutex_lock_interruptible(dev);
1469 if (ret) {
1470 drm_gem_object_unreference_unlocked(obj);
1471 return ret;
1472 }
1429 1473
1430 obj_priv = to_intel_bo(obj); 1474 obj_priv = to_intel_bo(obj);
1431 1475
@@ -3668,16 +3712,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
3668 if (ret != 0) 3712 if (ret != 0)
3669 goto pre_mutex_err; 3713 goto pre_mutex_err;
3670 3714
3671 mutex_lock(&dev->struct_mutex); 3715 ret = i915_mutex_lock_interruptible(dev);
3716 if (ret)
3717 goto pre_mutex_err;
3672 3718
3673 i915_verify_inactive(dev, __FILE__, __LINE__); 3719 i915_verify_inactive(dev, __FILE__, __LINE__);
3674 3720
3675 if (atomic_read(&dev_priv->mm.wedged)) {
3676 mutex_unlock(&dev->struct_mutex);
3677 ret = -EAGAIN;
3678 goto pre_mutex_err;
3679 }
3680
3681 if (dev_priv->mm.suspended) { 3721 if (dev_priv->mm.suspended) {
3682 mutex_unlock(&dev->struct_mutex); 3722 mutex_unlock(&dev->struct_mutex);
3683 ret = -EBUSY; 3723 ret = -EBUSY;
@@ -4161,21 +4201,20 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
4161 struct drm_i915_gem_object *obj_priv; 4201 struct drm_i915_gem_object *obj_priv;
4162 int ret; 4202 int ret;
4163 4203
4164 ret = i915_gem_check_is_wedged(dev);
4165 if (ret)
4166 return ret;
4167
4168 mutex_lock(&dev->struct_mutex);
4169
4170 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4204 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4171 if (obj == NULL) { 4205 if (obj == NULL) {
4172 DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n", 4206 DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
4173 args->handle); 4207 args->handle);
4174 mutex_unlock(&dev->struct_mutex);
4175 return -ENOENT; 4208 return -ENOENT;
4176 } 4209 }
4177 obj_priv = to_intel_bo(obj); 4210 obj_priv = to_intel_bo(obj);
4178 4211
4212 ret = i915_mutex_lock_interruptible(dev);
4213 if (ret) {
4214 drm_gem_object_unreference_unlocked(obj);
4215 return ret;
4216 }
4217
4179 if (obj_priv->madv != I915_MADV_WILLNEED) { 4218 if (obj_priv->madv != I915_MADV_WILLNEED) {
4180 DRM_ERROR("Attempting to pin a purgeable buffer\n"); 4219 DRM_ERROR("Attempting to pin a purgeable buffer\n");
4181 drm_gem_object_unreference(obj); 4220 drm_gem_object_unreference(obj);
@@ -4220,18 +4259,23 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
4220 struct drm_i915_gem_pin *args = data; 4259 struct drm_i915_gem_pin *args = data;
4221 struct drm_gem_object *obj; 4260 struct drm_gem_object *obj;
4222 struct drm_i915_gem_object *obj_priv; 4261 struct drm_i915_gem_object *obj_priv;
4223 4262 int ret;
4224 mutex_lock(&dev->struct_mutex);
4225 4263
4226 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4264 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4227 if (obj == NULL) { 4265 if (obj == NULL) {
4228 DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n", 4266 DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
4229 args->handle); 4267 args->handle);
4230 mutex_unlock(&dev->struct_mutex);
4231 return -ENOENT; 4268 return -ENOENT;
4232 } 4269 }
4233 4270
4234 obj_priv = to_intel_bo(obj); 4271 obj_priv = to_intel_bo(obj);
4272
4273 ret = i915_mutex_lock_interruptible(dev);
4274 if (ret) {
4275 drm_gem_object_unreference_unlocked(obj);
4276 return ret;
4277 }
4278
4235 if (obj_priv->pin_filp != file_priv) { 4279 if (obj_priv->pin_filp != file_priv) {
4236 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", 4280 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
4237 args->handle); 4281 args->handle);
@@ -4254,16 +4298,11 @@ int
4254i915_gem_busy_ioctl(struct drm_device *dev, void *data, 4298i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4255 struct drm_file *file_priv) 4299 struct drm_file *file_priv)
4256{ 4300{
4257 struct drm_i915_private *dev_priv = dev->dev_private;
4258 struct drm_i915_gem_busy *args = data; 4301 struct drm_i915_gem_busy *args = data;
4259 struct drm_gem_object *obj; 4302 struct drm_gem_object *obj;
4260 struct drm_i915_gem_object *obj_priv; 4303 struct drm_i915_gem_object *obj_priv;
4261 int ret; 4304 int ret;
4262 4305
4263 ret = i915_gem_check_is_wedged(dev);
4264 if (ret)
4265 return ret;
4266
4267 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4306 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4268 if (obj == NULL) { 4307 if (obj == NULL) {
4269 DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n", 4308 DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
@@ -4271,11 +4310,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4271 return -ENOENT; 4310 return -ENOENT;
4272 } 4311 }
4273 4312
4274 mutex_lock(&dev->struct_mutex); 4313 ret = i915_mutex_lock_interruptible(dev);
4275 4314 if (ret) {
4276 if (atomic_read(&dev_priv->mm.wedged)) { 4315 drm_gem_object_unreference_unlocked(obj);
4277 ret = -EAGAIN; 4316 return ret;
4278 goto unlock;
4279 } 4317 }
4280 4318
4281 /* Count all active objects as busy, even if they are currently not used 4319 /* Count all active objects as busy, even if they are currently not used
@@ -4306,10 +4344,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4306 args->busy = obj_priv->active; 4344 args->busy = obj_priv->active;
4307 } 4345 }
4308 4346
4309unlock:
4310 drm_gem_object_unreference(obj); 4347 drm_gem_object_unreference(obj);
4311 mutex_unlock(&dev->struct_mutex); 4348 mutex_unlock(&dev->struct_mutex);
4312 return ret; 4349 return 0;
4313} 4350}
4314 4351
4315int 4352int
@@ -4326,6 +4363,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
4326 struct drm_i915_gem_madvise *args = data; 4363 struct drm_i915_gem_madvise *args = data;
4327 struct drm_gem_object *obj; 4364 struct drm_gem_object *obj;
4328 struct drm_i915_gem_object *obj_priv; 4365 struct drm_i915_gem_object *obj_priv;
4366 int ret;
4329 4367
4330 switch (args->madv) { 4368 switch (args->madv) {
4331 case I915_MADV_DONTNEED: 4369 case I915_MADV_DONTNEED:
@@ -4341,10 +4379,14 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
4341 args->handle); 4379 args->handle);
4342 return -ENOENT; 4380 return -ENOENT;
4343 } 4381 }
4344
4345 mutex_lock(&dev->struct_mutex);
4346 obj_priv = to_intel_bo(obj); 4382 obj_priv = to_intel_bo(obj);
4347 4383
4384 ret = i915_mutex_lock_interruptible(dev);
4385 if (ret) {
4386 drm_gem_object_unreference_unlocked(obj);
4387 return ret;
4388 }
4389
4348 if (obj_priv->pin_count) { 4390 if (obj_priv->pin_count) {
4349 drm_gem_object_unreference(obj); 4391 drm_gem_object_unreference(obj);
4350 mutex_unlock(&dev->struct_mutex); 4392 mutex_unlock(&dev->struct_mutex);