diff mbox series

[10/10] fs: super_cache_to_text()

Message ID 20240824191020.3170516-11-kent.overstreet@linux.dev (mailing list archive)
State New
Headers show
Series shrinker debugging, .to_text() report (resend) | expand

Commit Message

Kent Overstreet Aug. 24, 2024, 7:10 p.m. UTC
Implement shrinker.to_text() for the superblock shrinker: print out nr
of dentries and inodes, total and shrinkable.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
---
 fs/super.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Dave Chinner Aug. 28, 2024, 3:43 a.m. UTC | #1
On Sat, Aug 24, 2024 at 03:10:17PM -0400, Kent Overstreet wrote:
> Implement shrinker.to_text() for the superblock shrinker: print out nr
> of dentries and inodes, total and shrinkable.
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Dave Chinner <david@fromorbit.com>
> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
> ---
>  fs/super.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/fs/super.c b/fs/super.c
> index 5b0fea6ff1cd..d3e43127e311 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -36,6 +36,7 @@
>  #include <linux/lockdep.h>
>  #include <linux/user_namespace.h>
>  #include <linux/fs_context.h>
> +#include <linux/seq_buf.h>
>  #include <uapi/linux/mount.h>
>  #include "internal.h"
>  
> @@ -270,6 +271,16 @@ static unsigned long super_cache_count(struct shrinker *shrink,
>  	return total_objects;
>  }
>  
> +static void super_cache_to_text(struct seq_buf *out, struct shrinker *shrink)
> +{
> +	struct super_block *sb = shrink->private_data;
> +
> +	seq_buf_printf(out, "inodes:   total %zu shrinkable %lu\n",
> +		       per_cpu_sum(sb->s_inodes_nr), list_lru_count(&sb->s_inode_lru));
> +	seq_buf_printf(out, "dentries: toal %zu shrinkbale %lu\n",
> +		       per_cpu_sum(sb->s_dentry_nr), list_lru_count(&sb->s_dentry_lru));

There's no superblock identification in this output - how are we
supposed to take this information and relate it to the filesystems
that are mounted on the system?

Also, list_lru_count() only counts root memcg objects, so any inodes
and dentries accounted to memcgs and are freeable will not be
included in this output. For systems with lots of memcgs, that will
result in the superblock reporting lots of inodes and dentries, but
almost nothing being freeable. hence to do this correctly, there
needs to be per-node, per-memcg list_lru_count_one() iteration here...

-Dave.
diff mbox series

Patch

diff --git a/fs/super.c b/fs/super.c
index 5b0fea6ff1cd..d3e43127e311 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -36,6 +36,7 @@ 
 #include <linux/lockdep.h>
 #include <linux/user_namespace.h>
 #include <linux/fs_context.h>
+#include <linux/seq_buf.h>
 #include <uapi/linux/mount.h>
 #include "internal.h"
 
@@ -270,6 +271,16 @@  static unsigned long super_cache_count(struct shrinker *shrink,
 	return total_objects;
 }
 
+static void super_cache_to_text(struct seq_buf *out, struct shrinker *shrink)
+{
+	struct super_block *sb = shrink->private_data;
+
+	seq_buf_printf(out, "inodes:   total %zu shrinkable %lu\n",
+		       per_cpu_sum(sb->s_inodes_nr), list_lru_count(&sb->s_inode_lru));
+	seq_buf_printf(out, "dentries: toal %zu shrinkbale %lu\n",
+		       per_cpu_sum(sb->s_dentry_nr), list_lru_count(&sb->s_dentry_lru));
+}
+
 static void destroy_super_work(struct work_struct *work)
 {
 	struct super_block *s = container_of(work, struct super_block,
@@ -394,6 +405,7 @@  static struct super_block *alloc_super(struct file_system_type *type, int flags,
 
 	s->s_shrink->scan_objects = super_cache_scan;
 	s->s_shrink->count_objects = super_cache_count;
+	s->s_shrink->to_text = super_cache_to_text;
 	s->s_shrink->batch = 1024;
 	s->s_shrink->private_data = s;