public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir
@ 2025-04-15 18:49 Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 1/8] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton, Thomas Weißschuh

I had previously sent some patches to add debugfs files for the net
namespace refcount trackers, but Andrew convinced me to make this more
generic and better-integrated into the ref_tracker infrastructure.

This adds a new ref_tracker_dir_debugfs() call that subsystems can call
to finalize the name of their dir and register a debugfs file for it.
The last two patches add these calls for the netns and netdev
ref_trackers.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v2:
- Add patch to do %pK -> %p conversion in ref_tracker.c
- Pass in output function to pr_ostream() instead of if statement
- Widen ref_tracker_dir.name to 64 bytes to accomodate unique names
- Eliminate error handling with debugfs manipulation
- Incorporate pointer value into netdev name
- Link to v1: https://lore.kernel.org/r/20250414-reftrack-dbgfs-v1-0-f03585832203@kernel.org

---
Jeff Layton (8):
      ref_tracker: don't use %pK in pr_ostream() output
      ref_tracker: add a top level debugfs directory for ref_tracker
      ref_tracker: have callers pass output function to pr_ostream()
      ref_tracker: allow pr_ostream() to print directly to a seq_file
      ref_tracker: add ability to register a file in debugfs for a ref_tracker_dir
      net: add ref_tracker_dir_debugfs() calls for netns refcount tracking
      ref_tracker: widen the ref_tracker_dir.name field
      net: register debugfs file for net_device refcnt tracker

 include/linux/ref_tracker.h |  15 ++++-
 lib/ref_tracker.c           | 153 +++++++++++++++++++++++++++++++++++++++-----
 net/core/dev.c              |   6 +-
 net/core/net_namespace.c    |  34 +++++++++-
 4 files changed, 190 insertions(+), 18 deletions(-)
---
base-commit: 695caca9345a160ecd9645abab8e70cfe849e9ff
change-id: 20250413-reftrack-dbgfs-3767b303e2fa

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/8] ref_tracker: don't use %pK in pr_ostream() output
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 2/8] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton, Thomas Weißschuh

As Thomas Weißschuh points out [1], it is now preferable to use %p
instead of hashed pointers with printk(), since raw pointers should no
longer be leaked into the kernel log. Change the ref_tracker
infrastructure to use %p instead of %pK in its formats.

[1]: https://lore.kernel.org/netdev/20250414-restricted-pointers-net-v1-0-12af0ce46cdd@linutronix.de/

