From 51288af76ba3f9481179aac23b0bf03decb3cc9d Mon Sep 17 00:00:00 2001 From: Tim Chase Date: Thu, 2 Oct 2014 07:21:08 -0500 Subject: [PATCH] Return number of pages freed in the __arc_shrunker_func(). According to the comments in the kernel's shrinker.h file, the scan_objects callback should return the number of objects actually freed. Previously, the shrinker returned the number of objects which were _attempted_ to be freed. When the return value of a shrinker is too high, callers may retry shrinking indefinitely. --- module/zfs/arc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 2c7abe6ec542..1a278c795ff3 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -2607,7 +2607,7 @@ arc_evictable_memory(void) { static int __arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc) { - uint64_t pages; + uint64_t oldpages, pages; /* The arc is considered warm once reclaim has occurred */ if (unlikely(arc_warm == B_FALSE)) @@ -2632,8 +2632,13 @@ __arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc) * reap whatever we can from the various arc slabs. */ if (pages > 0) { + oldpages = btop(arc_evictable_memory()); arc_kmem_reap_now(ARC_RECLAIM_AGGR, ptob(sc->nr_to_scan)); pages = btop(arc_evictable_memory()); + if (pages > oldpages) + pages = pages - oldpages; + else + pages = 0; } else { arc_kmem_reap_now(ARC_RECLAIM_CONS, ptob(sc->nr_to_scan)); pages = -1;