View | Details | Raw Unified | Return to bug 15911 | Differences between
and this patch

Collapse All | Expand All

(-)a/drivers/gpu/drm/i915/i915_drv.h (+13 lines)
Lines 557-562 typedef struct drm_i915_private { Link Here
557
		 */
557
		 */
558
		struct list_head inactive_list;
558
		struct list_head inactive_list;
559
559
560
		/**
561
		 * LRU list of objects which are not in the ringbuffer and
562
		 * are ready to unbind, but are still in the GTT and currently
563
		 * mapped and in use by the CPU.
564
		 *
565
		 * last_rendering_seqno is 0 while an object is in this list.
566
		 *
567
		 * A reference is not held on the buffer while on this list,
568
		 * as merely being GTT-bound shouldn't prevent its being
569
		 * freed, and we'll pull it off the list in the free path.
570
		 */
571
		struct list_head mmap_list;
572
560
		/** LRU list of objects with fence regs on them. */
573
		/** LRU list of objects with fence regs on them. */
561
		struct list_head fence_list;
574
		struct list_head fence_list;
562
575
(-)a/drivers/gpu/drm/i915/i915_gem.c (-9 / +63 lines)
Lines 52-57 static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, Link Here
52
static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
52
static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
53
static int i915_gem_evict_something(struct drm_device *dev, int min_size);
53
static int i915_gem_evict_something(struct drm_device *dev, int min_size);
54
static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
54
static int i915_gem_evict_from_inactive_list(struct drm_device *dev);
55
static int i915_gem_evict_from_mmap_list(struct drm_device *dev);
55
static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
56
static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
56
				struct drm_i915_gem_pwrite *args,
57
				struct drm_i915_gem_pwrite *args,
57
				struct drm_file *file_priv);
58
				struct drm_file *file_priv);
Lines 1064-1069 i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, Link Here
1064
		ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
1065
		ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
1065
	}
1066
	}
1066
1067
1068
	if (ret == 0 && obj_priv->gtt_space && !obj_priv->active)
1069
	    list_move_tail(&obj_priv->list, &dev_priv->mm.mmap_list);
1070
1067
	drm_gem_object_unreference(obj);
1071
	drm_gem_object_unreference(obj);
1068
	mutex_unlock(&dev->struct_mutex);
1072
	mutex_unlock(&dev->struct_mutex);
1069
	return ret;
1073
	return ret;
Lines 1197-1202 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) Link Here
1197
			goto unlock;
1201
			goto unlock;
1198
	}
1202
	}
1199
1203
1204
	if (!obj_priv->active)
1205
		list_move_tail(&obj_priv->list, &dev_priv->mm.mmap_list);
1206
1200
	pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
1207
	pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
1201
		page_offset;
1208
		page_offset;
1202
1209
Lines 2162-2168 i915_gem_evict_everything(struct drm_device *dev) Link Here
2162
	bool lists_empty;
2169
	bool lists_empty;
2163
2170
2164
	spin_lock(&dev_priv->mm.active_list_lock);
2171
	spin_lock(&dev_priv->mm.active_list_lock);
2165
	lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
2172
	lists_empty = (list_empty(&dev_priv->mm.mmap_list) &&
2173
		       list_empty(&dev_priv->mm.inactive_list) &&
2166
		       list_empty(&dev_priv->mm.flushing_list) &&
2174
		       list_empty(&dev_priv->mm.flushing_list) &&
2167
		       list_empty(&dev_priv->mm.active_list));
2175
		       list_empty(&dev_priv->mm.active_list));
2168
	spin_unlock(&dev_priv->mm.active_list_lock);
2176
	spin_unlock(&dev_priv->mm.active_list_lock);
Lines 2177-2188 i915_gem_evict_everything(struct drm_device *dev) Link Here
2177
2185
2178
	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
2186
	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
2179
2187
2188
	ret = i915_gem_evict_from_mmap_list(dev);
2189
	if (ret)
2190
		return ret;
2191
2180
	ret = i915_gem_evict_from_inactive_list(dev);
2192
	ret = i915_gem_evict_from_inactive_list(dev);
2181
	if (ret)
2193
	if (ret)
2182
		return ret;
2194
		return ret;
2183
2195
2184
	spin_lock(&dev_priv->mm.active_list_lock);
2196
	spin_lock(&dev_priv->mm.active_list_lock);
2185
	lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
2197
	lists_empty = (list_empty(&dev_priv->mm.mmap_list) &&
2198
		       list_empty(&dev_priv->mm.inactive_list) &&
2186
		       list_empty(&dev_priv->mm.flushing_list) &&
2199
		       list_empty(&dev_priv->mm.flushing_list) &&
2187
		       list_empty(&dev_priv->mm.active_list));
2200
		       list_empty(&dev_priv->mm.active_list));
2188
	spin_unlock(&dev_priv->mm.active_list_lock);
2201
	spin_unlock(&dev_priv->mm.active_list_lock);
Lines 4624-4640 void i915_gem_free_object(struct drm_gem_object *obj) Link Here
4624
	kfree(obj->driver_private);
4637
	kfree(obj->driver_private);