Cc: "Thomas Weißschuh" <thomas.weissschuh@linutronix.de>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 lib/ref_tracker.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index cf5609b1ca79361763abe5a3a98484a3ee591ff2..de71439e12a3bab6456910986fa611dfbdd97980 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -96,7 +96,7 @@ __ref_tracker_dir_pr_ostream(struct ref_tracker_dir *dir,
 
 	stats = ref_tracker_get_stats(dir, display_limit);
 	if (IS_ERR(stats)) {
-		pr_ostream(s, "%s@%pK: couldn't get stats, error %pe\n",
+		pr_ostream(s, "%s@%p: couldn't get stats, error %pe\n",
 			   dir->name, dir, stats);
 		return;
 	}
@@ -107,13 +107,13 @@ __ref_tracker_dir_pr_ostream(struct ref_tracker_dir *dir,
 		stack = stats->stacks[i].stack_handle;
 		if (sbuf && !stack_depot_snprint(stack, sbuf, STACK_BUF_SIZE, 4))
 			sbuf[0] = 0;
-		pr_ostream(s, "%s@%pK has %d/%d users at\n%s\n", dir->name, dir,
+		pr_ostream(s, "%s@%p has %d/%d users at\n%s\n", dir->name, dir,
 			   stats->stacks[i].count, stats->total, sbuf);
 		skipped -= stats->stacks[i].count;
 	}
 
 	if (skipped)
-		pr_ostream(s, "%s@%pK skipped reports about %d/%d users.\n",
+		pr_ostream(s, "%s@%p skipped reports about %d/%d users.\n",
 			   dir->name, dir, skipped, stats->total);
 
 	kfree(sbuf);

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/8] ref_tracker: add a top level debugfs directory for ref_tracker
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 1/8] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 3/8] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

Add a new "ref_tracker" directory in debugfs. Each individual refcount
tracker can register files under there to display info about
currently-held references.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 lib/ref_tracker.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index de71439e12a3bab6456910986fa611dfbdd97980..a66cde325920780cfe7529ea9d827d0ee943318d 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -12,6 +12,8 @@
 #define REF_TRACKER_STACK_ENTRIES 16
 #define STACK_BUF_SIZE 1024
 
+static struct dentry *ref_tracker_debug_dir = (struct dentry *)-ENOENT;
+
 struct ref_tracker {
 	struct list_head	head;   /* anchor into dir->list or dir->quarantine */
 	bool			dead;
@@ -273,3 +275,17 @@ int ref_tracker_free(struct ref_tracker_dir *dir,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ref_tracker_free);
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+
+static int __init ref_tracker_debugfs_init(void)
+{
+	ref_tracker_debug_dir = debugfs_create_dir("ref_tracker", NULL);
+	if (IS_ERR(ref_tracker_debug_dir))
+		pr_warn("ref_tracker: unable to create debugfs ref_tracker directory: %pe\n",
+			ref_tracker_debug_dir);
+	return 0;
+}
+late_initcall(ref_tracker_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/8] ref_tracker: have callers pass output function to pr_ostream()
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 1/8] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 2/8] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 4/8] ref_tracker: allow pr_ostream() to print directly to a seq_file Jeff Layton
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

In a later patch, we'll be adding a 3rd mechanism for outputting
ref_tracker info via seq_file. Instead of a conditional, have the caller
set a pointer to an output function in struct ostream. As part of this,
the log prefix must be explicitly passed in, as it's too late for the
pr_fmt macro.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 lib/ref_tracker.c | 53 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index a66cde325920780cfe7529ea9d827d0ee943318d..b6e0a87dd75eddef4d504419c0cf398ea65c19d8 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -64,22 +64,40 @@ ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit)
 	return stats;
 }
 
+#define __ostream_printf __printf(2, 3)
+
 struct ostream {
+	void __ostream_printf (*func)(struct ostream *stream, char *fmt, ...);
+	char *prefix;
 	char *buf;
 	int size, used;
 };
 
