[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220421234837.3629927-12-kent.overstreet@gmail.com>
Date: Thu, 21 Apr 2022 19:48:35 -0400
From: Kent Overstreet <kent.overstreet@...il.com>
To: linux-kernel@...r.kernel.org, linux-mm@...ck.org,
linux-fsdevel@...r.kernel.org
Cc: Kent Overstreet <kent.overstreet@...il.com>, hch@....de,
hannes@...xchg.org, akpm@...ux-foundation.org,
linux-clk@...r.kernel.org, linux-tegra@...r.kernel.org,
linux-input@...r.kernel.org, roman.gushchin@...ux.dev
Subject: [PATCH v2 6/8] mm: Count requests to free & nr freed per shrinker
The next step in this patch series for improving debugging of shrinker
related issues: keep counts of number of objects we request to free vs.
actually freed, and prints them in shrinker_to_text().
Shrinkers won't necessarily free all objects requested for a variety of
reasons, but if the two counts are wildly different something is likely
amiss.
Signed-off-by: Kent Overstreet <kent.overstreet@...il.com>
---
include/linux/shrinker.h | 3 +++
mm/vmscan.c | 16 +++++++++++++---
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index b5f411768b..12967748f9 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -79,6 +79,9 @@ struct shrinker {
#endif
/* objs pending delete, per node */
atomic_long_t *nr_deferred;
+
+ atomic_long_t objects_requested_to_free;
+ atomic_long_t objects_freed;
};
#define DEFAULT_SEEKS 2 /* A good number if you don't know better. */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 905bc23800..12562546a7 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -711,16 +711,22 @@ void shrinker_to_text(struct printbuf *out, struct shrinker *shrinker)
pr_buf(out, "%s", shrinker->name);
else
pr_buf(out, "%ps:", shrinker->scan_objects);
+ pr_newline(out);
+ pr_indent_push(out, 2);
- pr_buf(out, " objects: %lu", shrinker->count_objects(shrinker, &sc));
+ pr_buf(out, "objects: %lu", shrinker->count_objects(shrinker, &sc));
+ pr_newline(out);
+ pr_buf(out, "requested to free: %lu", atomic_long_read(&shrinker->objects_requested_to_free));
+ pr_newline(out);
+ pr_buf(out, "objects freed: %lu", atomic_long_read(&shrinker->objects_freed));
pr_newline(out);
if (shrinker->to_text) {
- pr_indent_push(out, 2);
shrinker->to_text(out, shrinker);
- pr_indent_pop(out, 2);
pr_newline(out);
}
+
+ pr_indent_pop(out, 2);
}
/**
@@ -846,12 +852,16 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
unsigned long ret;
unsigned long nr_to_scan = min(batch_size, total_scan);
+ atomic_long_add(nr_to_scan, &shrinker->objects_requested_to_free);
+
shrinkctl->nr_to_scan = nr_to_scan;
shrinkctl->nr_scanned = nr_to_scan;
ret = shrinker->scan_objects(shrinker, shrinkctl);
if (ret == SHRINK_STOP)
break;
+
freed += ret;
+ atomic_long_add(ret, &shrinker->objects_freed);
count_vm_events(SLABS_SCANNED, shrinkctl->nr_scanned);
total_scan -= shrinkctl->nr_scanned;
--
2.35.2
Powered by blists - more mailing lists