aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-11 10:41:04 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-08-23 20:03:33 -0400
commit86a1ee26bb60e1ab8984e92f0e9186c354670aed (patch)
treed8eb2c95987bdf4c1fa6ef3998615eeee88ced08 /drivers
parent53621860c38caff37fff99ba5f0b817511907bc4 (diff)
drm/i915: Only pwrite through the GTT if there is space in the aperture
Avoid stalling and waiting for the GPU by checking to see if there is sufficient inactive space in the aperture for us to bind the buffer prior to writing through the GTT. If there is inadequate space we will have to stall waiting for the GPU, and incur overheads moving objects about. Instead, only incur the clflush overhead on the target object by writing through shmem. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c29
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c6
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c6
8 files changed, 33 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cbd3cd0747b9..06a88be067f1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1307,7 +1307,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
1307void i915_gem_free_object(struct drm_gem_object *obj); 1307void i915_gem_free_object(struct drm_gem_object *obj);
1308int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, 1308int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
1309 uint32_t alignment, 1309 uint32_t alignment,
1310 bool map_and_fenceable); 1310 bool map_and_fenceable,
1311 bool nonblocking);
1311void i915_gem_object_unpin(struct drm_i915_gem_object *obj); 1312void i915_gem_object_unpin(struct drm_i915_gem_object *obj);
1312int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); 1313int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj);
1313void i915_gem_release_mmap(struct drm_i915_gem_object *obj); 1314void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
@@ -1454,7 +1455,8 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
1454int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size, 1455int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
1455 unsigned alignment, 1456 unsigned alignment,
1456 unsigned cache_level, 1457 unsigned cache_level,
1457 bool mappable); 1458 bool mappable,
1459 bool nonblock);
1458int i915_gem_evict_everything(struct drm_device *dev); 1460int i915_gem_evict_everything(struct drm_device *dev);
1459 1461
1460/* i915_gem_stolen.c */ 1462/* i915_gem_stolen.c */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e1ec587c42c8..1ec5f7ef2cc2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -41,7 +41,8 @@ static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *o
41static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); 41static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
42static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, 42static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
43 unsigned alignment, 43 unsigned alignment,
44 bool map_and_fenceable); 44 bool map_and_fenceable,
45 bool nonblocking);
45static int i915_gem_phys_pwrite(struct drm_device *dev, 46static int i915_gem_phys_pwrite(struct drm_device *dev,
46 struct drm_i915_gem_object *obj, 47 struct drm_i915_gem_object *obj,
47 struct drm_i915_gem_pwrite *args, 48 struct drm_i915_gem_pwrite *args,
@@ -609,7 +610,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
609 char __user *user_data; 610 char __user *user_data;
610 int page_offset, page_length, ret; 611 int page_offset, page_length, ret;
611 612
612 ret = i915_gem_object_pin(obj, 0, true); 613 ret = i915_gem_object_pin(obj, 0, true, true);
613 if (ret) 614 if (ret)
614 goto out; 615 goto out;
615 616
@@ -925,10 +926,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
925 goto out; 926 goto out;
926 } 927 }
927 928
928 if (obj->gtt_space && 929 if (obj->cache_level == I915_CACHE_NONE &&
929 obj->cache_level == I915_CACHE_NONE &&
930 obj->tiling_mode == I915_TILING_NONE && 930 obj->tiling_mode == I915_TILING_NONE &&
931 obj->map_and_fenceable &&
932 obj->base.write_domain != I915_GEM_DOMAIN_CPU) { 931 obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
933 ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file); 932 ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file);
934 /* Note that the gtt paths might fail with non-page-backed user 933 /* Note that the gtt paths might fail with non-page-backed user
@@ -936,7 +935,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
936 * textures). Fallback to the shmem path in that case. */ 935 * textures). Fallback to the shmem path in that case. */
937 } 936 }
938 937
939 if (ret == -EFAULT) 938 if (ret == -EFAULT || ret == -ENOSPC)
940 ret = i915_gem_shmem_pwrite(dev, obj, args, file); 939 ret = i915_gem_shmem_pwrite(dev, obj, args, file);
941 940
942out: 941out:
@@ -1115,7 +1114,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1115 goto unlock; 1114 goto unlock;
1116 } 1115 }
1117 if (!obj->gtt_space) { 1116 if (!obj->gtt_space) {
1118 ret = i915_gem_object_bind_to_gtt(obj, 0, true); 1117 ret = i915_gem_object_bind_to_gtt(obj, 0, true, false);
1119 if (ret) 1118 if (ret)
1120 goto unlock; 1119 goto unlock;
1121 1120
@@ -2772,7 +2771,8 @@ static void i915_gem_verify_gtt(struct drm_device *dev)
2772static int 2771static int
2773i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, 2772i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
2774 unsigned alignment, 2773 unsigned alignment,
2775 bool map_and_fenceable) 2774 bool map_and_fenceable,
2775 bool nonblocking)
2776{ 2776{
2777 struct drm_device *dev = obj->base.dev; 2777 struct drm_device *dev = obj->base.dev;
2778 drm_i915_private_t *dev_priv = dev->dev_private; 2778 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2848,7 +2848,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
2848 if (obj->gtt_space == NULL) { 2848 if (obj->gtt_space == NULL) {
2849 ret = i915_gem_evict_something(dev, size, alignment, 2849 ret = i915_gem_evict_something(dev, size, alignment,
2850 obj->cache_level, 2850 obj->cache_level,
2851 map_and_fenceable); 2851 map_and_fenceable,
2852 nonblocking);
2852 if (ret) 2853 if (ret)
2853 return ret; 2854 return ret;
2854 2855
@@ -3188,7 +3189,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
3188 * (e.g. libkms for the bootup splash), we have to ensure that we 3189 * (e.g. libkms for the bootup splash), we have to ensure that we
3189 * always use map_and_fenceable for all scanout buffers. 3190 * always use map_and_fenceable for all scanout buffers.
3190 */ 3191 */
3191 ret = i915_gem_object_pin(obj, alignment, true); 3192 ret = i915_gem_object_pin(obj, alignment, true, false);
3192 if (ret) 3193 if (ret)
3193 return ret; 3194 return ret;
3194 3195
@@ -3325,7 +3326,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
3325int 3326int
3326i915_gem_object_pin(struct drm_i915_gem_object *obj, 3327i915_gem_object_pin(struct drm_i915_gem_object *obj,
3327 uint32_t alignment, 3328 uint32_t alignment,
3328 bool map_and_fenceable) 3329 bool map_and_fenceable,
3330 bool nonblocking)
3329{ 3331{
3330 int ret; 3332 int ret;
3331 3333
@@ -3349,7 +3351,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
3349 3351
3350 if (obj->gtt_space == NULL) { 3352 if (obj->gtt_space == NULL) {
3351 ret = i915_gem_object_bind_to_gtt(obj, alignment, 3353 ret = i915_gem_object_bind_to_gtt(obj, alignment,
3352 map_and_fenceable); 3354 map_and_fenceable,
3355 nonblocking);
3353 if (ret) 3356 if (ret)
3354 return ret; 3357 return ret;
3355 } 3358 }
@@ -3407,7 +3410,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3407 obj->user_pin_count++; 3410 obj->user_pin_count++;
3408 obj->pin_filp = file; 3411 obj->pin_filp = file;
3409 if (obj->user_pin_count == 1) { 3412 if (obj->user_pin_count == 1) {
3410 ret = i915_gem_object_pin(obj, args->alignment, true); 3413 ret = i915_gem_object_pin(obj, args->alignment, true, false);
3411 if (ret) 3414 if (ret)
3412 goto out; 3415 goto out;
3413 } 3416 }
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5c2d354cebbd..4aa7ecf77ede 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -221,7 +221,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
221 * default context. 221 * default context.
222 */ 222 */
223 dev_priv->ring[RCS].default_context = ctx; 223 dev_priv->ring[RCS].default_context = ctx;
224 ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false); 224 ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false);
225 if (ret) 225 if (ret)
226 goto err_destroy; 226 goto err_destroy;
227 227
@@ -374,7 +374,7 @@ static int do_switch(struct i915_hw_context *to)
374 if (from_obj == to->obj) 374 if (from_obj == to->obj)
375 return 0; 375 return 0;
376 376
377 ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false); 377 ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false);
378 if (ret) 378 if (ret)
379 return ret; 379 return ret;
380 380
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 74635da7c498..a2d8acde8550 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -45,7 +45,7 @@ mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
45int 45int
46i915_gem_evict_something(struct drm_device *dev, int min_size, 46i915_gem_evict_something(struct drm_device *dev, int min_size,
47 unsigned alignment, unsigned cache_level, 47 unsigned alignment, unsigned cache_level,
48 bool mappable) 48 bool mappable, bool nonblocking)
49{ 49{
50 drm_i915_private_t *dev_priv = dev->dev_private; 50 drm_i915_private_t *dev_priv = dev->dev_private;
51 struct list_head eviction_list, unwind_list; 51 struct list_head eviction_list, unwind_list;
@@ -92,12 +92,16 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
92 goto found; 92 goto found;
93 } 93 }
94 94
95 if (nonblocking)
96 goto none;
97
95 /* Now merge in the soon-to-be-expired objects... */ 98 /* Now merge in the soon-to-be-expired objects... */
96 list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { 99 list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
97 if (mark_free(obj, &unwind_list)) 100 if (mark_free(obj, &unwind_list))
98 goto found; 101 goto found;
99 } 102 }
100 103
104none:
101 /* Nothing found, clean up and bail out! */ 105 /* Nothing found, clean up and bail out! */
102 while (!list_empty(&unwind_list)) { 106 while (!list_empty(&unwind_list)) {
103 obj = list_first_entry(&unwind_list, 107 obj = list_first_entry(&unwind_list,
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 834a636b44f0..f7346d876551 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -354,7 +354,7 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
354 obj->tiling_mode != I915_TILING_NONE; 354 obj->tiling_mode != I915_TILING_NONE;
355 need_mappable = need_fence || need_reloc_mappable(obj); 355 need_mappable = need_fence || need_reloc_mappable(obj);
356 356
357 ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); 357 ret = i915_gem_object_pin(obj, entry->alignment, need_mappable, false);
358 if (ret) 358 if (ret)
359 return ret; 359 return ret;
360 360
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index c0f48580405a..afd0f30ab882 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1383,7 +1383,7 @@ void intel_setup_overlay(struct drm_device *dev)
1383 } 1383 }
1384 overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; 1384 overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
1385 } else { 1385 } else {
1386 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); 1386 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false);
1387 if (ret) { 1387 if (ret) {
1388 DRM_ERROR("failed to pin overlay register bo\n"); 1388 DRM_ERROR("failed to pin overlay register bo\n");
1389 goto out_free_bo; 1389 goto out_free_bo;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c0407aa5baac..c0721ffb56a2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2138,7 +2138,7 @@ intel_alloc_context_page(struct drm_device *dev)
2138 return NULL; 2138 return NULL;
2139 } 2139 }
2140 2140
2141 ret = i915_gem_object_pin(ctx, 4096, true); 2141 ret = i915_gem_object_pin(ctx, 4096, true, false);
2142 if (ret) { 2142 if (ret) {
2143 DRM_ERROR("failed to pin power context: %d\n", ret); 2143 DRM_ERROR("failed to pin power context: %d\n", ret);
2144 goto err_unref; 2144 goto err_unref;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index c828169c73ae..ac93643731aa 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -391,7 +391,7 @@ init_pipe_control(struct intel_ring_buffer *ring)
391 391
392 i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); 392 i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
393 393
394 ret = i915_gem_object_pin(obj, 4096, true); 394 ret = i915_gem_object_pin(obj, 4096, true, false);
395 if (ret) 395 if (ret)
396 goto err_unref; 396 goto err_unref;
397 397
@@ -979,7 +979,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
979 979
980 i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); 980 i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
981 981
982 ret = i915_gem_object_pin(obj, 4096, true); 982 ret = i915_gem_object_pin(obj, 4096, true, false);
983 if (ret != 0) { 983 if (ret != 0) {
984 goto err_unref; 984 goto err_unref;
985 } 985 }
@@ -1036,7 +1036,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1036 1036
1037 ring->obj = obj; 1037 ring->obj = obj;
1038 1038
1039 ret = i915_gem_object_pin(obj, PAGE_SIZE, true); 1039 ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false);
1040 if (ret) 1040 if (ret)
1041 goto err_unref; 1041 goto err_unref;
1042 1042