+static void __ostream_printf pr_ostream_log(struct ostream *stream, char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	vprintk(fmt, args);
+	va_end(args);
+}
+
+static void __ostream_printf pr_ostream_buf(struct ostream *stream, char *fmt, ...)
+{
+	int ret, len = stream->size - stream->used;
+	va_list args;
+
+	va_start(args, fmt);
+	ret = vsnprintf(stream->buf + stream->used, len, fmt, args);
+	va_end(args);
+	stream->used += min(ret, len);
+}
+
 #define pr_ostream(stream, fmt, args...) \
 ({ \
 	struct ostream *_s = (stream); \
 \
-	if (!_s->buf) { \
-		pr_err(fmt, ##args); \
-	} else { \
-		int ret, len = _s->size - _s->used; \
-		ret = snprintf(_s->buf + _s->used, len, pr_fmt(fmt), ##args); \
-		_s->used += min(ret, len); \
-	} \
+	_s->func(_s, fmt, ##args); \
 })
 
 static void
@@ -98,8 +116,8 @@ __ref_tracker_dir_pr_ostream(struct ref_tracker_dir *dir,
 
 	stats = ref_tracker_get_stats(dir, display_limit);
 	if (IS_ERR(stats)) {
-		pr_ostream(s, "%s@%p: couldn't get stats, error %pe\n",
-			   dir->name, dir, stats);
+		pr_ostream(s, "%s%s@%p: couldn't get stats, error %pe\n",
+			   s->prefix, dir->name, dir, stats);
 		return;
 	}
 
@@ -109,14 +127,15 @@ __ref_tracker_dir_pr_ostream(struct ref_tracker_dir *dir,
 		stack = stats->stacks[i].stack_handle;
 		if (sbuf && !stack_depot_snprint(stack, sbuf, STACK_BUF_SIZE, 4))
 			sbuf[0] = 0;
-		pr_ostream(s, "%s@%p has %d/%d users at\n%s\n", dir->name, dir,
-			   stats->stacks[i].count, stats->total, sbuf);
+		pr_ostream(s, "%s%s@%p has %d/%d users at\n%s\n", s->prefix,
+			   dir->name, dir, stats->stacks[i].count,
+			   stats->total, sbuf);
 		skipped -= stats->stacks[i].count;
 	}
 
 	if (skipped)
-		pr_ostream(s, "%s@%p skipped reports about %d/%d users.\n",
-			   dir->name, dir, skipped, stats->total);
+		pr_ostream(s, "%s%s@%p skipped reports about %d/%d users.\n",
+			   s->prefix, dir->name, dir, skipped, stats->total);
 
 	kfree(sbuf);
 
@@ -126,7 +145,8 @@ __ref_tracker_dir_pr_ostream(struct ref_tracker_dir *dir,
 void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
 				  unsigned int display_limit)
 {
-	struct ostream os = {};
+	struct ostream os = { .func = pr_ostream_log,
+			      .prefix = "ref_tracker: " };
 
 	__ref_tracker_dir_pr_ostream(dir, display_limit, &os);
 }
@@ -145,7 +165,10 @@ EXPORT_SYMBOL(ref_tracker_dir_print);
 
 int ref_tracker_dir_snprint(struct ref_tracker_dir *dir, char *buf, size_t size)
 {
-	struct ostream os = { .buf = buf, .size = size };
+	struct ostream os = { .func = pr_ostream_buf,
+			      .prefix = "ref_tracker: ",
+			      .buf = buf,
+			      .size = size };
 	unsigned long flags;
 
 	spin_lock_irqsave(&dir->lock, flags);

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/8] ref_tracker: allow pr_ostream() to print directly to a seq_file
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (2 preceding siblings ...)
  2025-04-15 18:49 ` [PATCH v2 3/8] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 5/8] ref_tracker: add ability to register a file in debugfs for a ref_tracker_dir Jeff Layton
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

Allow pr_ostream to also output directly to a seq_file without an
intermediate buffer.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 lib/ref_tracker.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index b6e0a87dd75eddef4d504419c0cf398ea65c19d8..4857bcb6d4bf557a0089f51328e75e8209e959e6 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/stacktrace.h>
 #include <linux/stackdepot.h>
+#include <linux/seq_file.h>
 
 #define REF_TRACKER_STACK_ENTRIES 16
 #define STACK_BUF_SIZE 1024
@@ -70,6 +71,7 @@ struct ostream {
 	void __ostream_printf (*func)(struct ostream *stream, char *fmt, ...);
 	char *prefix;
 	char *buf;
+	struct seq_file *seq;
 	int size, used;
 };
 
@@ -93,6 +95,15 @@ static void __ostream_printf pr_ostream_buf(struct ostream *stream, char *fmt, .
 	stream->used += min(ret, len);
 }
 
+static void __ostream_printf pr_ostream_seq(struct ostream *stream, char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	seq_vprintf(stream->seq, fmt, args);
+	va_end(args);
+}
+
 #define pr_ostream(stream, fmt, args...) \
 ({ \
 	struct ostream *_s = (stream); \
@@ -302,6 +313,20 @@ EXPORT_SYMBOL_GPL(ref_tracker_free);
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 
+static int ref_tracker_dir_seq_print(struct ref_tracker_dir *dir, struct seq_file *seq)
+{
+	struct ostream os = { .func = pr_ostream_seq,
+			      .prefix = "",
+			      .seq = seq };
+	unsigned long flags;
+
+	spin_lock_irqsave(&dir->lock, flags);
+	__ref_tracker_dir_pr_ostream(dir, 16, &os);
+	spin_unlock_irqrestore(&dir->lock, flags);
+
+	return os.used;
+}
+
 static int __init ref_tracker_debugfs_init(void)
 {
 	ref_tracker_debug_dir = debugfs_create_dir("ref_tracker", NULL);

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/8] ref_tracker: add ability to register a file in debugfs for a ref_tracker_dir
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (3 preceding siblings ...)
  2025-04-15 18:49 ` [PATCH v2 4/8] ref_tracker: allow pr_ostream() to print directly to a seq_file Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 6/8] net: add ref_tracker_dir_debugfs() calls for netns refcount tracking Jeff Layton
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

Currently, there is no convenient way to see the info that the
ref_tracking infrastructure collects. Add a new function that other
subsystems can optionally call to update the name field in the
ref_tracker_dir and register a corresponding seq_file for it in the
top-level ref_tracker directory.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 include/linux/ref_tracker.h | 13 ++++++++++
 lib/ref_tracker.c           | 59 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index 8eac4f3d52547ccbaf9dcd09962ce80d26fbdff8..77a55a32c067216fa02ba349498f53bd289aee0c 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/stackdepot.h>
+#include <linux/seq_file.h>
 
 struct ref_tracker;
 
@@ -17,6 +18,9 @@ struct ref_tracker_dir {
 	bool			dead;
 	struct list_head	list; /* List of active trackers */
 	struct list_head	quarantine; /* List of dead trackers */
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		*dentry;
+#endif
 	char			name[32];
 #endif
 };
@@ -34,10 +38,15 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 	dir->dead = false;
 	refcount_set(&dir->untracked, 1);
 	refcount_set(&dir->no_tracker, 1);
+#ifdef CONFIG_DEBUG_FS
+	dir->dentry = NULL;
+#endif
 	strscpy(dir->name, name, sizeof(dir->name));
 	stack_depot_init();
 }
 
+void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir, const char *name);
+
 void ref_tracker_dir_exit(struct ref_tracker_dir *dir);
 
 void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
@@ -62,6 +71,10 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 {
 }
 
+static inline void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir, const char *name)
+{
+}
+
 static inline void ref_tracker_dir_exit(struct ref_tracker_dir *dir)
 {
 }
diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index 4857bcb6d4bf557a0089f51328e75e8209e959e6..f47ff67f24ef4b84bd9ce8d027559509e3e5fcfa 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -31,6 +31,14 @@ struct ref_tracker_dir_stats {
 	} stacks[];
 };
 
+#ifdef CONFIG_DEBUG_FS
+static void ref_tracker_debugfs_remove(struct ref_tracker_dir *dir);
+#else
+static inline void ref_tracker_debugfs_remove(struct ref_tracker_dir *dir)
+{
+}
+#endif
+
 static struct ref_tracker_dir_stats *
 ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit)
 {
@@ -197,6 +205,7 @@ void ref_tracker_dir_exit(struct ref_tracker_dir *dir)
 	bool leak = false;
 
 	dir->dead = true;
+	ref_tracker_debugfs_remove(dir);
 	spin_lock_irqsave(&dir->lock, flags);
 	list_for_each_entry_safe(tracker, n, &dir->quarantine, head) {
 		list_del(&tracker->head);
@@ -327,6 +336,56 @@ static int ref_tracker_dir_seq_print(struct ref_tracker_dir *dir, struct seq_fil
 	return os.used;
 }
 
+static int ref_tracker_debugfs_show(struct seq_file *f, void *v)
+{
+	struct ref_tracker_dir *dir = f->private;
+
+	return ref_tracker_dir_seq_print(dir, f);
+}
+
+static int ref_tracker_debugfs_open(struct inode *inode, struct file *filp)
+{
+	struct ref_tracker_dir *dir = inode->i_private;
+
+	return single_open(filp, ref_tracker_debugfs_show, dir);
+}
+
+static const struct file_operations ref_tracker_debugfs_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ref_tracker_debugfs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/**
+ * ref_tracker_dir_debugfs - create debugfs file for ref_tracker_dir
+ * @dir: ref_tracker_dir to finalize
+ * @name: updated name of the ref_tracker_dir
+ *
+ * In some cases, the name given to a ref_tracker_dir is based on incomplete information,
+ * and may not be unique. Call this to finalize the name of @dir, and create a debugfs
+ * file for it. If the name is not unique, a warning will be emitted but it is not fatal
+ * to the tracker.
+ */
+void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir, const char *name)
+{
+	strscpy(dir->name, name, sizeof(dir->name));
+
+	dir->dentry = debugfs_create_file(dir->name, S_IFREG | 0400,
+					  ref_tracker_debug_dir, dir,
+					  &ref_tracker_debugfs_fops);
+	if (IS_ERR(dir->dentry))
+		pr_warn("ref_tracker: unable to create debugfs file for %s: %pe\n",
+			dir->name, dir->dentry);
+}
+EXPORT_SYMBOL(ref_tracker_dir_debugfs);
+
+static void ref_tracker_debugfs_remove(struct ref_tracker_dir *dir)
+{
+	debugfs_remove(dir->dentry);
+}
+
 static int __init ref_tracker_debugfs_init(void)
 {
 	ref_tracker_debug_dir = debugfs_create_dir("ref_tracker", NULL);

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/8] net: add ref_tracker_dir_debugfs() calls for netns refcount tracking
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (4 preceding siblings ...)
  2025-04-15 18:49 ` [PATCH v2 5/8] ref_tracker: add ability to register a file in debugfs for a ref_tracker_dir Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-16  1:52   ` Kuniyuki Iwashima
  2025-04-15 18:49 ` [PATCH v2 7/8] ref_tracker: widen the ref_tracker_dir.name field Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 8/8] net: register debugfs file for net_device refcnt tracker Jeff Layton
  7 siblings, 1 reply; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

After assigning the inode number to the namespace, use it to create a
unique name for each netns refcount tracker and register the debugfs
files for them.

The init_net is registered early in the boot process before the
ref_tracker dir is created, so add a late_initcall() to register its
files.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 net/core/net_namespace.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 4303f2a4926243e2c0ff0c0387383cd8e0658019..f636eb9b8eba28114fd192d64bcd359a25381988 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -761,12 +761,44 @@ struct net *get_net_ns_by_pid(pid_t pid)
 }
 EXPORT_SYMBOL_GPL(get_net_ns_by_pid);
 
+#ifdef CONFIG_NET_NS_REFCNT_TRACKER
+static void net_ns_net_debugfs(struct net *net)
+{
+	char name[32];
+	size_t len;
+
+	len = snprintf(name, sizeof(name), "netns-%u-refcnt", net->ns.inum);
+	if (len < sizeof(name))
+		ref_tracker_dir_debugfs(&net->refcnt_tracker, name);
+
+	len = snprintf(name, sizeof(name), "netns-%u-notrefcnt", net->ns.inum);
+	if (len < sizeof(name))
+		ref_tracker_dir_debugfs(&net->notrefcnt_tracker, name);
+}
+
+static int __init init_net_debugfs(void)
+{
+	net_ns_net_debugfs(&init_net);
+	return 0;
+}
+late_initcall(init_net_debugfs);
+#else
+static void net_ns_net_debugfs(struct net *net)
+{
+}
+#endif
+
 static __net_init int net_ns_net_init(struct net *net)
 {
+	int ret;
+
 #ifdef CONFIG_NET_NS
 	net->ns.ops = &netns_operations;
 #endif
-	return ns_alloc_inum(&net->ns);
+	ret = ns_alloc_inum(&net->ns);
+	if (!ret)
+		net_ns_net_debugfs(net);
+	return ret;
 }
 
 static __net_exit void net_ns_net_exit(struct net *net)

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 7/8] ref_tracker: widen the ref_tracker_dir.name field
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (5 preceding siblings ...)
  2025-04-15 18:49 ` [PATCH v2 6/8] net: add ref_tracker_dir_debugfs() calls for netns refcount tracking Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-15 18:49 ` [PATCH v2 8/8] net: register debugfs file for net_device refcnt tracker Jeff Layton
  7 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

Currently it's 32 bytes, but with the need to move to unique names for
debugfs files, that's inadequate. Move to a 64 byte name field.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 include/linux/ref_tracker.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index 77a55a32c067216fa02ba349498f53bd289aee0c..be3e43127843f710c22aadb47612e07ce9eeeacd 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -21,7 +21,7 @@ struct ref_tracker_dir {
 #ifdef CONFIG_DEBUG_FS
 	struct dentry		*dentry;
 #endif
-	char			name[32];
+	char			name[64];
 #endif
 };
 

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 8/8] net: register debugfs file for net_device refcnt tracker
  2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (6 preceding siblings ...)
  2025-04-15 18:49 ` [PATCH v2 7/8] ref_tracker: widen the ref_tracker_dir.name field Jeff Layton
@ 2025-04-15 18:49 ` Jeff Layton
  2025-04-16  2:00   ` Kuniyuki Iwashima
  7 siblings, 1 reply; 11+ messages in thread
From: Jeff Layton @ 2025-04-15 18:49 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, Jeff Layton

As a nearly-final step in register_netdevice(), finalize the name in the
refcount tracker, and register a debugfs file for it.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 net/core/dev.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 2f7f5fd9ffec7c0fc219eb6ba57d57a55134186e..a87488e127ed13fded156023de676851826a1a8f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -10834,8 +10834,9 @@ static void netdev_free_phy_link_topology(struct net_device *dev)
  */
 int register_netdevice(struct net_device *dev)
 {
-	int ret;
 	struct net *net = dev_net(dev);
+	char name[64];
+	int ret;
 
 	BUILD_BUG_ON(sizeof(netdev_features_t) * BITS_PER_BYTE <
 		     NETDEV_FEATURE_COUNT);
@@ -10994,6 +10995,9 @@ int register_netdevice(struct net_device *dev)
 	    dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
 		rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL, 0, NULL);
 
+	/* Register debugfs file for the refcount tracker */
+	if (snprintf(name, sizeof(name), "netdev-%s@%p", dev->name, dev) < sizeof(name))
+		ref_tracker_dir_debugfs(&dev->refcnt_tracker, name);
 out:
 	return ret;
 

-- 
2.49.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/8] net: add ref_tracker_dir_debugfs() calls for netns refcount tracking
  2025-04-15 18:49 ` [PATCH v2 6/8] net: add ref_tracker_dir_debugfs() calls for netns refcount tracking Jeff Layton
@ 2025-04-16  1:52   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 11+ messages in thread
From: Kuniyuki Iwashima @ 2025-04-16  1:52 UTC (permalink / raw)
  To: jlayton
  Cc: akpm, andrew, davem, edumazet, horms, kuba, kuniyu, linux-kernel,
	nathan, netdev, pabeni, qasdev00

From: Jeff Layton <jlayton@kernel.org>
Date: Tue, 15 Apr 2025 14:49:44 -0400
> After assigning the inode number to the namespace, use it to create a
> unique name for each netns refcount tracker and register the debugfs
> files for them.
> 
> The init_net is registered early in the boot process before the
> ref_tracker dir is created, so add a late_initcall() to register its
> files.
> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  net/core/net_namespace.c | 34 +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
> index 4303f2a4926243e2c0ff0c0387383cd8e0658019..f636eb9b8eba28114fd192d64bcd359a25381988 100644
> --- a/net/core/net_namespace.c
> +++ b/net/core/net_namespace.c
> @@ -761,12 +761,44 @@ struct net *get_net_ns_by_pid(pid_t pid)
>  }
>  EXPORT_SYMBOL_GPL(get_net_ns_by_pid);
>  
> +#ifdef CONFIG_NET_NS_REFCNT_TRACKER
> +static void net_ns_net_debugfs(struct net *net)
> +{
> +	char name[32];

Perhaps define REF_TRACKER_NAMESZ (I'm really bad at naming) and reuse
it in the next two patches ?

Otherwise looks good to me.

Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 8/8] net: register debugfs file for net_device refcnt tracker
  2025-04-15 18:49 ` [PATCH v2 8/8] net: register debugfs file for net_device refcnt tracker Jeff Layton
