diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-03-28 03:55:57 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-03-28 03:55:57 +0000 |
commit | 089446c4c0bcb81eb3b29f63d01a0b206be8d70b (patch) | |
tree | c4cf9d1fc3b6ddfdf197a999e41249572cc0fea1 | |
parent | 54deeeef628a34783e00d12cb0248c4fad699a71 (diff) |
drm/msm/gem: Prevent blocking within shrinker loop
From Dmitry Osipenko
96a5aee27439e56fca69628c3f87a042e7026b3e in linux-6.1.y/6.1.21
9630b585b607bd26f505d34620b14d75b9a5af7d in mainline linux
-rw-r--r-- | sys/dev/pci/drm/drm_gem.c | 9 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/drm/drm_gem.h | 4 |
2 files changed, 10 insertions, 3 deletions
diff --git a/sys/dev/pci/drm/drm_gem.c b/sys/dev/pci/drm/drm_gem.c index d8884670a2c..b91420bf232 100644 --- a/sys/dev/pci/drm/drm_gem.c +++ b/sys/dev/pci/drm/drm_gem.c @@ -1660,10 +1660,13 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail); * * @lru: The LRU to scan * @nr_to_scan: The number of pages to try to reclaim + * @remaining: The number of pages left to reclaim, should be initialized by caller * @shrink: Callback to try to shrink/reclaim the object. */ unsigned long -drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan, +drm_gem_lru_scan(struct drm_gem_lru *lru, + unsigned int nr_to_scan, + unsigned long *remaining, bool (*shrink)(struct drm_gem_object *obj)) { struct drm_gem_lru still_in_lru; @@ -1702,8 +1705,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan, * hit shrinker in response to trying to get backing pages * for this obj (ie. while it's lock is already held) */ - if (!dma_resv_trylock(obj->resv)) + if (!dma_resv_trylock(obj->resv)) { + *remaining += obj->size >> PAGE_SHIFT; goto tail; + } if (shrink(obj)) { freed += obj->size >> PAGE_SHIFT; diff --git a/sys/dev/pci/drm/include/drm/drm_gem.h b/sys/dev/pci/drm/include/drm/drm_gem.h index cd878673149..4b4001f6a2a 100644 --- a/sys/dev/pci/drm/include/drm/drm_gem.h +++ b/sys/dev/pci/drm/include/drm/drm_gem.h @@ -495,7 +495,9 @@ int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, void drm_gem_lru_init(struct drm_gem_lru *lru, struct rwlock *lock); void drm_gem_lru_remove(struct drm_gem_object *obj); void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj); -unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan, +unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, + unsigned int nr_to_scan, + unsigned long *remaining, bool (*shrink)(struct drm_gem_object *obj)); void drm_ref(struct uvm_object *); |