4625
}
4638
}
4626
4639
4627
/** Unbinds all inactive objects. */
4628
static int
4640
static int
4629
i915_gem_evict_from_inactive_list(struct drm_device *dev)
4641
i915_gem_evict_from_list(struct drm_device *dev,
4642
			 struct list_head *list)
4630
{
4643
{
4631
	drm_i915_private_t *dev_priv = dev->dev_private;
4644
	while (!list_empty(list)) {
4632
4633
	while (!list_empty(&dev_priv->mm.inactive_list)) {
4634
		struct drm_gem_object *obj;
4645
		struct drm_gem_object *obj;
4635
		int ret;
4646
		int ret;
4636
4647
4637
		obj = list_first_entry(&dev_priv->mm.inactive_list,
4648
		obj = list_first_entry(list,
4638
				       struct drm_i915_gem_object,
4649
				       struct drm_i915_gem_object,
4639
				       list)->obj;
4650
				       list)->obj;
4640
4651
Lines 4648-4653 i915_gem_evict_from_inactive_list(struct drm_device *dev) Link Here
4648
	return 0;
4659
	return 0;
4649
}
4660
}
4650
4661
4662
/** Unbinds all inactive objects. */
4663
static int
4664
i915_gem_evict_from_inactive_list(struct drm_device *dev)
4665
{
4666
	drm_i915_private_t *dev_priv = dev->dev_private;
4667
4668
	return i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
4669
}
4670
4671
static int
4672
i915_gem_evict_from_mmap_list(struct drm_device *dev)
4673
{
4674
	drm_i915_private_t *dev_priv = dev->dev_private;
4675
4676
	return i915_gem_evict_from_list(dev, &dev_priv->mm.mmap_list);
4677
}
4678
4651
int
4679
int
4652
i915_gem_idle(struct drm_device *dev)
4680
i915_gem_idle(struct drm_device *dev)
4653
{
4681
{
Lines 4674-4679 i915_gem_idle(struct drm_device *dev) Link Here
4674
			mutex_unlock(&dev->struct_mutex);
4702
			mutex_unlock(&dev->struct_mutex);
4675
			return ret;
4703
			return ret;
4676
		}
4704
		}
4705
4706
		ret = i915_gem_evict_from_mmap_list(dev);
4707
		if (ret) {
4708
			mutex_unlock(&dev->struct_mutex);
4709
			return ret;
4710
		}
4677
	}
4711
	}
4678
4712
4679
	/* Hack!  Don't let anybody do execbuf while we don't control the chip.
4713
	/* Hack!  Don't let anybody do execbuf while we don't control the chip.
Lines 5010-5015 i915_gem_entervt_ioctl(struct drm_device *dev, void *data, Link Here
5010
5044
5011
	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
5045
	BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
5012
	BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
5046
	BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
5047
	BUG_ON(!list_empty(&dev_priv->mm.mmap_list));
5013
	BUG_ON(!list_empty(&dev_priv->mm.request_list));
5048
	BUG_ON(!list_empty(&dev_priv->mm.request_list));
5014
	mutex_unlock(&dev->struct_mutex);
5049
	mutex_unlock(&dev->struct_mutex);
5015
5050
Lines 5053-5058 i915_gem_load(struct drm_device *dev) Link Here
5053
	INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
5088
	INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
5054
	INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
5089
	INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list);
5055
	INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
5090
	INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
5091
	INIT_LIST_HEAD(&dev_priv->mm.mmap_list);
5056
	INIT_LIST_HEAD(&dev_priv->mm.request_list);
5092
	INIT_LIST_HEAD(&dev_priv->mm.request_list);
5057
	INIT_LIST_HEAD(&dev_priv->mm.fence_list);
5093
	INIT_LIST_HEAD(&dev_priv->mm.fence_list);
5058
	INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
5094
	INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
Lines 5308-5313 i915_gpu_is_active(struct drm_device *dev) Link Here
5308
}
5344
}
5309
5345
5310
static int
5346
static int
5347
i915_move_mmap_onto_inactive_list(struct drm_device *dev)
5348
{
5349
	drm_i915_private_t *dev_priv = dev->dev_private;
5350
5351
	if (list_empty(&dev_priv->mm.mmap_list))
5352
		return 0;
5353
5354
	do {
5355
		list_move_tail(dev_priv->mm.mmap_list.next,
5356
			       &dev_priv->mm.inactive_list);
5357
	} while (!list_empty(&dev_priv->mm.mmap_list));
5358
5359
	return 1;
5360
}
5361
5362
static int
5311
i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask)
5363
i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask)
5312
{
5364
{
5313
	drm_i915_private_t *dev_priv, *next_dev;
5365
	drm_i915_private_t *dev_priv, *next_dev;
Lines 5416-5421 rescan: Link Here
5416
				active++;
5468
				active++;
5417
			}
5469
			}
5418
5470
5471
			if (i915_move_mmap_onto_inactive_list(dev))
5472
				active++;
5473
5419
			spin_lock(&shrink_list_lock);
5474
			spin_lock(&shrink_list_lock);
5420
			mutex_unlock(&dev->struct_mutex);
5475
			mutex_unlock(&dev->struct_mutex);
5421
		}
5476
		}
5422
- 

Return to bug 15911