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.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e0389ad1477d..1449b452cc63 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1072,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1072 case -EAGAIN: 1072 case -EAGAIN:
1073 return VM_FAULT_OOM; 1073 return VM_FAULT_OOM;
1074 case -EFAULT: 1074 case -EFAULT:
1075 case -EINVAL:
1075 return VM_FAULT_SIGBUS; 1076 return VM_FAULT_SIGBUS;
1076 default: 1077 default:
1077 return VM_FAULT_NOPAGE; 1078 return VM_FAULT_NOPAGE;
@@ -1324,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
1324 obj_priv->active = 1; 1325 obj_priv->active = 1;
1325 } 1326 }
1326 /* Move from whatever list we were on to the tail of execution. */ 1327 /* Move from whatever list we were on to the tail of execution. */
1328 spin_lock(&dev_priv->mm.active_list_lock);
1327 list_move_tail(&obj_priv->list, 1329 list_move_tail(&obj_priv->list,
1328 &dev_priv->mm.active_list); 1330 &dev_priv->mm.active_list);
1331 spin_unlock(&dev_priv->mm.active_list_lock);
1329 obj_priv->last_rendering_seqno = seqno; 1332 obj_priv->last_rendering_seqno = seqno;
1330} 1333}
1331 1334
@@ -1467,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev,
1467 /* Move any buffers on the active list that are no longer referenced 1470 /* Move any buffers on the active list that are no longer referenced
1468 * by the ringbuffer to the flushing/inactive lists as appropriate. 1471 * by the ringbuffer to the flushing/inactive lists as appropriate.
1469 */ 1472 */
1473 spin_lock(&dev_priv->mm.active_list_lock);
1470 while (!list_empty(&dev_priv->mm.active_list)) { 1474 while (!list_empty(&dev_priv->mm.active_list)) {
1471 struct drm_gem_object *obj; 1475 struct drm_gem_object *obj;
1472 struct drm_i915_gem_object *obj_priv; 1476 struct drm_i915_gem_object *obj_priv;
@@ -1481,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev,
1481 * this seqno. 1485 * this seqno.
1482 */ 1486 */
1483 if (obj_priv->last_rendering_seqno != request->seqno) 1487 if (obj_priv->last_rendering_seqno != request->seqno)
1484 return; 1488 goto out;
1485 1489
1486#if WATCH_LRU 1490#if WATCH_LRU
1487 DRM_INFO("%s: retire %d moves to inactive list %p\n", 1491 DRM_INFO("%s: retire %d moves to inactive list %p\n",
@@ -1493,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev,
1493 else 1497 else
1494 i915_gem_object_move_to_inactive(obj); 1498 i915_gem_object_move_to_inactive(obj);
1495 } 1499 }
1500out:
1501 spin_unlock(&dev_priv->mm.active_list_lock);
1496} 1502}
1497 1503
1498/** 1504/**
@@ -1990,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
1990 int regnum = obj_priv->fence_reg; 1996 int regnum = obj_priv->fence_reg;
1991 uint32_t val; 1997 uint32_t val;
1992 uint32_t pitch_val; 1998 uint32_t pitch_val;
1999 uint32_t fence_size_bits;
1993 2000
1994 if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || 2001 if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
1995 (obj_priv->gtt_offset & (obj->size - 1))) { 2002 (obj_priv->gtt_offset & (obj->size - 1))) {
1996 WARN(1, "%s: object 0x%08x not 1M or size aligned\n", 2003 WARN(1, "%s: object 0x%08x not 512K or size aligned\n",
1997 __func__, obj_priv->gtt_offset); 2004 __func__, obj_priv->gtt_offset);
1998 return; 2005 return;
1999 } 2006 }
2000 2007
2001 pitch_val = (obj_priv->stride / 128) - 1; 2008 pitch_val = (obj_priv->stride / 128) - 1;
2002 2009 WARN_ON(pitch_val & ~0x0000000f);
2003 val = obj_priv->gtt_offset; 2010 val = obj_priv->gtt_offset;
2004 if (obj_priv->tiling_mode == I915_TILING_Y) 2011 if (obj_priv->tiling_mode == I915_TILING_Y)
2005 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 2012 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
2006 val |= I830_FENCE_SIZE_BITS(obj->size); 2013 fence_size_bits = I830_FENCE_SIZE_BITS(obj->size);
2014 WARN_ON(fence_size_bits & ~0x00000f00);
2015 val |= fence_size_bits;
2007 val |= pitch_val << I830_FENCE_PITCH_SHIFT; 2016 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
2008 val |= I830_FENCE_REG_VALID; 2017 val |= I830_FENCE_REG_VALID;
2009 2018
@@ -2194,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2194 return -EBUSY; 2203 return -EBUSY;
2195 if (alignment == 0) 2204 if (alignment == 0)
2196 alignment = i915_gem_get_gtt_alignment(obj); 2205 alignment = i915_gem_get_gtt_alignment(obj);
2197 if (alignment & (PAGE_SIZE - 1)) { 2206 if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) {
2198 DRM_ERROR("Invalid object alignment requested %u\n", alignment); 2207 DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2199 return -EINVAL; 2208 return -EINVAL;
2200 } 2209 }
@@ -2211,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2211 } 2220 }
2212 } 2221 }
2213 if (obj_priv->gtt_space == NULL) { 2222 if (obj_priv->gtt_space == NULL) {
2223 bool lists_empty;
2224
2214 /* If the gtt is empty and we're still having trouble 2225 /* If the gtt is empty and we're still having trouble
2215 * fitting our object in, we're out of memory. 2226 * fitting our object in, we're out of memory.
2216 */ 2227 */
2217#if WATCH_LRU 2228#if WATCH_LRU
2218 DRM_INFO("%s: GTT full, evicting something\n", __func__); 2229 DRM_INFO("%s: GTT full, evicting something\n", __func__);
2219#endif 2230#endif
2220 if (list_empty(&dev_priv->mm.inactive_list) && 2231 spin_lock(&dev_priv->mm.active_list_lock);
2221 list_empty(&dev_priv->mm.flushing_list) && 2232 lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
2222 list_empty(&dev_priv->mm.active_list)) { 2233 list_empty(&dev_priv->mm.flushing_list) &&
2234 list_empty(&dev_priv->mm.active_list));
2235 spin_unlock(&dev_priv->mm.active_list_lock);
2236 if (lists_empty) {
2223 DRM_ERROR("GTT full, but LRU list empty\n"); 2237 DRM_ERROR("GTT full, but LRU list empty\n");
2224 return -ENOMEM; 2238 return -ENOMEM;
2225 } 2239 }
@@ -3675,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev)
3675 3689
3676 i915_gem_retire_requests(dev); 3690 i915_gem_retire_requests(dev);
3677 3691
3692 spin_lock(&dev_priv->mm.active_list_lock);
3678 if (!dev_priv->mm.wedged) { 3693 if (!dev_priv->mm.wedged) {
3679 /* Active and flushing should now be empty as we've 3694 /* Active and flushing should now be empty as we've
3680 * waited for a sequence higher than any pending execbuffer 3695 * waited for a sequence higher than any pending execbuffer
@@ -3701,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev)
3701 obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; 3716 obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
3702 i915_gem_object_move_to_inactive(obj_priv->obj); 3717 i915_gem_object_move_to_inactive(obj_priv->obj);
3703 } 3718 }
3719 spin_unlock(&dev_priv->mm.active_list_lock);
3704 3720
3705 while (!list_empty(&dev_priv->mm.flushing_list)) { 3721 while (!list_empty(&dev_priv->mm.flushing_list)) {
3706 struct drm_i915_gem_object *obj_priv; 3722 struct drm_i915_gem_object *obj_priv;
@@ -3949,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3949 if (ret != 0) 3965 if (ret != 0)
3950 return ret; 3966 return ret;
3951 3967
3968 spin_lock(&dev_priv->mm.active_list_lock);
3952 BUG_ON(!list_empty(&dev_priv->mm.active_list)); 3969 BUG_ON(!list_empty(&dev_priv->mm.active_list));
3970 spin_unlock(&dev_priv->mm.active_list_lock);
3971
3953 BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); 3972 BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3954 BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); 3973 BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3955 BUG_ON(!list_empty(&dev_priv->mm.request_list)); 3974 BUG_ON(!list_empty(&dev_priv->mm.request_list));
@@ -3993,6 +4012,7 @@ i915_gem_load(struct drm_device *dev)
3993{ 4012{
3994 drm_i915_private_t *dev_priv = dev->dev_private; 4013 drm_i915_private_t *dev_priv = dev->dev_private;
3995 4014
4015 spin_lock_init(&dev_priv->mm.active_list_lock);
3996 INIT_LIST_HEAD(&dev_priv->mm.active_list); 4016 INIT_LIST_HEAD(&dev_priv->mm.active_list);
3997 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 4017 INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
3998 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); 4018 INIT_LIST_HEAD(&dev_priv->mm.inactive_list);