[dm-devel] [PATCH] shrinker: fix a bug when callback returns -1
Mikulas Patocka
mpatocka at redhat.com
Mon Aug 29 19:36:48 UTC 2011
Hi
This patch fixes a lockup when shrinker callback returns -1.
BTW. shouldn't the value returned by callback be long instead of int? On
64-bit architectures, there may be more than 2^32 entries allocated.
Mikulas
---
shrinker: fix a bug when callback returns -1
Shrinker callback can return -1 if it is at a risk of deadlock.
However, this is not tested at some places.
If do_shrinker_shrink returns -1 here
"max_pass = do_shrinker_shrink(shrinker, shrink, 0)",
it is converted to an unsigned long integer. This may result in excessive
total_scan value and a lockup due to code looping too much in
"while (total_scan >= batch_size)" cycle.
Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
---
mm/vmscan.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
Index: linux-3.1-rc3-fast/mm/vmscan.c
===================================================================
--- linux-3.1-rc3-fast.orig/mm/vmscan.c 2011-08-29 20:34:27.000000000 +0200
+++ linux-3.1-rc3-fast/mm/vmscan.c 2011-08-29 20:37:38.000000000 +0200
@@ -250,6 +250,7 @@ unsigned long shrink_slab(struct shrink_
unsigned long long delta;
unsigned long total_scan;
unsigned long max_pass;
+ int sr;
int shrink_ret = 0;
long nr;
long new_nr;
@@ -266,7 +267,10 @@ unsigned long shrink_slab(struct shrink_
} while (cmpxchg(&shrinker->nr, nr, 0) != nr);
total_scan = nr;
- max_pass = do_shrinker_shrink(shrinker, shrink, 0);
+ sr = do_shrinker_shrink(shrinker, shrink, 0);
+ if (sr == -1)
+ continue;
+ max_pass = sr;
delta = (4 * nr_pages_scanned) / shrinker->seeks;
delta *= max_pass;
do_div(delta, lru_pages + 1);
@@ -309,6 +313,8 @@ unsigned long shrink_slab(struct shrink_
int nr_before;
nr_before = do_shrinker_shrink(shrinker, shrink, 0);
+ if (nr_before == -1)
+ break;
shrink_ret = do_shrinker_shrink(shrinker, shrink,
batch_size);
if (shrink_ret == -1)
More information about the dm-devel
mailing list