aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c86
1 files changed, 60 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c0ae6bbbd9b..fd2b8bdffe3 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -46,7 +46,6 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o
46static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); 46static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
47static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, 47static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
48 unsigned alignment); 48 unsigned alignment);
49static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write);
50static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 49static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
51static int i915_gem_evict_something(struct drm_device *dev); 50static int i915_gem_evict_something(struct drm_device *dev);
52static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 51static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
@@ -1158,7 +1157,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1158 /* Need a new fence register? */ 1157 /* Need a new fence register? */
1159 if (obj_priv->fence_reg == I915_FENCE_REG_NONE && 1158 if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
1160 obj_priv->tiling_mode != I915_TILING_NONE) { 1159 obj_priv->tiling_mode != I915_TILING_NONE) {
1161 ret = i915_gem_object_get_fence_reg(obj, write); 1160 ret = i915_gem_object_get_fence_reg(obj);
1162 if (ret) { 1161 if (ret) {
1163 mutex_unlock(&dev->struct_mutex); 1162 mutex_unlock(&dev->struct_mutex);
1164 return VM_FAULT_SIGBUS; 1163 return VM_FAULT_SIGBUS;
@@ -1208,8 +1207,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
1208 1207
1209 /* Set the object up for mmap'ing */ 1208 /* Set the object up for mmap'ing */
1210 list = &obj->map_list; 1209 list = &obj->map_list;
1211 list->map = drm_calloc(1, sizeof(struct drm_map_list), 1210 list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
1212 DRM_MEM_DRIVER);
1213 if (!list->map) 1211 if (!list->map)
1214 return -ENOMEM; 1212 return -ENOMEM;
1215 1213
@@ -1249,7 +1247,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
1249out_free_mm: 1247out_free_mm:
1250 drm_mm_put_block(list->file_offset_node); 1248 drm_mm_put_block(list->file_offset_node);
1251out_free_list: 1249out_free_list:
1252 drm_free(list->map, sizeof(struct drm_map_list), DRM_MEM_DRIVER); 1250 kfree(list->map);
1253 1251
1254 return ret; 1252 return ret;
1255} 1253}
@@ -1271,7 +1269,7 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj)
1271 } 1269 }
1272 1270
1273 if (list->map) { 1271 if (list->map) {
1274 drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER); 1272 kfree(list->map);
1275 list->map = NULL; 1273 list->map = NULL;
1276 } 1274 }
1277 1275
@@ -1494,7 +1492,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1494 if (file_priv != NULL) 1492 if (file_priv != NULL)
1495 i915_file_priv = file_priv->driver_priv; 1493 i915_file_priv = file_priv->driver_priv;
1496 1494
1497 request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER); 1495 request = kzalloc(sizeof(*request), GFP_KERNEL);
1498 if (request == NULL) 1496 if (request == NULL)
1499 return 0; 1497 return 0;
1500 1498
@@ -1676,7 +1674,7 @@ i915_gem_retire_requests(struct drm_device *dev)
1676 1674
1677 list_del(&request->list); 1675 list_del(&request->list);
1678 list_del(&request->client_list); 1676 list_del(&request->client_list);
1679 drm_free(request, sizeof(*request), DRM_MEM_DRIVER); 1677 kfree(request);
1680 } else 1678 } else
1681 break; 1679 break;
1682 } 1680 }
@@ -2163,13 +2161,11 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
2163 val |= I830_FENCE_REG_VALID; 2161 val |= I830_FENCE_REG_VALID;
2164 2162
2165 I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); 2163 I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
2166
2167} 2164}
2168 2165
2169/** 2166/**
2170 * i915_gem_object_get_fence_reg - set up a fence reg for an object 2167 * i915_gem_object_get_fence_reg - set up a fence reg for an object
2171 * @obj: object to map through a fence reg 2168 * @obj: object to map through a fence reg
2172 * @write: object is about to be written
2173 * 2169 *
2174 * When mapping objects through the GTT, userspace wants to be able to write 2170 * When mapping objects through the GTT, userspace wants to be able to write
2175 * to them without having to worry about swizzling if the object is tiled. 2171 * to them without having to worry about swizzling if the object is tiled.
@@ -2180,8 +2176,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
2180 * It then sets up the reg based on the object's properties: address, pitch 2176 * It then sets up the reg based on the object's properties: address, pitch
2181 * and tiling format. 2177 * and tiling format.
2182 */ 2178 */
2183static int 2179int
2184i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) 2180i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
2185{ 2181{
2186 struct drm_device *dev = obj->dev; 2182 struct drm_device *dev = obj->dev;
2187 struct drm_i915_private *dev_priv = dev->dev_private; 2183 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2331,6 +2327,42 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
2331} 2327}
2332 2328
2333/** 2329/**
2330 * i915_gem_object_put_fence_reg - waits on outstanding fenced access
2331 * to the buffer to finish, and then resets the fence register.
2332 * @obj: tiled object holding a fence register.
2333 *
2334 * Zeroes out the fence register itself and clears out the associated
2335 * data structures in dev_priv and obj_priv.
2336 */
2337int
2338i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
2339{
2340 struct drm_device *dev = obj->dev;
2341 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2342
2343 if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
2344 return 0;
2345
2346 /* On the i915, GPU access to tiled buffers is via a fence,
2347 * therefore we must wait for any outstanding access to complete
2348 * before clearing the fence.
2349 */
2350 if (!IS_I965G(dev)) {
2351 int ret;
2352
2353 i915_gem_object_flush_gpu_write_domain(obj);
2354 i915_gem_object_flush_gtt_write_domain(obj);
2355 ret = i915_gem_object_wait_rendering(obj);
2356 if (ret != 0)
2357 return ret;
2358 }
2359
2360 i915_gem_clear_fence_reg (obj);
2361
2362 return 0;
2363}
2364
2365/**
2334 * Finds free space in the GTT aperture and binds the object there. 2366 * Finds free space in the GTT aperture and binds the object there.
2335 */ 2367 */
2336static int 2368static int
@@ -2800,8 +2832,7 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
2800 /* Free the page_cpu_valid mappings which are now stale, whether 2832 /* Free the page_cpu_valid mappings which are now stale, whether
2801 * or not we've got I915_GEM_DOMAIN_CPU. 2833 * or not we've got I915_GEM_DOMAIN_CPU.
2802 */ 2834 */
2803 drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, 2835 kfree(obj_priv->page_cpu_valid);
2804 DRM_MEM_DRIVER);
2805 obj_priv->page_cpu_valid = NULL; 2836 obj_priv->page_cpu_valid = NULL;
2806} 2837}
2807 2838
@@ -2843,8 +2874,8 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
2843 * newly adding I915_GEM_DOMAIN_CPU 2874 * newly adding I915_GEM_DOMAIN_CPU
2844 */ 2875 */
2845 if (obj_priv->page_cpu_valid == NULL) { 2876 if (obj_priv->page_cpu_valid == NULL) {
2846 obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, 2877 obj_priv->page_cpu_valid = kzalloc(obj->size / PAGE_SIZE,
2847 DRM_MEM_DRIVER); 2878 GFP_KERNEL);
2848 if (obj_priv->page_cpu_valid == NULL) 2879 if (obj_priv->page_cpu_valid == NULL)
2849 return -ENOMEM; 2880 return -ENOMEM;
2850 } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) 2881 } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0)
@@ -3267,8 +3298,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
3267 } 3298 }
3268 3299
3269 if (args->num_cliprects != 0) { 3300 if (args->num_cliprects != 0) {
3270 cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects), 3301 cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects),
3271 DRM_MEM_DRIVER); 3302 GFP_KERNEL);
3272 if (cliprects == NULL) 3303 if (cliprects == NULL)
3273 goto pre_mutex_err; 3304 goto pre_mutex_err;
3274 3305
@@ -3521,8 +3552,7 @@ err:
3521pre_mutex_err: 3552pre_mutex_err:
3522 drm_free_large(object_list); 3553 drm_free_large(object_list);
3523 drm_free_large(exec_list); 3554 drm_free_large(exec_list);
3524 drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects, 3555 kfree(cliprects);
3525 DRM_MEM_DRIVER);
3526 3556
3527 return ret; 3557 return ret;
3528} 3558}
@@ -3550,7 +3580,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3550 if (!IS_I965G(dev) && 3580 if (!IS_I965G(dev) &&
3551 obj_priv->fence_reg == I915_FENCE_REG_NONE && 3581 obj_priv->fence_reg == I915_FENCE_REG_NONE &&
3552 obj_priv->tiling_mode != I915_TILING_NONE) { 3582 obj_priv->tiling_mode != I915_TILING_NONE) {
3553 ret = i915_gem_object_get_fence_reg(obj, true); 3583 ret = i915_gem_object_get_fence_reg(obj);
3554 if (ret != 0) { 3584 if (ret != 0) {
3555 if (ret != -EBUSY && ret != -ERESTARTSYS) 3585 if (ret != -EBUSY && ret != -ERESTARTSYS)
3556 DRM_ERROR("Failure to install fence: %d\n", 3586 DRM_ERROR("Failure to install fence: %d\n",
@@ -3739,7 +3769,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
3739{ 3769{
3740 struct drm_i915_gem_object *obj_priv; 3770 struct drm_i915_gem_object *obj_priv;
3741 3771
3742 obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER); 3772 obj_priv = kzalloc(sizeof(*obj_priv), GFP_KERNEL);
3743 if (obj_priv == NULL) 3773 if (obj_priv == NULL)
3744 return -ENOMEM; 3774 return -ENOMEM;
3745 3775
@@ -3777,9 +3807,9 @@ void i915_gem_free_object(struct drm_gem_object *obj)
3777 3807
3778 i915_gem_free_mmap_offset(obj); 3808 i915_gem_free_mmap_offset(obj);
3779 3809
3780 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); 3810 kfree(obj_priv->page_cpu_valid);
3781 kfree(obj_priv->bit_17); 3811 kfree(obj_priv->bit_17);
3782 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); 3812 kfree(obj->driver_private);
3783} 3813}
3784 3814
3785/** Unbinds all objects that are on the given buffer list. */ 3815/** Unbinds all objects that are on the given buffer list. */
@@ -4233,7 +4263,7 @@ int i915_gem_init_phys_object(struct drm_device *dev,
4233 if (dev_priv->mm.phys_objs[id - 1] || !size) 4263 if (dev_priv->mm.phys_objs[id - 1] || !size)
4234 return 0; 4264 return 0;
4235 4265
4236 phys_obj = drm_calloc(1, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); 4266 phys_obj = kzalloc(sizeof(struct drm_i915_gem_phys_object), GFP_KERNEL);
4237 if (!phys_obj) 4267 if (!phys_obj)
4238 return -ENOMEM; 4268 return -ENOMEM;
4239 4269
@@ -4252,7 +4282,7 @@ int i915_gem_init_phys_object(struct drm_device *dev,
4252 4282
4253 return 0; 4283 return 0;
4254kfree_obj: 4284kfree_obj:
4255 drm_free(phys_obj, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); 4285 kfree(phys_obj);
4256 return ret; 4286 return ret;
4257} 4287}
4258 4288
@@ -4312,6 +4342,8 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
4312 } 4342 }
4313 drm_clflush_pages(obj_priv->pages, page_count); 4343 drm_clflush_pages(obj_priv->pages, page_count);
4314 drm_agp_chipset_flush(dev); 4344 drm_agp_chipset_flush(dev);
4345
4346 i915_gem_object_put_pages(obj);
4315out: 4347out:
4316 obj_priv->phys_obj->cur_obj = NULL; 4348 obj_priv->phys_obj->cur_obj = NULL;
4317 obj_priv->phys_obj = NULL; 4349 obj_priv->phys_obj = NULL;
@@ -4369,6 +4401,8 @@ i915_gem_attach_phys_object(struct drm_device *dev,
4369 kunmap_atomic(src, KM_USER0); 4401 kunmap_atomic(src, KM_USER0);
4370 } 4402 }
4371 4403
4404 i915_gem_object_put_pages(obj);
4405
4372 return 0; 4406 return 0;
4373out: 4407out:
4374 return ret; 4408 return ret;