aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c34
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c111
3 files changed, 74 insertions, 77 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 2cbc85f3b237..063b44817e08 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3826,7 +3826,6 @@ i915_drop_caches_set(void *data, u64 val)
3826{ 3826{
3827 struct drm_device *dev = data; 3827 struct drm_device *dev = data;
3828 struct drm_i915_private *dev_priv = dev->dev_private; 3828 struct drm_i915_private *dev_priv = dev->dev_private;
3829 struct drm_i915_gem_object *obj, *next;
3830 int ret; 3829 int ret;
3831 3830
3832 DRM_DEBUG("Dropping caches: 0x%08llx\n", val); 3831 DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
@@ -3846,36 +3845,11 @@ i915_drop_caches_set(void *data, u64 val)
3846 if (val & (DROP_RETIRE | DROP_ACTIVE)) 3845 if (val & (DROP_RETIRE | DROP_ACTIVE))
3847 i915_gem_retire_requests(dev); 3846 i915_gem_retire_requests(dev);
3848 3847
3849 if (val & DROP_BOUND) { 3848 if (val & DROP_BOUND)
3850 list_for_each_entry_safe(obj, next, &dev_priv->mm.bound_list, 3849 i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND);
3851 global_list) {
3852 struct i915_vma *vma, *v;
3853 3850
3854 ret = 0; 3851 if (val & DROP_UNBOUND)
3855 drm_gem_object_reference(&obj->base); 3852 i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_UNBOUND);
3856 list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) {
3857 if (vma->pin_count)
3858 continue;
3859
3860 ret = i915_vma_unbind(vma);
3861 if (ret)
3862 break;
3863 }
3864 drm_gem_object_unreference(&obj->base);
3865 if (ret)
3866 goto unlock;
3867 }
3868 }
3869
3870 if (val & DROP_UNBOUND) {
3871 list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list,
3872 global_list)
3873 if (obj->pages_pin_count == 0) {
3874 ret = i915_gem_object_put_pages(obj);
3875 if (ret)
3876 goto unlock;
3877 }
3878 }
3879 3853
3880unlock: 3854unlock:
3881 mutex_unlock(&dev->struct_mutex); 3855 mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 88a8b72b553e..17dfce0f4e68 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2368,6 +2368,12 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
2368int i915_gem_wait_ioctl(struct drm_device *dev, void *data, 2368int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
2369 struct drm_file *file_priv); 2369 struct drm_file *file_priv);
2370void i915_gem_load(struct drm_device *dev); 2370void i915_gem_load(struct drm_device *dev);
2371unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv,
2372 long target,
2373 unsigned flags);
2374#define I915_SHRINK_PURGEABLE 0x1
2375#define I915_SHRINK_UNBOUND 0x2
2376#define I915_SHRINK_BOUND 0x4
2371void *i915_gem_object_alloc(struct drm_device *dev); 2377void *i915_gem_object_alloc(struct drm_device *dev);
2372void i915_gem_object_free(struct drm_i915_gem_object *obj); 2378void i915_gem_object_free(struct drm_i915_gem_object *obj);
2373void i915_gem_object_init(struct drm_i915_gem_object *obj, 2379void i915_gem_object_init(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4ca3a6dcf10b..1ef6700e5d98 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -60,7 +60,6 @@ static unsigned long i915_gem_shrinker_scan(struct shrinker *shrinker,
60static int i915_gem_shrinker_oom(struct notifier_block *nb, 60static int i915_gem_shrinker_oom(struct notifier_block *nb,
61 unsigned long event, 61 unsigned long event,
62 void *ptr); 62 void *ptr);
63static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
64static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); 63static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
65 64
66static bool cpu_cache_is_coherent(struct drm_device *dev, 65static bool cpu_cache_is_coherent(struct drm_device *dev,
@@ -1741,7 +1740,11 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
1741 * offsets on purgeable objects by truncating it and marking it purged, 1740 * offsets on purgeable objects by truncating it and marking it purged,
1742 * which prevents userspace from ever using that object again. 1741 * which prevents userspace from ever using that object again.
1743 */ 1742 */
1744 i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT); 1743 i915_gem_shrink(dev_priv,
1744 obj->base.size >> PAGE_SHIFT,
1745 I915_SHRINK_BOUND |
1746 I915_SHRINK_UNBOUND |
1747 I915_SHRINK_PURGEABLE);
1745 ret = drm_gem_create_mmap_offset(&obj->base); 1748 ret = drm_gem_create_mmap_offset(&obj->base);
1746 if (ret != -ENOSPC) 1749 if (ret != -ENOSPC)
1747 goto out; 1750 goto out;
@@ -1938,12 +1941,11 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
1938 return 0; 1941 return 0;
1939} 1942}
1940 1943
1941static unsigned long 1944unsigned long
1942__i915_gem_shrink(struct drm_i915_private *dev_priv, long target, 1945i915_gem_shrink(struct drm_i915_private *dev_priv,
1943 bool purgeable_only) 1946 long target, unsigned flags)
1944{ 1947{
1945 struct list_head still_in_list; 1948 const bool purgeable_only = flags & I915_SHRINK_PURGEABLE;
1946 struct drm_i915_gem_object *obj;
1947 unsigned long count = 0; 1949 unsigned long count = 0;
1948 1950
1949 /* 1951 /*
@@ -1965,62 +1967,68 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
1965 * dev->struct_mutex and so we won't ever be able to observe an 1967 * dev->struct_mutex and so we won't ever be able to observe an
1966 * object on the bound_list with a reference count equals 0. 1968 * object on the bound_list with a reference count equals 0.
1967 */ 1969 */
1968 INIT_LIST_HEAD(&still_in_list); 1970 if (flags & I915_SHRINK_UNBOUND) {
1969 while (count < target && !list_empty(&dev_priv->mm.unbound_list)) { 1971 struct list_head still_in_list;
1970 obj = list_first_entry(&dev_priv->mm.unbound_list,
1971 typeof(*obj), global_list);
1972 list_move_tail(&obj->global_list, &still_in_list);
1973 1972
1974 if (!i915_gem_object_is_purgeable(obj) && purgeable_only) 1973 INIT_LIST_HEAD(&still_in_list);
1975 continue; 1974 while (count < target && !list_empty(&dev_priv->mm.unbound_list)) {
1975 struct drm_i915_gem_object *obj;
1976 1976
1977 drm_gem_object_reference(&obj->base); 1977 obj = list_first_entry(&dev_priv->mm.unbound_list,
1978 typeof(*obj), global_list);
1979 list_move_tail(&obj->global_list, &still_in_list);
1978 1980
1979 if (i915_gem_object_put_pages(obj) == 0) 1981 if (!i915_gem_object_is_purgeable(obj) && purgeable_only)
1980 count += obj->base.size >> PAGE_SHIFT; 1982 continue;
1981 1983
1982 drm_gem_object_unreference(&obj->base); 1984 drm_gem_object_reference(&obj->base);
1985
1986 if (i915_gem_object_put_pages(obj) == 0)
1987 count += obj->base.size >> PAGE_SHIFT;
1988
1989 drm_gem_object_unreference(&obj->base);
1990 }
1991 list_splice(&still_in_list, &dev_priv->mm.unbound_list);
1983 } 1992 }
1984 list_splice(&still_in_list, &dev_priv->mm.unbound_list);
1985 1993
1986 INIT_LIST_HEAD(&still_in_list); 1994 if (flags & I915_SHRINK_BOUND) {
1987 while (count < target && !list_empty(&dev_priv->mm.bound_list)) { 1995 struct list_head still_in_list;
1988 struct i915_vma *vma, *v;
1989 1996
1990 obj = list_first_entry(&dev_priv->mm.bound_list, 1997 INIT_LIST_HEAD(&still_in_list);
1991 typeof(*obj), global_list); 1998 while (count < target && !list_empty(&dev_priv->mm.bound_list)) {
1992 list_move_tail(&obj->global_list, &still_in_list); 1999 struct drm_i915_gem_object *obj;
2000 struct i915_vma *vma, *v;
1993 2001
1994 if (!i915_gem_object_is_purgeable(obj) && purgeable_only) 2002 obj = list_first_entry(&dev_priv->mm.bound_list,
1995 continue; 2003 typeof(*obj), global_list);
2004 list_move_tail(&obj->global_list, &still_in_list);
1996 2005
1997 drm_gem_object_reference(&obj->base);