aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c206
1 files changed, 93 insertions, 113 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index efc6a4e3b1d2..34a07fc20513 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -547,16 +547,16 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
547 struct drm_i915_gem_object *obj_priv; 547 struct drm_i915_gem_object *obj_priv;
548 int ret = 0; 548 int ret = 0;
549 549
550 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
551 if (obj == NULL)
552 return -ENOENT;
553 obj_priv = to_intel_bo(obj);
554
555 ret = i915_mutex_lock_interruptible(dev); 550 ret = i915_mutex_lock_interruptible(dev);
556 if (ret) { 551 if (ret)
557 drm_gem_object_unreference_unlocked(obj);
558 return ret; 552 return ret;
553
554 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
555 if (obj == NULL) {
556 ret = -ENOENT;
557 goto unlock;
559 } 558 }
559 obj_priv = to_intel_bo(obj);
560 560
561 /* Bounds check source. */ 561 /* Bounds check source. */
562 if (args->offset > obj->size || args->size > obj->size - args->offset) { 562 if (args->offset > obj->size || args->size > obj->size - args->offset) {
@@ -601,6 +601,7 @@ out_put:
601 i915_gem_object_put_pages(obj); 601 i915_gem_object_put_pages(obj);
602out: 602out:
603 drm_gem_object_unreference(obj); 603 drm_gem_object_unreference(obj);
604unlock:
604 mutex_unlock(&dev->struct_mutex); 605 mutex_unlock(&dev->struct_mutex);
605 return ret; 606 return ret;
606} 607}
@@ -982,16 +983,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
982 struct drm_i915_gem_object *obj_priv; 983 struct drm_i915_gem_object *obj_priv;
983 int ret = 0; 984 int ret = 0;
984 985
985 obj = drm_gem_object_lookup(dev, file, args->handle);
986 if (obj == NULL)
987 return -ENOENT;
988 obj_priv = to_intel_bo(obj);
989
990 ret = i915_mutex_lock_interruptible(dev); 986 ret = i915_mutex_lock_interruptible(dev);
991 if (ret) { 987 if (ret)
992 drm_gem_object_unreference_unlocked(obj);
993 return ret; 988 return ret;
989
990 obj = drm_gem_object_lookup(dev, file, args->handle);
991 if (obj == NULL) {
992 ret = -ENOENT;
993 goto unlock;
994 } 994 }
995 obj_priv = to_intel_bo(obj);
996
995 997
996 /* Bounds check destination. */ 998 /* Bounds check destination. */
997 if (args->offset > obj->size || args->size > obj->size - args->offset) { 999 if (args->offset > obj->size || args->size > obj->size - args->offset) {
@@ -1062,6 +1064,7 @@ out_put:
1062 1064
1063out: 1065out:
1064 drm_gem_object_unreference(obj); 1066 drm_gem_object_unreference(obj);
1067unlock:
1065 mutex_unlock(&dev->struct_mutex); 1068 mutex_unlock(&dev->struct_mutex);
1066 return ret; 1069 return ret;
1067} 1070}
@@ -1098,16 +1101,16 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1098 if (write_domain != 0 && read_domains != write_domain) 1101 if (write_domain != 0 && read_domains != write_domain)
1099 return -EINVAL; 1102 return -EINVAL;
1100 1103
1101 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1102 if (obj == NULL)
1103 return -ENOENT;
1104 obj_priv = to_intel_bo(obj);
1105
1106 ret = i915_mutex_lock_interruptible(dev); 1104 ret = i915_mutex_lock_interruptible(dev);
1107 if (ret) { 1105 if (ret)
1108 drm_gem_object_unreference_unlocked(obj);
1109 return ret; 1106 return ret;
1107
1108 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1109 if (obj == NULL) {
1110 ret = -ENOENT;
1111 goto unlock;
1110 } 1112 }
1113 obj_priv = to_intel_bo(obj);
1111 1114
1112 intel_mark_busy(dev, obj); 1115 intel_mark_busy(dev, obj);
1113 1116
@@ -1139,6 +1142,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1139 list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); 1142 list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
1140 1143
1141 drm_gem_object_unreference(obj); 1144 drm_gem_object_unreference(obj);
1145unlock:
1142 mutex_unlock(&dev->struct_mutex); 1146 mutex_unlock(&dev->struct_mutex);
1143 return ret; 1147 return ret;
1144} 1148}
@@ -1157,14 +1161,14 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1157 if (!(dev->driver->driver_features & DRIVER_GEM)) 1161 if (!(dev->driver->driver_features & DRIVER_GEM))
1158 return -ENODEV; 1162 return -ENODEV;
1159 1163
1160 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1161 if (obj == NULL)
1162 return -ENOENT;
1163
1164 ret = i915_mutex_lock_interruptible(dev); 1164 ret = i915_mutex_lock_interruptible(dev);
1165 if (ret) { 1165 if (ret)
1166 drm_gem_object_unreference_unlocked(obj);
1167 return ret; 1166 return ret;
1167
1168 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1169 if (obj == NULL) {
1170 ret = -ENOENT;
1171 goto unlock;
1168 } 1172 }
1169 1173
1170 /* Pinned buffers may be scanout, so flush the cache */ 1174 /* Pinned buffers may be scanout, so flush the cache */
@@ -1172,6 +1176,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1172 i915_gem_object_flush_cpu_write_domain(obj); 1176 i915_gem_object_flush_cpu_write_domain(obj);
1173 1177
1174 drm_gem_object_unreference(obj); 1178 drm_gem_object_unreference(obj);
1179unlock:
1175 mutex_unlock(&dev->struct_mutex); 1180 mutex_unlock(&dev->struct_mutex);
1176 return ret; 1181 return ret;
1177} 1182}
@@ -1469,33 +1474,27 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1469 if (!(dev->driver->driver_features & DRIVER_GEM)) 1474 if (!(dev->driver->driver_features & DRIVER_GEM))
1470 return -ENODEV; 1475 return -ENODEV;
1471 1476
1472 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1473 if (obj == NULL)
1474 return -ENOENT;
1475
1476 ret = i915_mutex_lock_interruptible(dev); 1477 ret = i915_mutex_lock_interruptible(dev);
1477 if (ret) { 1478 if (ret)
1478 drm_gem_object_unreference_unlocked(obj);
1479 return ret; 1479 return ret;
1480 }
1481 1480
1481 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1482 if (obj == NULL) {
1483 ret = -ENOENT;
1484 goto unlock;
1485 }
1482 obj_priv = to_intel_bo(obj); 1486 obj_priv = to_intel_bo(obj);
1483 1487
1484 if (obj_priv->madv != I915_MADV_WILLNEED) { 1488 if (obj_priv->madv != I915_MADV_WILLNEED) {
1485 DRM_ERROR("Attempting to mmap a purgeable buffer\n"); 1489 DRM_ERROR("Attempting to mmap a purgeable buffer\n");
1486 drm_gem_object_unreference(obj); 1490 ret = -EINVAL;
1487 mutex_unlock(&dev->struct_mutex); 1491 goto out;
1488 return -EINVAL;
1489 } 1492 }
1490 1493
1491
1492 if (!obj_priv->mmap_offset) { 1494 if (!obj_priv->mmap_offset) {
1493 ret = i915_gem_create_mmap_offset(obj); 1495 ret = i915_gem_create_mmap_offset(obj);
1494 if (ret) { 1496 if (ret)
1495 drm_gem_object_unreference(obj); 1497 goto out;
1496 mutex_unlock(&dev->struct_mutex);
1497 return ret;
1498 }
1499 } 1498 }
1500 1499
1501 args->offset = obj_priv->mmap_offset; 1500 args->offset = obj_priv->mmap_offset;
@@ -1506,17 +1505,15 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1506 */ 1505 */
1507 if (!obj_priv->agp_mem) { 1506 if (!obj_priv->agp_mem) {
1508 ret = i915_gem_object_bind_to_gtt(obj, 0); 1507 ret = i915_gem_object_bind_to_gtt(obj, 0);
1509 if (ret) { 1508 if (ret)
1510 drm_gem_object_unreference(obj); 1509 goto out;
1511 mutex_unlock(&dev->struct_mutex);
1512 return ret;
1513 }
1514 } 1510 }
1515 1511
1512out:
1516 drm_gem_object_unreference(obj); 1513 drm_gem_object_unreference(obj);
1514unlock:
1517 mutex_unlock(&dev->struct_mutex); 1515 mutex_unlock(&dev->struct_mutex);
1518 1516 return ret;
1519 return 0;
1520} 1517}
1521 1518
1522static void 1519static void
@@ -4100,44 +4097,36 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
4100 struct drm_i915_gem_object *obj_priv; 4097 struct drm_i915_gem_object *obj_priv;
4101 int ret; 4098 int ret;
4102 4099
4100 ret = i915_mutex_lock_interruptible(dev);
4101 if (ret)
4102 return ret;
4103
4103 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4104 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4104 if (obj == NULL) { 4105 if (obj == NULL) {
4105 DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n", 4106 ret = -ENOENT;
4106 args->handle); 4107 goto unlock;
4107 return -ENOENT;
4108 } 4108 }
4109 obj_priv = to_intel_bo(obj); 4109 obj_priv = to_intel_bo(obj);
4110 4110
4111 ret = i915_mutex_lock_interruptible(dev);
4112 if (ret) {
4113 drm_gem_object_unreference_unlocked(obj);
4114 return ret;
4115 }
4116
4117 if (obj_priv->madv != I915_MADV_WILLNEED) { 4111 if (obj_priv->madv != I915_MADV_WILLNEED) {
4118 DRM_ERROR("Attempting to pin a purgeable buffer\n"); 4112 DRM_ERROR("Attempting to pin a purgeable buffer\n");
4119 drm_gem_object_unreference(obj); 4113 ret = -EINVAL;
4120 mutex_unlock(&dev->struct_mutex); 4114 goto out;
4121 return -EINVAL;
4122 } 4115 }
4123 4116
4124 if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { 4117 if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
4125 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", 4118 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
4126 args->handle); 4119 args->handle);
4127 drm_gem_object_unreference(obj); 4120 ret = -EINVAL;
4128 mutex_unlock(&dev->struct_mutex); 4121 goto out;
4129 return -EINVAL;
4130 } 4122 }
4131 4123
4132 obj_priv->user_pin_count++; 4124 obj_priv->user_pin_count++;
4133 obj_priv->pin_filp = file_priv; 4125 obj_priv->pin_filp = file_priv;
4134 if (obj_priv->user_pin_count == 1) { 4126 if (obj_priv->user_pin_count == 1) {
4135 ret = i915_gem_object_pin(obj, args->alignment); 4127 ret = i915_gem_object_pin(obj, args->alignment);
4136 if (ret != 0) { 4128 if (ret)
4137 drm_gem_object_unreference(obj); 4129 goto out;
4138 mutex_unlock(&dev->struct_mutex);
4139 return ret;
4140 }
4141 } 4130 }
4142 4131
4143 /* XXX - flush the CPU caches for pinned objects 4132 /* XXX - flush the CPU caches for pinned objects
@@ -4145,10 +4134,11 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
4145 */ 4134 */
4146 i915_gem_object_flush_cpu_write_domain(obj); 4135 i915_gem_object_flush_cpu_write_domain(obj);
4147 args->offset = obj_priv->gtt_offset; 4136 args->offset = obj_priv->gtt_offset;
4137out:
4148 drm_gem_object_unreference(obj); 4138 drm_gem_object_unreference(obj);
4139unlock:
4149 mutex_unlock(&dev->struct_mutex); 4140 mutex_unlock(&dev->struct_mutex);
4150 4141 return ret;
4151 return 0;
4152} 4142}
4153 4143
4154int 4144int
@@ -4160,27 +4150,22 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
4160 struct drm_i915_gem_object *obj_priv; 4150 struct drm_i915_gem_object *obj_priv;
4161 int ret; 4151 int ret;
4162 4152
4153 ret = i915_mutex_lock_interruptible(dev);
4154 if (ret)
4155 return ret;
4156
4163 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4157 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4164 if (obj == NULL) { 4158 if (obj == NULL) {
4165 DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n", 4159 ret = -ENOENT;
4166 args->handle); 4160 goto unlock;
4167 return -ENOENT;
4168 } 4161 }
4169
4170 obj_priv = to_intel_bo(obj); 4162 obj_priv = to_intel_bo(obj);
4171 4163
4172 ret = i915_mutex_lock_interruptible(dev);
4173 if (ret) {
4174 drm_gem_object_unreference_unlocked(obj);
4175 return ret;
4176 }
4177
4178 if (obj_priv->pin_filp != file_priv) { 4164 if (obj_priv->pin_filp != file_priv) {
4179 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", 4165 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
4180 args->handle); 4166 args->handle);
4181 drm_gem_object_unreference(obj); 4167 ret = -EINVAL;
4182 mutex_unlock(&dev->struct_mutex); 4168 goto out;
4183 return -EINVAL;
4184 } 4169 }
4185 obj_priv->user_pin_count--; 4170 obj_priv->user_pin_count--;
4186 if (obj_priv->user_pin_count == 0) { 4171 if (obj_priv->user_pin_count == 0) {
@@ -4188,9 +4173,11 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
4188 i915_gem_object_unpin(obj); 4173 i915_gem_object_unpin(obj);
4189 } 4174 }
4190 4175
4176out:
4191 drm_gem_object_unreference(obj); 4177 drm_gem_object_unreference(obj);
4178unlock:
4192 mutex_unlock(&dev->struct_mutex); 4179 mutex_unlock(&dev->struct_mutex);
4193 return 0; 4180 return ret;
4194} 4181}
4195 4182
4196int 4183int
@@ -4202,25 +4189,22 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4202 struct drm_i915_gem_object *obj_priv; 4189 struct drm_i915_gem_object *obj_priv;
4203 int ret; 4190 int ret;
4204 4191
4205 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4206 if (obj == NULL) {
4207 DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
4208 args->handle);
4209 return -ENOENT;
4210 }
4211
4212 ret = i915_mutex_lock_interruptible(dev); 4192 ret = i915_mutex_lock_interruptible(dev);
4213 if (ret) { 4193 if (ret)
4214 drm_gem_object_unreference_unlocked(obj);
4215 return ret; 4194 return ret;
4195
4196 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4197 if (obj == NULL) {
4198 ret = -ENOENT;
4199 goto unlock;
4216 } 4200 }
4201 obj_priv = to_intel_bo(obj);
4217 4202
4218 /* Count all active objects as busy, even if they are currently not used 4203 /* Count all active objects as busy, even if they are currently not used
4219 * by the gpu. Users of this interface expect objects to eventually 4204 * by the gpu. Users of this interface expect objects to eventually
4220 * become non-busy without any further actions, therefore emit any 4205 * become non-busy without any further actions, therefore emit any
4221 * necessary flushes here. 4206 * necessary flushes here.
4222 */ 4207 */
4223 obj_priv = to_intel_bo(obj);
4224 args->busy = obj_priv->active; 4208 args->busy = obj_priv->active;
4225 if (args->busy) { 4209 if (args->busy) {
4226 /* Unconditionally flush objects, even when the gpu still uses this 4210 /* Unconditionally flush objects, even when the gpu still uses this
@@ -4244,8 +4228,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
4244 } 4228 }
4245 4229
4246 drm_gem_object_unreference(obj); 4230 drm_gem_object_unreference(obj);
4231unlock:
4247 mutex_unlock(&dev->struct_mutex); 4232 mutex_unlock(&dev->struct_mutex);
4248 return 0; 4233 return ret;
4249} 4234}
4250 4235
4251int 4236int
@@ -4272,26 +4257,20 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
4272 return -EINVAL; 4257 return -EINVAL;
4273 } 4258 }
4274 4259
4260 ret = i915_mutex_lock_interruptible(dev);
4261 if (ret)
4262 return ret;
4263
4275 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 4264 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4276 if (obj == NULL) { 4265 if (obj == NULL) {
4277 DRM_ERROR("Bad handle in i915_gem_madvise_ioctl(): %d\n", 4266 ret = -ENOENT;
4278 args->handle); 4267 goto unlock;
4279 return -ENOENT;
4280 } 4268 }
4281 obj_priv = to_intel_bo(obj); 4269 obj_priv = to_intel_bo(obj);
4282 4270
4283 ret = i915_mutex_lock_interruptible(dev);
4284 if (ret) {
4285 drm_gem_object_unreference_unlocked(obj);
4286 return ret;
4287 }
4288
4289 if (obj_priv->pin_count) { 4271 if (obj_priv->pin_count) {
4290 drm_gem_object_unreference(obj); 4272 ret = -EINVAL;
4291 mutex_unlock(&dev->struct_mutex); 4273 goto out;
4292
4293 DRM_ERROR("Attempted i915_gem_madvise_ioctl() on a pinned object\n");
4294 return -EINVAL;
4295 } 4274 }
4296 4275
4297 if (obj_priv->madv != __I915_MADV_PURGED) 4276 if (obj_priv->madv != __I915_MADV_PURGED)
@@ -4304,10 +4283,11 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
4304 4283
4305 args->retained = obj_priv->madv != __I915_MADV_PURGED; 4284 args->retained = obj_priv->madv != __I915_MADV_PURGED;
4306 4285
4286out:
4307 drm_gem_object_unreference(obj); 4287 drm_gem_object_unreference(obj);
4288unlock:
4308 mutex_unlock(&dev->struct_mutex); 4289 mutex_unlock(&dev->struct_mutex);
4309 4290 return ret;
4310 return 0;
4311} 4291}
4312 4292
4313struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, 4293struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,