@ 2025-04-16  2:00   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 11+ messages in thread
From: Kuniyuki Iwashima @ 2025-04-16  2:00 UTC (permalink / raw)
  To: jlayton
  Cc: akpm, andrew, davem, edumazet, horms, kuba, kuniyu, linux-kernel,
	nathan, netdev, pabeni, qasdev00

From: Jeff Layton <jlayton@kernel.org>
Date: Tue, 15 Apr 2025 14:49:46 -0400
> As a nearly-final step in register_netdevice(), finalize the name in the
> refcount tracker, and register a debugfs file for it.
> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  net/core/dev.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 2f7f5fd9ffec7c0fc219eb6ba57d57a55134186e..a87488e127ed13fded156023de676851826a1a8f 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -10834,8 +10834,9 @@ static void netdev_free_phy_link_topology(struct net_device *dev)
>   */
>  int register_netdevice(struct net_device *dev)
>  {
> -	int ret;
>  	struct net *net = dev_net(dev);
> +	char name[64];
> +	int ret;
>  
>  	BUILD_BUG_ON(sizeof(netdev_features_t) * BITS_PER_BYTE <
>  		     NETDEV_FEATURE_COUNT);
> @@ -10994,6 +10995,9 @@ int register_netdevice(struct net_device *dev)
>  	    dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
>  		rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL, 0, NULL);
>  
> +	/* Register debugfs file for the refcount tracker */
> +	if (snprintf(name, sizeof(name), "netdev-%s@%p", dev->name, dev) < sizeof(name))

