diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 34 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 111 |
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 | ||
| 3880 | unlock: | 3854 | unlock: |
| 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, | |||
| 2368 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, | 2368 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, |
| 2369 | struct drm_file *file_priv); | 2369 | struct drm_file *file_priv); |
| 2370 | void i915_gem_load(struct drm_device *dev); | 2370 | void i915_gem_load(struct drm_device *dev); |
| 2371 | unsigned 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 | ||
| 2371 | void *i915_gem_object_alloc(struct drm_device *dev); | 2377 | void *i915_gem_object_alloc(struct drm_device *dev); |
| 2372 | void i915_gem_object_free(struct drm_i915_gem_object *obj); | 2378 | void i915_gem_object_free(struct drm_i915_gem_object *obj); |
| 2373 | void i915_gem_object_init(struct drm_i915_gem_object *obj, | 2379 | void 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, | |||
| 60 | static int i915_gem_shrinker_oom(struct notifier_block *nb, | 60 | static int i915_gem_shrinker_oom(struct notifier_block *nb, |
| 61 | unsigned long event, | 61 | unsigned long event, |
| 62 | void *ptr); | 62 | void *ptr); |
| 63 | static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target); | ||
| 64 | static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); | 63 | static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); |
| 65 | 64 | ||
| 66 | static bool cpu_cache_is_coherent(struct drm_device *dev, | 65 | static 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 | ||
| 1941 | static unsigned long | 1944 | unsigned long |
| 1942 | __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, | 1945 | i915_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); | ||
