From 456c96b7fd2d741bc55f3c8511ef75fad3ff23a8 Mon Sep 17 00:00:00 2001 From: jsg Date: Tue, 28 Mar 2023 03:55:56 +0000 Subject: [PATCH] drm/msm/gem: Prevent blocking within shrinker loop From Dmitry Osipenko 96a5aee27439e56fca69628c3f87a042e7026b3e in linux-6.1.y/6.1.21 9630b585b607bd26f505d34620b14d75b9a5af7d in mainline linux --- sys/dev/pci/drm/drm_gem.c | 9 +++++++-- 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 *); -- 2.20.1