aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2010-09-16 11:54:23 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-27 18:31:05 -0400
commit920afa77ced7124c8bb7d0c4839885618a3b4a54 (patch)
tree849a91385768a4050df8d605c52a81ea2c255cda
parenta6e0aa421406dc4cfd736c6d07d26ed39ab4f7bc (diff)
drm/i915: range-restricted bind_to_gtt
Like before add a parameter mappable (also to gem_object_pin) and set it depending upon the context. Only bos that are brought into the gtt due to an execbuffer call can be put into the unmappable part of the gtt, everything else (especially pinned objects) need to be put into the mappable part of the gtt. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c63
-rw-r--r--drivers/gpu/drm/i915/intel_display.c6
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c4
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c4
5 files changed, 53 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dc0a21a3489b..263bb0506247 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1012,7 +1012,8 @@ int i915_gem_init_object(struct drm_gem_object *obj);
1012struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, 1012struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev,
1013 size_t size); 1013 size_t size);
1014void i915_gem_free_object(struct drm_gem_object *obj); 1014void i915_gem_free_object(struct drm_gem_object *obj);
1015int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); 1015int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
1016 bool mappable);
1016void i915_gem_object_unpin(struct drm_gem_object *obj); 1017void i915_gem_object_unpin(struct drm_gem_object *obj);
1017int i915_gem_object_unbind(struct drm_gem_object *obj); 1018int i915_gem_object_unbind(struct drm_gem_object *obj);
1018void i915_gem_release_mmap(struct drm_gem_object *obj); 1019void i915_gem_release_mmap(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 254eb0c46aeb..ef14546fc08d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -51,7 +51,7 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o
51static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, 51static int i915_gem_object_wait_rendering(struct drm_gem_object *obj,
52 bool interruptible); 52 bool interruptible);
53static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, 53static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
54 unsigned alignment); 54 unsigned alignment, bool mappable);
55static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 55static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
56static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 56static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
57 struct drm_i915_gem_pwrite *args, 57 struct drm_i915_gem_pwrite *args,
@@ -1031,7 +1031,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1031 else if (obj_priv->tiling_mode == I915_TILING_NONE && 1031 else if (obj_priv->tiling_mode == I915_TILING_NONE &&
1032 obj_priv->gtt_space && 1032 obj_priv->gtt_space &&
1033 obj->write_domain != I915_GEM_DOMAIN_CPU) { 1033 obj->write_domain != I915_GEM_DOMAIN_CPU) {
1034 ret = i915_gem_object_pin(obj, 0); 1034 ret = i915_gem_object_pin(obj, 0, true);
1035 if (ret) 1035 if (ret)
1036 goto out; 1036 goto out;
1037 1037
@@ -1256,7 +1256,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1256 /* Now bind it into the GTT if needed */ 1256 /* Now bind it into the GTT if needed */
1257 mutex_lock(&dev->struct_mutex); 1257 mutex_lock(&dev->struct_mutex);
1258 if (!obj_priv->gtt_space) { 1258 if (!obj_priv->gtt_space) {
1259 ret = i915_gem_object_bind_to_gtt(obj, 0); 1259 ret = i915_gem_object_bind_to_gtt(obj, 0, true);
1260 if (ret) 1260 if (ret)
1261 goto unlock; 1261 goto unlock;
1262 1262
@@ -1506,7 +1506,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1506 * initial fault faster and any subsequent flushing possible). 1506 * initial fault faster and any subsequent flushing possible).
1507 */ 1507 */
1508 if (!obj_priv->agp_mem) { 1508 if (!obj_priv->agp_mem) {
1509 ret = i915_gem_object_bind_to_gtt(obj, 0); 1509 ret = i915_gem_object_bind_to_gtt(obj, 0, true);
1510 if (ret) 1510 if (ret)
1511 goto out; 1511 goto out;
1512 } 1512 }
@@ -2635,7 +2635,9 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
2635 * Finds free space in the GTT aperture and binds the object there. 2635 * Finds free space in the GTT aperture and binds the object there.
2636 */ 2636 */
2637static int 2637static int
2638i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) 2638i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
2639 unsigned alignment,
2640 bool mappable)
2639{ 2641{
2640 struct drm_device *dev = obj->dev; 2642 struct drm_device *dev = obj->dev;
2641 drm_i915_private_t *dev_priv = dev->dev_private; 2643 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2659,22 +2661,42 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2659 /* If the object is bigger than the entire aperture, reject it early 2661 /* If the object is bigger than the entire aperture, reject it early
2660 * before evicting everything in a vain attempt to find space. 2662 * before evicting everything in a vain attempt to find space.
2661 */ 2663 */
2662 if (obj->size > dev_priv->mm.gtt_total) { 2664 if (obj->size >
2665 (mappable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) {
2663 DRM_ERROR("Attempting to bind an object larger than the aperture\n"); 2666 DRM_ERROR("Attempting to bind an object larger than the aperture\n");
2664 return -E2BIG; 2667 return -E2BIG;
2665 } 2668 }
2666 2669
2667 search_free: 2670 search_free:
2668 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, 2671 if (mappable)
2669 obj->size, alignment, 0); 2672 free_space =
2670 if (free_space != NULL) 2673 drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
2671 obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, 2674 obj->size, alignment, 0,
2672 alignment); 2675 dev_priv->mm.gtt_mappable_end,
2676 0);
2677 else
2678 free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2679 obj->size, alignment, 0);
2680
2681 if (free_space != NULL) {
2682 if (mappable)
2683 obj_priv->gtt_space =
2684 drm_mm_get_block_range_generic(free_space,
2685 obj->size,
2686 alignment, 0,
2687 dev_priv->mm.gtt_mappable_end,
2688 0);
2689 else
2690 obj_priv->gtt_space =
2691 drm_mm_get_block(free_space, obj->size,
2692 alignment);
2693 }
2673 if (obj_priv->gtt_space == NULL) { 2694 if (obj_priv->gtt_space == NULL) {
2674 /* If the gtt is empty and we're still having trouble 2695 /* If the gtt is empty and we're still having trouble
2675 * fitting our object in, we're out of memory. 2696 * fitting our object in, we're out of memory.
2676 */ 2697 */
2677 ret = i915_gem_evict_something(dev, obj->size, alignment, true); 2698 ret = i915_gem_evict_something(dev, obj->size, alignment,
2699 mappable);
2678 if (ret) 2700 if (ret)
2679 return ret; 2701 return ret;
2680 2702
@@ -2689,7 +2711,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2689 if (ret == -ENOMEM) { 2711 if (ret == -ENOMEM) {
2690 /* first try to clear up some space from the GTT */ 2712 /* first try to clear up some space from the GTT */
2691 ret = i915_gem_evict_something(dev, obj->size, 2713 ret = i915_gem_evict_something(dev, obj->size,
2692 alignment, true); 2714 alignment, mappable);
2693 if (ret) { 2715 if (ret) {
2694 /* now try to shrink everyone else */ 2716 /* now try to shrink everyone else */
2695 if (gfpmask) { 2717 if (gfpmask) {
@@ -2719,7 +2741,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2719 drm_mm_put_block(obj_priv->gtt_space); 2741 drm_mm_put_block(obj_priv->gtt_space);
2720 obj_priv->gtt_space = NULL; 2742 obj_priv->gtt_space = NULL;
2721 2743
2722 ret = i915_gem_evict_something(dev, obj->size, alignment, true); 2744 ret = i915_gem_evict_something(dev, obj->size, alignment,
2745 mappable);
2723 if (ret) 2746 if (ret)
2724 return ret; 2747 return ret;
2725 2748
@@ -3456,7 +3479,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
3456 break; 3479 break;
3457 } 3480 }
3458 3481
3459 ret = i915_gem_object_pin(&obj->base, entry->alignment); 3482 ret = i915_gem_object_pin(&obj->base,
3483 entry->alignment, true);
3460 if (ret) 3484 if (ret)
3461 break; 3485 break;
3462 3486
@@ -4026,7 +4050,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
4026} 4050}
4027 4051
4028int 4052int
4029i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) 4053i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment,
4054 bool mappable)
4030{ 4055{
4031 struct drm_device *dev = obj->dev; 4056 struct drm_device *dev = obj->dev;
4032 struct drm_i915_private *dev_priv = dev->dev_private; 4057 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4051,7 +4076,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
4051 } 4076 }
4052 4077
4053 if (obj_priv->gtt_space == NULL) { 4078 if (obj_priv->gtt_space == NULL) {
4054 ret = i915_gem_object_bind_to_gtt(obj, alignment); 4079 ret = i915_gem_object_bind_to_gtt(obj, alignment, mappable);
4055 if (ret) 4080 if (ret)
4056 return ret; 4081 return ret;
4057 } 4082 }
@@ -4133,7 +4158,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
4133 obj_priv->user_pin_count++; 4158 obj_priv->user_pin_count++;
4134 obj_priv->pin_filp = file_priv; 4159 obj_priv->pin_filp = file_priv;
4135 if (obj_priv->user_pin_count == 1) { 4160 if (obj_priv->user_pin_count == 1) {
4136 ret = i915_gem_object_pin(obj, args->alignment); 4161 ret = i915_gem_object_pin(obj, args->alignment, true);
4137 if (ret) 4162 if (ret)
4138 goto out; 4163 goto out;
4139 } 4164 }
@@ -4445,7 +4470,7 @@ i915_gem_init_pipe_control(struct drm_device *dev)
4445 obj_priv = to_intel_bo(obj); 4470 obj_priv = to_intel_bo(obj);
4446 obj_priv->agp_type = AGP_USER_CACHED_MEMORY; 4471 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
4447 4472
4448 ret = i915_gem_object_pin(obj, 4096); 4473 ret = i915_gem_object_pin(obj, 4096, true);
4449 if (ret) 4474 if (ret)
4450 goto err_unref; 4475 goto err_unref;
4451 4476
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index eb4c725e3069..c9c4c707cf1a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1461,7 +1461,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
1461 BUG(); 1461 BUG();
1462 } 1462 }
1463 1463
1464 ret = i915_gem_object_pin(obj, alignment); 1464 ret = i915_gem_object_pin(obj, alignment, true);
1465 if (ret) 1465 if (ret)
1466 return ret; 1466 return ret;
1467 1467
@@ -4353,7 +4353,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
4353 /* we only need to pin inside GTT if cursor is non-phy */ 4353 /* we only need to pin inside GTT if cursor is non-phy */
4354 mutex_lock(&dev->struct_mutex); 4354 mutex_lock(&dev->struct_mutex);
4355 if (!dev_priv->info->cursor_needs_physical) { 4355 if (!dev_priv->info->cursor_needs_physical) {
4356 ret = i915_gem_object_pin(bo, PAGE_SIZE); 4356 ret = i915_gem_object_pin(bo, PAGE_SIZE, true);
4357 if (ret) { 4357 if (ret) {
4358 DRM_ERROR("failed to pin cursor bo\n"); 4358 DRM_ERROR("failed to pin cursor bo\n");
4359 goto fail_locked; 4359 goto fail_locked;
@@ -5517,7 +5517,7 @@ intel_alloc_context_page(struct drm_device *dev)
5517 } 5517 }
5518 5518
5519 mutex_lock(&dev->struct_mutex); 5519 mutex_lock(&dev->struct_mutex);
5520 ret = i915_gem_object_pin(ctx, 4096); 5520 ret = i915_gem_object_pin(ctx, 4096, true);
5521 if (ret) { 5521 if (ret) {
5522 DRM_ERROR("failed to pin power context: %d\n", ret); 5522 DRM_ERROR("failed to pin power context: %d\n", ret);
5523 goto err_unref; 5523 goto err_unref;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 2d4a6968cd76..beda2016eb16 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -781,7 +781,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
781 if (ret != 0) 781 if (ret != 0)
782 return ret; 782 return ret;
783 783
784 ret = i915_gem_object_pin(new_bo, PAGE_SIZE); 784 ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true);
785 if (ret != 0) 785 if (ret != 0)
786 return ret; 786 return ret;
787 787
@@ -1423,7 +1423,7 @@ void intel_setup_overlay(struct drm_device *dev)
1423 } 1423 }
1424 overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; 1424 overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
1425 } else { 1425 } else {
1426 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); 1426 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true);
1427 if (ret) { 1427 if (ret) {
1428 DRM_ERROR("failed to pin overlay register bo\n"); 1428 DRM_ERROR("failed to pin overlay register bo\n");
1429 goto out_free_bo; 1429 goto out_free_bo;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 4803b32f308f..8eaa60cc5d25 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -546,7 +546,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
546 obj_priv = to_intel_bo(obj); 546 obj_priv = to_intel_bo(obj);
547 obj_priv->agp_type = AGP_USER_CACHED_MEMORY; 547 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
548 548
549 ret = i915_gem_object_pin(obj, 4096); 549 ret = i915_gem_object_pin(obj, 4096, true);
550 if (ret != 0) { 550 if (ret != 0) {
551 goto err_unref; 551 goto err_unref;
552 } 552 }
@@ -602,7 +602,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
602 602
603 ring->gem_object = obj; 603 ring->gem_object = obj;
604 604
605 ret = i915_gem_object_pin(obj, PAGE_SIZE); 605 ret = i915_gem_object_pin(obj, PAGE_SIZE, true);
606 if (ret) 606 if (ret)
607 goto err_unref; 607 goto err_unref;
608 608