Given IFNAMSIZ is 16, using WARN_ON_ONCE() and calling
ref_tracker_dir_debugfs() unconditionally would be better
to catch future regression with syzbot.

Also, this hunk conflicts with

commit 097f171f98289cf737437599c40b0d1e81266e9e
Author: Jakub Kicinski <kuba@kernel.org>
Date:   Wed Apr 9 18:42:46 2025 -0700

    net: convert dev->rtnl_link_state to a bool


> +		ref_tracker_dir_debugfs(&dev->refcnt_tracker, name);
>  out:
>  	return ret;
>  
> 
> -- 
> 2.49.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-04-16  2:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-15 18:49 [PATCH v2 0/8] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
2025-04-15 18:49 ` [PATCH v2 1/8] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
2025-04-15 18:49 ` [PATCH v2 2/8] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
2025-04-15 18:49 ` [PATCH v2 3/8] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
2025-04-15 18:49 ` [PATCH v2 4/8] ref_tracker: allow pr_ostream() to print directly to a seq_file Jeff Layton
2025-04-15 18:49 ` [PATCH v2 5/8] ref_tracker: add ability to register a file in debugfs for a ref_tracker_dir Jeff Layton
2025-04-15 18:49 ` [PATCH v2 6/8] net: add ref_tracker_dir_debugfs() calls for netns refcount tracking Jeff Layton
2025-04-16  1:52   ` Kuniyuki Iwashima
2025-04-15 18:49 ` [PATCH v2 7/8] ref_tracker: widen the ref_tracker_dir.name field Jeff Layton
2025-04-15 18:49 ` [PATCH v2 8/8] net: register debugfs file for net_device refcnt tracker Jeff Layton
2025-04-16  2:00   ` Kuniyuki Iwashima

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox