[RFC PATCH v5 07/14] drm/ttm: Introduce shrink throttling.
Thomas Hellström
thomas.hellstrom at linux.intel.com
Sun Feb 12 13:26:54 UTC 2023
Since pages are not immediately freed by the TTM shrinker but rather
inserted into the swap cache, the system will keep on calling the
shrinker rapidly filling the swap cache which has a negative impact
on system performance.
When shrinking, throttle on the number of pages present in the swap
cache.
Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
---
drivers/gpu/drm/ttm/ttm_tt.c | 40 ++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index fbf42db8a211..f2ae40762e06 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -428,6 +428,42 @@ static unsigned long ttm_tt_shrinker_count(struct shrinker *shrink,
return num_pages ? num_pages : SHRINK_EMPTY;
}
+#define TTM_SWAP_MIN_SWAP_PAGES (SZ_128M >> PAGE_SHIFT)
+#define TTM_SWAP_MAX_SWAPCACHE_PAGES (SZ_1G >> PAGE_SHIFT)
+static unsigned long ttm_tt_shrinker_throttle(unsigned long pages)
+{
+ unsigned long
+ tmp = get_nr_swap_pages();
+
+ /*
+ * Draining available swap space too far will trigger
+ * systemd-oomd even if there are a huge number of dirty pages
+ * available for laundry and free in the swap cache. Don't drain
+ * the available swap-space too far.
+ */
+ if (tmp > TTM_SWAP_MIN_SWAP_PAGES)
+ tmp -= TTM_SWAP_MIN_SWAP_PAGES;
+ else
+ tmp = 0;
+
+ pages = min(tmp, pages);
+
+ /*
+ * Our shrinker doesn't immediately free pages unless they belong
+ * to purgeable objects. Rather they are inserted into the swap-cache.
+ * But the system doesn't really get this and continues to call our
+ * shrinker thinking it's still out of memory, when it could just
+ * laundry pages in the swap cache and free them. So throttle on the
+ * number of pages in the swap cache.
+ */
+
+ tmp = total_swapcache_pages();
+ if (tmp > TTM_SWAP_MAX_SWAPCACHE_PAGES)
+ pages = 0;
+
+ return pages;
+}
+
static unsigned long ttm_tt_shrinker_scan(struct shrinker *shrink,
struct shrink_control *sc)
{
@@ -455,6 +491,10 @@ static unsigned long ttm_tt_shrinker_scan(struct shrinker *shrink,
nr_to_scan -= freed;
else
nr_to_scan = 0;
+
+ if (nr_to_scan)
+ nr_to_scan = ttm_tt_shrinker_throttle(nr_to_scan);
+
if (!nr_to_scan)
return freed ? freed : SHRINK_STOP;
--
2.34.1
More information about the Intel-gfx-trybot
mailing list