linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir
@ 2025-05-29 15:20 Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once Jeff Layton
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton,
	Thomas Weißschuh

Sorry for the reposting, but this makes things easier with automated CI.

This posting just drops the pr_warn() calls from the new functions. We
were still seeing some warnings during (expected) times that debugfs
file creation would fail. debugfs already throws warnings when these
things fail unexpectedly, so these warnings are unwanted when dentry
creation fails before debugfs is up.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v12:
- drop redundant pr_warn() calls. Debugfs already warns when these ops fail
- Link to v11: https://lore.kernel.org/r/20250528-reftrack-dbgfs-v11-0-94ae0b165841@kernel.org

Changes in v11:
- don't call ref_tracker_dir_init() more than once for same i915 objects
- use %llx in format for net_cookie in symlink name
- Link to v10: https://lore.kernel.org/r/20250527-reftrack-dbgfs-v10-0-dc55f7705691@kernel.org

Changes in v10:
- drop the i915 symlink patch
- Link to v9: https://lore.kernel.org/r/20250509-reftrack-dbgfs-v9-0-8ab888a4524d@kernel.org

Changes in v9:
- fix typo in ref_tracker_dir_init() kerneldoc header
- Link to v8: https://lore.kernel.org/r/20250507-reftrack-dbgfs-v8-0-607717d3bb98@kernel.org

Changes in v8:
- fix up compiler warnings that the KTR warned about
- ensure builds with CONFIG_DEBUG_FS=n and CONFIG_REF_TRACKER=y work
- Link to v7: https://lore.kernel.org/r/20250505-reftrack-dbgfs-v7-0-f78c5d97bcca@kernel.org

Changes in v7:
- include net->net_cookie in netns symlink name
- add __ostream_printf to ref_tracker_dir_symlink() stub function
- remove unneeded #include of seq_file.h
- Link to v6: https://lore.kernel.org/r/20250430-reftrack-dbgfs-v6-0-867c29aff03a@kernel.org

Changes in v6:
- clean up kerneldoc comment for ref_tracker_dir_debugfs()
- add missing stub function for ref_tracker_dir_symlink()
- temporary __maybe_unused on ref_tracker_dir_seq_print() to silence compiler warning
- Link to v5: https://lore.kernel.org/r/20250428-reftrack-dbgfs-v5-0-1cbbdf2038bd@kernel.org

Changes in v5:
- add class string to each ref_tracker_dir
- auto-register debugfs file for every tracker in ref_tracker_dir_init
- add function to allow adding a symlink for each tracker
- add patches to create symlinks for netns's and i915 entries
- change output format to print class@%p instead of name@%p
- eliminate the name field in ref_tracker_dir
- fix off-by-one bug when NULL terminating name string
- Link to v4: https://lore.kernel.org/r/20250418-reftrack-dbgfs-v4-0-5ca5c7899544@kernel.org

Changes in v4:
- Drop patch to widen ref_tracker_dir_.name, use NAME_MAX+1 (256) instead since this only affects dentry name
- Link to v3: https://lore.kernel.org/r/20250417-reftrack-dbgfs-v3-0-c3159428c8fb@kernel.org

Changes in v3:
- don't overwrite dir->name in ref_tracker_dir_debugfs
- define REF_TRACKER_NAMESZ and use it when setting name
- Link to v2: https://lore.kernel.org/r/20250415-reftrack-dbgfs-v2-0-b18c4abd122f@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 (10):
      i915: only initialize struct ref_tracker_dir once
      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: add a static classname string to each ref_tracker_dir
      ref_tracker: allow pr_ostream() to print directly to a seq_file
      ref_tracker: automatically register a file in debugfs for a ref_tracker_dir
      ref_tracker: add a way to create a symlink to the ref_tracker_dir debugfs file
      net: add symlinks to ref_tracker_dir for netns
      ref_tracker: eliminate the ref_tracker_dir name field

 drivers/gpu/drm/display/drm_dp_tunnel.c |   2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c |   4 +-
 drivers/gpu/drm/i915/intel_wakeref.c    |   3 +-
 include/linux/ref_tracker.h             |  58 ++++++++++-
 lib/ref_tracker.c                       | 175 +++++++++++++++++++++++++++++---
 net/core/dev.c                          |   2 +-
 net/core/net_namespace.c                |  34 ++++++-
 7 files changed, 252 insertions(+), 26 deletions(-)
---
base-commit: 90b83efa6701656e02c86e7df2cb1765ea602d07
change-id: 20250413-reftrack-dbgfs-3767b303e2fa

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


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

* [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-30 11:01   ` Krzysztof Karas
  2025-05-29 15:20 ` [PATCH v12 02/10] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

I got some warnings from the i915 CI with the ref_tracker debugfs
patches applied, that indicated that these ref_tracker_dir_init() calls
were being called more than once. If references were held on these
objects between the initializations, then that could lead to leaked ref
tracking objects.

Since these objects are zalloc'ed, ensure that they are only initialized
once by testing whether the first byte of the name field is 0.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 drivers/gpu/drm/i915/intel_runtime_pm.c | 3 ++-
 drivers/gpu/drm/i915/intel_wakeref.c    | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 8d9f4c410546e4144d4bc8bbc6696f3bd9498848..1b2ad1e0aef7d317f63a23b39193ea81c90401f0 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -59,7 +59,8 @@ static struct drm_i915_private *rpm_to_i915(struct intel_runtime_pm *rpm)
 
 static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
 {
-	ref_tracker_dir_init(&rpm->debug, INTEL_REFTRACK_DEAD_COUNT, dev_name(rpm->kdev));
+	if (!rpm->debug.name[0])
+		ref_tracker_dir_init(&rpm->debug, INTEL_REFTRACK_DEAD_COUNT, dev_name(rpm->kdev));
 }
 
 static intel_wakeref_t
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index 07e81be4d3920febece34709c63a63204a41583c..3cfd68c98023fef75faa4dd69eba55e093130dd7 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -114,7 +114,8 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 			 "wakeref.work", &key->work, 0);
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF)
-	ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, name);
+	if (!wf->debug.name[0])
+		ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, name);
 #endif
 }
 

-- 
2.49.0


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

* [PATCH v12 02/10] ref_tracker: don't use %pK in pr_ostream() output
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-30 11:03   ` Krzysztof Karas
  2025-05-29 15:20 ` [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, 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>
Reviewed-by: 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] 20+ messages in thread

* [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 02/10] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-30 11:05   ` Krzysztof Karas
  2025-06-04  9:12   ` Jani Nikula
  2025-05-29 15:20 ` [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
                   ` (7 subsequent siblings)
  10 siblings, 2 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, 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.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 lib/ref_tracker.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index de71439e12a3bab6456910986fa611dfbdd97980..d374e5273e1497cac0d70c02c282baa2c3ab63fe 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -273,3 +273,16 @@ 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 struct dentry *ref_tracker_debug_dir = (struct dentry *)-ENOENT;
+
+static int __init ref_tracker_debugfs_init(void)
+{
+	ref_tracker_debug_dir = debugfs_create_dir("ref_tracker", NULL);
+	return 0;
+}
+late_initcall(ref_tracker_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */

-- 
2.49.0


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

* [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream()
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (2 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-30 11:13   ` Krzysztof Karas
  2025-05-29 15:20 ` [PATCH v12 05/10] ref_tracker: add a static classname string to each ref_tracker_dir Jeff Layton
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, 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.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 include/linux/ref_tracker.h |  2 ++
 lib/ref_tracker.c           | 51 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index 8eac4f3d52547ccbaf9dcd09962ce80d26fbdff8..a0a1ee43724ffa00e60c116be18e481bfe1d1455 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -6,6 +6,8 @@
 #include <linux/spinlock.h>
 #include <linux/stackdepot.h>
 
+#define __ostream_printf __printf(2, 3)
+
 struct ref_tracker;
 
 struct ref_tracker_dir {
diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index d374e5273e1497cac0d70c02c282baa2c3ab63fe..4f2112b001de3049ed542ea3c4f2bc1e9cce6043 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -63,21 +63,37 @@ ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit)
 }
 
 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
@@ -96,8 +112,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;
 	}
 
@@ -107,14 +123,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);
 
@@ -124,7 +141,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);
 }
@@ -143,7 +161,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] 20+ messages in thread

* [PATCH v12 05/10] ref_tracker: add a static classname string to each ref_tracker_dir
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (3 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 06/10] ref_tracker: allow pr_ostream() to print directly to a seq_file Jeff Layton
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

A later patch in the series will be adding debugfs files for each
ref_tracker that get created in ref_tracker_dir_init(). The format will
be "class@%px". The current "name" string can vary between
ref_tracker_dir objects of the same type, so it's not suitable for this
purpose.

Add a new "class" string to the ref_tracker dir that describes the
the type of object (sans any individual info for that object).

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 drivers/gpu/drm/display/drm_dp_tunnel.c | 2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 5 +++--
 drivers/gpu/drm/i915/intel_wakeref.c    | 4 ++--
 include/linux/ref_tracker.h             | 4 ++++
 lib/test_ref_tracker.c                  | 2 +-
 net/core/dev.c                          | 2 +-
 net/core/net_namespace.c                | 4 ++--
 7 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c
index 076edf1610480275c62395334ab0536befa42f15..b9c12b8bf2a3e400b6d8e9d184145834c603b9e1 100644
--- a/drivers/gpu/drm/display/drm_dp_tunnel.c
+++ b/drivers/gpu/drm/display/drm_dp_tunnel.c
@@ -1920,7 +1920,7 @@ drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
 	}
 
 #ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG
-	ref_tracker_dir_init(&mgr->ref_tracker, 16, "dptun");
+	ref_tracker_dir_init(&mgr->ref_tracker, 16, "drm_dptun", "dptun");
 #endif
 
 	for (i = 0; i < max_group_count; i++) {
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 1b2ad1e0aef7d317f63a23b39193ea81c90401f0..90d90145a1890bf788e789858ddad3b3d8e3b978 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -59,8 +59,9 @@ static struct drm_i915_private *rpm_to_i915(struct intel_runtime_pm *rpm)
 
 static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
 {
-	if (!rpm->debug.name[0])
-		ref_tracker_dir_init(&rpm->debug, INTEL_REFTRACK_DEAD_COUNT, dev_name(rpm->kdev));
+	if (!rpm->debug.class)
+		ref_tracker_dir_init(&rpm->debug, INTEL_REFTRACK_DEAD_COUNT,
+				     "intel_runtime_pm", dev_name(rpm->kdev));
 }
 
 static intel_wakeref_t
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index 3cfd68c98023fef75faa4dd69eba55e093130dd7..21dcee7c9a659ac1fb0aa19f3018647be3bda754 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -114,8 +114,8 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 			 "wakeref.work", &key->work, 0);
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF)
-	if (!wf->debug.name[0])
-		ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, name);
+	if (!wf->debug.class)
+		ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, "intel_wakeref", name);
 #endif
 }
 
diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index a0a1ee43724ffa00e60c116be18e481bfe1d1455..3968f993db81e95c0d58c81454311841c1b9cd35 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -19,6 +19,7 @@ struct ref_tracker_dir {
 	bool			dead;
 	struct list_head	list; /* List of active trackers */
 	struct list_head	quarantine; /* List of dead trackers */
+	const char		*class; /* object classname */
 	char			name[32];
 #endif
 };
@@ -27,6 +28,7 @@ struct ref_tracker_dir {
 
 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 					unsigned int quarantine_count,
+					const char *class,
 					const char *name)
 {
 	INIT_LIST_HEAD(&dir->list);
@@ -36,6 +38,7 @@ 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);
+	dir->class = class;
 	strscpy(dir->name, name, sizeof(dir->name));
 	stack_depot_init();
 }
@@ -60,6 +63,7 @@ int ref_tracker_free(struct ref_tracker_dir *dir,
 
 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 					unsigned int quarantine_count,
+					const char *class,
 					const char *name)
 {
 }
diff --git a/lib/test_ref_tracker.c b/lib/test_ref_tracker.c
index b983ceb12afcb84ad60360a1e6fec0072e78ef79..d263502a4c1db248f64a66a468e96c8e4cffab25 100644
--- a/lib/test_ref_tracker.c
+++ b/lib/test_ref_tracker.c
@@ -64,7 +64,7 @@ static int __init test_ref_tracker_init(void)
 {
 	int i;
 
-	ref_tracker_dir_init(&ref_dir, 100, "selftest");
+	ref_tracker_dir_init(&ref_dir, 100, "selftest", "selftest");
 
 	timer_setup(&test_ref_tracker_timer, test_ref_tracker_timer_func, 0);
 	mod_timer(&test_ref_tracker_timer, jiffies + 1);
diff --git a/net/core/dev.c b/net/core/dev.c
index 2b514d95c528b8d6da8f34a8955da76117958b63..eeb6aab16987dde277314d1a6b5bd32eaabab893 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -11714,7 +11714,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 
 	dev->priv_len = sizeof_priv;
 
-	ref_tracker_dir_init(&dev->refcnt_tracker, 128, name);
+	ref_tracker_dir_init(&dev->refcnt_tracker, 128, "netdev", name);
 #ifdef CONFIG_PCPU_DEV_REFCNT
 	dev->pcpu_refcnt = alloc_percpu(int);
 	if (!dev->pcpu_refcnt)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 42ee7fce3d95b5a2756d6a3780edba070f01ddb6..8708eb975295ffb78de35fcf4abef7cc281f5a51 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -403,8 +403,8 @@ static __net_init void preinit_net(struct net *net, struct user_namespace *user_
 {
 	refcount_set(&net->passive, 1);
 	refcount_set(&net->ns.count, 1);
-	ref_tracker_dir_init(&net->refcnt_tracker, 128, "net refcnt");
-	ref_tracker_dir_init(&net->notrefcnt_tracker, 128, "net notrefcnt");
+	ref_tracker_dir_init(&net->refcnt_tracker, 128, "net_refcnt", "net_refcnt");
+	ref_tracker_dir_init(&net->notrefcnt_tracker, 128, "net_notrefcnt", "net_notrefcnt");
 
 	get_random_bytes(&net->hash_mix, sizeof(u32));
 	net->dev_base_seq = 1;

-- 
2.49.0


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

* [PATCH v12 06/10] ref_tracker: allow pr_ostream() to print directly to a seq_file
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (4 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 05/10] ref_tracker: add a static classname string to each ref_tracker_dir Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 07/10] ref_tracker: automatically register a file in debugfs for a ref_tracker_dir Jeff Layton
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

Allow pr_ostream to also output directly to a seq_file without an
intermediate buffer. The first caller of +ref_tracker_dir_seq_print()
will come in a later patch, so mark that __maybe_unused for now. That
designation will be removed once it is used.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 lib/ref_tracker.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index 4f2112b001de3049ed542ea3c4f2bc1e9cce6043..5fed791da84f523500d2edf262fbb20adbd921bc 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
@@ -66,6 +67,7 @@ struct ostream {
 	void __ostream_printf (*func)(struct ostream *stream, char *fmt, ...);
 	char *prefix;
 	char *buf;
+	struct seq_file *seq;
 	int size, used;
 };
 
@@ -300,6 +302,30 @@ EXPORT_SYMBOL_GPL(ref_tracker_free);
 
 static struct dentry *ref_tracker_debug_dir = (struct dentry *)-ENOENT;
 
+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);
+}
+
+static __maybe_unused 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] 20+ messages in thread

* [PATCH v12 07/10] ref_tracker: automatically register a file in debugfs for a ref_tracker_dir
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (5 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 06/10] ref_tracker: allow pr_ostream() to print directly to a seq_file Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 08/10] ref_tracker: add a way to create a symlink to the ref_tracker_dir debugfs file Jeff Layton
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

Currently, there is no convenient way to see the info that the
ref_tracking infrastructure collects. Attempt to create a file in
debugfs when called from ref_tracker_dir_init().

The file is given the name "class@%px", as having the unmodified address
is helpful for debugging. This should be safe since this directory is only
accessible by root

If debugfs file creation fails, a pr_warn will be isssued.

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

diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index 3968f993db81e95c0d58c81454311841c1b9cd35..dd289fdda12b1a10197912f5796f97002e785aaf 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -20,12 +20,27 @@ struct ref_tracker_dir {
 	struct list_head	list; /* List of active trackers */
 	struct list_head	quarantine; /* List of dead trackers */
 	const char		*class; /* object classname */
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		*dentry;
+#endif
 	char			name[32];
 #endif
 };
 
 #ifdef CONFIG_REF_TRACKER
 
+#ifdef CONFIG_DEBUG_FS
+
+void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir);
+
+#else /* CONFIG_DEBUG_FS */
+
+static inline void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 					unsigned int quarantine_count,
 					const char *class,
@@ -39,7 +54,11 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 	refcount_set(&dir->untracked, 1);
 	refcount_set(&dir->no_tracker, 1);
 	dir->class = class;
+#ifdef CONFIG_DEBUG_FS
+	dir->dentry = NULL;
+#endif
 	strscpy(dir->name, name, sizeof(dir->name));
+	ref_tracker_dir_debugfs(dir);
 	stack_depot_init();
 }
 
@@ -68,6 +87,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)
+{
+}
+
 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 5fed791da84f523500d2edf262fbb20adbd921bc..aed35a898466888fcb4e4186774933f54793008a 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -29,6 +29,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)
 {
@@ -184,6 +192,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);
@@ -311,8 +320,7 @@ static void __ostream_printf pr_ostream_seq(struct ostream *stream, char *fmt, .
 	va_end(args);
 }
 
-static __maybe_unused int
-ref_tracker_dir_seq_print(struct ref_tracker_dir *dir, struct seq_file *seq)
+static int ref_tracker_dir_seq_print(struct ref_tracker_dir *dir, struct seq_file *seq)
 {
 	struct ostream os = { .func = pr_ostream_seq,
 			      .prefix = "",
@@ -326,6 +334,61 @@ ref_tracker_dir_seq_print(struct ref_tracker_dir *dir, struct seq_file *seq)
 	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 be associated with debugfs file
+ *
+ * In most cases, a debugfs file will be created automatically for every
+ * ref_tracker_dir. If the object was created before debugfs is brought up
+ * then that may fail. In those cases, it is safe to call this at a later
+ * time to create the file.
+ */
+void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir)
+{
+	char name[NAME_MAX + 1];
+	int ret;
+
+	/* No-op if already created */
+	if (!IS_ERR_OR_NULL(dir->dentry))
+		return;
+
+	ret = snprintf(name, sizeof(name), "%s@%px", dir->class, dir);
+	name[sizeof(name) - 1] = '\0';
+
+	if (ret < sizeof(name))
+		dir->dentry = debugfs_create_file(name, S_IFREG | 0400,
+						  ref_tracker_debug_dir, dir,
+						  &ref_tracker_debugfs_fops);
+}
+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] 20+ messages in thread

* [PATCH v12 08/10] ref_tracker: add a way to create a symlink to the ref_tracker_dir debugfs file
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (6 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 07/10] ref_tracker: automatically register a file in debugfs for a ref_tracker_dir Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 09/10] net: add symlinks to ref_tracker_dir for netns Jeff Layton
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

Add the ability for a subsystem to add a user-friendly symlink that
points to a ref_tracker_dir's debugfs file.

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

diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index dd289fdda12b1a10197912f5796f97002e785aaf..ddc5a7b2bd84692bbc1e1ae67674ec2c6857e1ec 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -22,6 +22,7 @@ struct ref_tracker_dir {
 	const char		*class; /* object classname */
 #ifdef CONFIG_DEBUG_FS
 	struct dentry		*dentry;
+	struct dentry		*symlink;
 #endif
 	char			name[32];
 #endif
@@ -32,6 +33,7 @@ struct ref_tracker_dir {
 #ifdef CONFIG_DEBUG_FS
 
 void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir);
+void ref_tracker_dir_symlink(struct ref_tracker_dir *dir, const char *fmt, ...);
 
 #else /* CONFIG_DEBUG_FS */
 
@@ -39,6 +41,11 @@ static inline void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir)
 {
 }
 
+static inline __ostream_printf
+void ref_tracker_dir_symlink(struct ref_tracker_dir *dir, const char *fmt, ...)
+{
+}
+
 #endif /* CONFIG_DEBUG_FS */
 
 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
@@ -56,6 +63,7 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 	dir->class = class;
 #ifdef CONFIG_DEBUG_FS
 	dir->dentry = NULL;
+	dir->symlink = NULL;
 #endif
 	strscpy(dir->name, name, sizeof(dir->name));
 	ref_tracker_dir_debugfs(dir);
@@ -91,6 +99,11 @@ static inline void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir)
 {
 }
 
+static inline __ostream_printf
+void ref_tracker_dir_symlink(struct ref_tracker_dir *dir, const char *fmt, ...)
+{
+}
+
 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 aed35a898466888fcb4e4186774933f54793008a..d778820bea952d96c9a1c280dfd6531135bd85e0 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -384,8 +384,30 @@ void ref_tracker_dir_debugfs(struct ref_tracker_dir *dir)
 }
 EXPORT_SYMBOL(ref_tracker_dir_debugfs);
 
+void __ostream_printf ref_tracker_dir_symlink(struct ref_tracker_dir *dir, const char *fmt, ...)
+{
+	char name[NAME_MAX + 1];
+	va_list args;
+	int ret;
+
+	/* Already created, or dentry doesn't exist? Do nothing */
+	if (!IS_ERR_OR_NULL(dir->symlink) || IS_ERR_OR_NULL(dir->dentry))
+		return;
+
+	va_start(args, fmt);
+	ret = vsnprintf(name, sizeof(name), fmt, args);
+	va_end(args);
+	name[sizeof(name) - 1] = '\0';
+
+	if (ret < sizeof(name))
+		dir->symlink = debugfs_create_symlink(name, ref_tracker_debug_dir,
+						      dir->dentry->d_name.name);
+}
+EXPORT_SYMBOL(ref_tracker_dir_symlink);
+
 static void ref_tracker_debugfs_remove(struct ref_tracker_dir *dir)
 {
+	debugfs_remove(dir->symlink);
 	debugfs_remove(dir->dentry);
 }
 

-- 
2.49.0


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

* [PATCH v12 09/10] net: add symlinks to ref_tracker_dir for netns
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (7 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 08/10] ref_tracker: add a way to create a symlink to the ref_tracker_dir debugfs file Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-29 15:20 ` [PATCH v12 10/10] ref_tracker: eliminate the ref_tracker_dir name field Jeff Layton
  2025-05-29 23:24 ` [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jakub Kicinski
  10 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

After assigning the inode number to the namespace, use it to create a
unique name for each netns refcount tracker with the ns.inum and
net_cookie values in it, and register a symlink to the debugfs file for
it.

init_net is registered before the ref_tracker dir is created, so add a
late_initcall() to register its files and symlinks.

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

diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 8708eb975295ffb78de35fcf4abef7cc281f5a51..b2fd9c5635ecf8fccd48f1d5b967a5c6c41cfec4 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -791,12 +791,40 @@ 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)
+{
+	ref_tracker_dir_symlink(&net->refcnt_tracker, "netns-%llx-%u-refcnt",
+				net->net_cookie, net->ns.inum);
+	ref_tracker_dir_symlink(&net->notrefcnt_tracker, "netns-%llx-%u-notrefcnt",
+				net->net_cookie, net->ns.inum);
+}
+
+static int __init init_net_debugfs(void)
+{
+	ref_tracker_dir_debugfs(&init_net.refcnt_tracker);
+	ref_tracker_dir_debugfs(&init_net.notrefcnt_tracker);
+	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] 20+ messages in thread

* [PATCH v12 10/10] ref_tracker: eliminate the ref_tracker_dir name field
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (8 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 09/10] net: add symlinks to ref_tracker_dir for netns Jeff Layton
@ 2025-05-29 15:20 ` Jeff Layton
  2025-05-29 23:24 ` [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jakub Kicinski
  10 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-29 15:20 UTC (permalink / raw)
  To: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

Now that we have dentries and the ability to create meaningful symlinks
to them, don't keep a name string in each tracker. Switch the output
format to print "class@address", and drop the name field.

Also, add a kerneldoc header for ref_tracker_dir_init().

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 drivers/gpu/drm/display/drm_dp_tunnel.c |  2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c |  2 +-
 drivers/gpu/drm/i915/intel_wakeref.c    |  2 +-
 include/linux/ref_tracker.h             | 20 ++++++++++++++------
 lib/ref_tracker.c                       |  6 +++---
 lib/test_ref_tracker.c                  |  2 +-
 net/core/dev.c                          |  2 +-
 net/core/net_namespace.c                |  4 ++--
 8 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c
index b9c12b8bf2a3e400b6d8e9d184145834c603b9e1..1205a4432eb4142344fb6eed1cb5ba5b21ec6953 100644
--- a/drivers/gpu/drm/display/drm_dp_tunnel.c
+++ b/drivers/gpu/drm/display/drm_dp_tunnel.c
@@ -1920,7 +1920,7 @@ drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count)
 	}
 
 #ifdef CONFIG_DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG
-	ref_tracker_dir_init(&mgr->ref_tracker, 16, "drm_dptun", "dptun");
+	ref_tracker_dir_init(&mgr->ref_tracker, 16, "drm_dptun");
 #endif
 
 	for (i = 0; i < max_group_count; i++) {
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 90d90145a1890bf788e789858ddad3b3d8e3b978..7ce3e6de0c1970697e0e58198e1e3852975ee7bc 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -61,7 +61,7 @@ static void init_intel_runtime_pm_wakeref(struct intel_runtime_pm *rpm)
 {
 	if (!rpm->debug.class)
 		ref_tracker_dir_init(&rpm->debug, INTEL_REFTRACK_DEAD_COUNT,
-				     "intel_runtime_pm", dev_name(rpm->kdev));
+				     "intel_runtime_pm");
 }
 
 static intel_wakeref_t
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index 21dcee7c9a659ac1fb0aa19f3018647be3bda754..080535fc71d8c25dcc848eefd063361bbe21b305 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -115,7 +115,7 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF)
 	if (!wf->debug.class)
-		ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, "intel_wakeref", name);
+		ref_tracker_dir_init(&wf->debug, INTEL_REFTRACK_DEAD_COUNT, "intel_wakeref");
 #endif
 }
 
diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h
index ddc5a7b2bd84692bbc1e1ae67674ec2c6857e1ec..5878e7fce712930700054033ff5f21547e75224f 100644
--- a/include/linux/ref_tracker.h
+++ b/include/linux/ref_tracker.h
@@ -24,7 +24,6 @@ struct ref_tracker_dir {
 	struct dentry		*dentry;
 	struct dentry		*symlink;
 #endif
-	char			name[32];
 #endif
 };
 
@@ -48,10 +47,21 @@ void ref_tracker_dir_symlink(struct ref_tracker_dir *dir, const char *fmt, ...)
 
 #endif /* CONFIG_DEBUG_FS */
 
+/**
+ * ref_tracker_dir_init - initialize a ref_tracker dir
+ * @dir: ref_tracker_dir to be initialized
+ * @quarantine_count: max number of entries to be tracked
+ * @class: pointer to static string that describes object type
+ *
+ * Initialize a ref_tracker_dir. If debugfs is configured, then a file
+ * will also be created for it under the top-level ref_tracker debugfs
+ * directory.
+ *
+ * Note that @class must point to a static string.
+ */
 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 					unsigned int quarantine_count,
-					const char *class,
-					const char *name)
+					const char *class)
 {
 	INIT_LIST_HEAD(&dir->list);
 	INIT_LIST_HEAD(&dir->quarantine);
@@ -65,7 +75,6 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 	dir->dentry = NULL;
 	dir->symlink = NULL;
 #endif
-	strscpy(dir->name, name, sizeof(dir->name));
 	ref_tracker_dir_debugfs(dir);
 	stack_depot_init();
 }
@@ -90,8 +99,7 @@ int ref_tracker_free(struct ref_tracker_dir *dir,
 
 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
 					unsigned int quarantine_count,
-					const char *class,
-					const char *name)
+					const char *class)
 {
 }
 
diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
index d778820bea952d96c9a1c280dfd6531135bd85e0..897c5b4aedf7393aca45ed10b5617c81e6f7e6bf 100644
--- a/lib/ref_tracker.c
+++ b/lib/ref_tracker.c
@@ -123,7 +123,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%s@%p: couldn't get stats, error %pe\n",
-			   s->prefix, dir->name, dir, stats);
+			   s->prefix, dir->class, dir, stats);
 		return;
 	}
 
@@ -134,14 +134,14 @@ __ref_tracker_dir_pr_ostream(struct ref_tracker_dir *dir,
 		if (sbuf && !stack_depot_snprint(stack, sbuf, STACK_BUF_SIZE, 4))
 			sbuf[0] = 0;
 		pr_ostream(s, "%s%s@%p has %d/%d users at\n%s\n", s->prefix,
-			   dir->name, dir, stats->stacks[i].count,
+			   dir->class, dir, stats->stacks[i].count,
 			   stats->total, sbuf);
 		skipped -= stats->stacks[i].count;
 	}
 
 	if (skipped)
 		pr_ostream(s, "%s%s@%p skipped reports about %d/%d users.\n",
-			   s->prefix, dir->name, dir, skipped, stats->total);
+			   s->prefix, dir->class, dir, skipped, stats->total);
 
 	kfree(sbuf);
 
diff --git a/lib/test_ref_tracker.c b/lib/test_ref_tracker.c
index d263502a4c1db248f64a66a468e96c8e4cffab25..b983ceb12afcb84ad60360a1e6fec0072e78ef79 100644
--- a/lib/test_ref_tracker.c
+++ b/lib/test_ref_tracker.c
@@ -64,7 +64,7 @@ static int __init test_ref_tracker_init(void)
 {
 	int i;
 
-	ref_tracker_dir_init(&ref_dir, 100, "selftest", "selftest");
+	ref_tracker_dir_init(&ref_dir, 100, "selftest");
 
 	timer_setup(&test_ref_tracker_timer, test_ref_tracker_timer_func, 0);
 	mod_timer(&test_ref_tracker_timer, jiffies + 1);
diff --git a/net/core/dev.c b/net/core/dev.c
index eeb6aab16987dde277314d1a6b5bd32eaabab893..c7c25278267adb338f99407abe4a62d2a9cc3d33 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -11714,7 +11714,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 
 	dev->priv_len = sizeof_priv;
 
-	ref_tracker_dir_init(&dev->refcnt_tracker, 128, "netdev", name);
+	ref_tracker_dir_init(&dev->refcnt_tracker, 128, "netdev");
 #ifdef CONFIG_PCPU_DEV_REFCNT
 	dev->pcpu_refcnt = alloc_percpu(int);
 	if (!dev->pcpu_refcnt)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index b2fd9c5635ecf8fccd48f1d5b967a5c6c41cfec4..8d21c8f4eb83597ddee5fd345b5e38b308ce0335 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -403,8 +403,8 @@ static __net_init void preinit_net(struct net *net, struct user_namespace *user_
 {
 	refcount_set(&net->passive, 1);
 	refcount_set(&net->ns.count, 1);
-	ref_tracker_dir_init(&net->refcnt_tracker, 128, "net_refcnt", "net_refcnt");
-	ref_tracker_dir_init(&net->notrefcnt_tracker, 128, "net_notrefcnt", "net_notrefcnt");
+	ref_tracker_dir_init(&net->refcnt_tracker, 128, "net_refcnt");
+	ref_tracker_dir_init(&net->notrefcnt_tracker, 128, "net_notrefcnt");
 
 	get_random_bytes(&net->hash_mix, sizeof(u32));
 	net->dev_base_seq = 1;

-- 
2.49.0


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

* Re: [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir
  2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
                   ` (9 preceding siblings ...)
  2025-05-29 15:20 ` [PATCH v12 10/10] ref_tracker: eliminate the ref_tracker_dir name field Jeff Layton
@ 2025-05-29 23:24 ` Jakub Kicinski
  10 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2025-05-29 23:24 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
	Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima, Qasim Ijaz,
	Nathan Chancellor, Andrew Lunn, linux-kernel, netdev, dri-devel,
	intel-gfx, Thomas Weißschuh

On Thu, 29 May 2025 11:20:36 -0400 Jeff Layton wrote:
> Sorry for the reposting, but this makes things easier with automated CI.
> 
> This posting just drops the pr_warn() calls from the new functions. We
> were still seeing some warnings during (expected) times that debugfs
> file creation would fail. debugfs already throws warnings when these
> things fail unexpectedly, so these warnings are unwanted when dentry
> creation fails before debugfs is up.

Hm, so FWIW we hit a lockdep issue now
raw:
 https://netdev-3.bots.linux.dev/vmksft-tcp-ao-dbg/results/142540/4-connect-deny-ipv6/stderr
decoded:
https://netdev-3.bots.linux.dev/vmksft-tcp-ao-dbg/results/142540/vm-crash-thr0-10

I suspect this may just be "merge window fun", since we forwarded our
trees to Linus's since your v11?

[   14.281410][    C0] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
[   14.281692][    C0] swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
[   14.281974][    C0] ffffffff9e1c5af8 (pin_fs_lock){+.?.}-{3:3}, at: simple_pin_fs+0x24/0x150
[   14.282373][    C0] {SOFTIRQ-ON-W} state was registered at:
[   14.282614][    C0]   __lock_acquire+0x20b/0x7e0
[   14.282849][    C0]   lock_acquire.part.0+0xb6/0x240
[   14.283072][    C0]   _raw_spin_lock+0x33/0x40
[   14.283298][    C0]   simple_pin_fs+0x24/0x150
[   14.283524][    C0]   start_creating.part.0+0x52/0x310
[   14.283752][    C0]   debugfs_create_dir+0x6a/0x540
[   14.283977][    C0]   component_debug_init+0x17/0x30
[   14.284206][    C0]   do_one_initcall+0x8f/0x1e0
[   14.284451][    C0]   do_initcalls+0x176/0x280
[   14.284679][    C0]   kernel_init_freeable+0x22d/0x300
[   14.284907][    C0]   kernel_init+0x20/0x200
[   14.285131][    C0]   ret_from_fork+0x240/0x320
[   14.285359][    C0]   ret_from_fork_asm+0x1a/0x30
[   14.285580][    C0] irq event stamp: 410868
[   14.285750][    C0] hardirqs last  enabled at (410868): [<ffffffff9cfc332d>] _raw_spin_unlock_irqrestore+0x5d/0x80
[   14.286200][    C0] hardirqs last disabled at (410867): [<ffffffff9cfc300b>] _raw_spin_lock_irqsave+0x5b/0x60
[   14.286653][    C0] softirqs last  enabled at (409604): [<ffffffff9a6877a8>] handle_softirqs+0x358/0x620
[   14.287061][    C0] softirqs last disabled at (409635): [<ffffffff9a687bfa>] __irq_exit_rcu+0xfa/0x160

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

* Re: [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once
  2025-05-29 15:20 ` [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once Jeff Layton
@ 2025-05-30 11:01   ` Krzysztof Karas
  2025-05-30 11:39     ` Jeff Layton
  0 siblings, 1 reply; 20+ messages in thread
From: Krzysztof Karas @ 2025-05-30 11:01 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima,
	Qasim Ijaz, Nathan Chancellor, Andrew Lunn, linux-kernel, netdev,
	dri-devel, intel-gfx

Hi Jeff,

> I got some warnings from the i915 CI with the ref_tracker debugfs
> patches applied, that indicated that these ref_tracker_dir_init() calls
> were being called more than once. If references were held on these
> objects between the initializations, then that could lead to leaked ref
> tracking objects.
> 
> Since these objects are zalloc'ed, ensure that they are only initialized
> once by testing whether the first byte of the name field is 0.

Are you referring to these warnings?
<3> [314.043410] debugfs: File 'intel_wakeref@ffff88815111a308' in directory 'ref_tracker' already present!
<4> [314.043427] ref_tracker: ref_tracker: unable to create debugfs file for intel_wakeref@ffff88815111a308: -EEXIST

I think those might be caused by introduction of:
"ref_tracker: automatically register a file in debugfs for a ref_tracker_dir".

Current version of "ref_tracker: add a static classname string
to each ref_tracker_dir" further in this series should prevent
multiple calls to "ref_tracker_dir_init()", so this patch could
be dropped I think.
If my reasoning is wrong however, then please add a note to the
commit message which explains why this is needed in more detail
or/and move this patch right before it is necessary. Otherwise
it looks like a vague workaround.

Best Regards,
Krzysztof

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

* Re: [PATCH v12 02/10] ref_tracker: don't use %pK in pr_ostream() output
  2025-05-29 15:20 ` [PATCH v12 02/10] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
@ 2025-05-30 11:03   ` Krzysztof Karas
  0 siblings, 0 replies; 20+ messages in thread
From: Krzysztof Karas @ 2025-05-30 11:03 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima,
	Qasim Ijaz, Nathan Chancellor, Andrew Lunn, linux-kernel, netdev,
	dri-devel, intel-gfx, Thomas Weißschuh

Hi Jeff,

> 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>
> Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---

Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>

Best Regards,
Krzysztof

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

* Re: [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker
  2025-05-29 15:20 ` [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
@ 2025-05-30 11:05   ` Krzysztof Karas
  2025-06-04  9:12   ` Jani Nikula
  1 sibling, 0 replies; 20+ messages in thread
From: Krzysztof Karas @ 2025-05-30 11:05 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima,
	Qasim Ijaz, Nathan Chancellor, Andrew Lunn, linux-kernel, netdev,
	dri-devel, intel-gfx

Hi Jeff,

> Add a new "ref_tracker" directory in debugfs. Each individual refcount
> tracker can register files under there to display info about
> currently-held references.
> 
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---

Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>

Best Regards,
Krzysztof

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

* Re: [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream()
  2025-05-29 15:20 ` [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
@ 2025-05-30 11:13   ` Krzysztof Karas
  2025-05-30 11:47     ` Jeff Layton
  0 siblings, 1 reply; 20+ messages in thread
From: Krzysztof Karas @ 2025-05-30 11:13 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima,
	Qasim Ijaz, Nathan Chancellor, Andrew Lunn, linux-kernel, netdev,
	dri-devel, intel-gfx

Hi Jeff,

[...]
> +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);
vsnprintf() technically may return a negative error code.
In that case, we'd be adding some unwanted values to the
stream->used. When we encounter an error we could skip
modifying that field.

> +	va_end(args);
> +	stream->used += min(ret, len);
> +}
> +
[...]

Best Regardsm
Krzysztof

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

* Re: [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once
  2025-05-30 11:01   ` Krzysztof Karas
@ 2025-05-30 11:39     ` Jeff Layton
  0 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-30 11:39 UTC (permalink / raw)
  To: Krzysztof Karas
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima,
	Qasim Ijaz, Nathan Chancellor, Andrew Lunn, linux-kernel, netdev,
	dri-devel, intel-gfx

On Fri, 2025-05-30 at 11:01 +0000, Krzysztof Karas wrote:
> Hi Jeff,
> 
> > I got some warnings from the i915 CI with the ref_tracker debugfs
> > patches applied, that indicated that these ref_tracker_dir_init() calls
> > were being called more than once. If references were held on these
> > objects between the initializations, then that could lead to leaked ref
> > tracking objects.
> > 
> > Since these objects are zalloc'ed, ensure that they are only initialized
> > once by testing whether the first byte of the name field is 0.
> 
> Are you referring to these warnings?
> <3> [314.043410] debugfs: File 'intel_wakeref@ffff88815111a308' in directory 'ref_tracker' already present!
> <4> [314.043427] ref_tracker: ref_tracker: unable to create debugfs file for intel_wakeref@ffff88815111a308: -EEXIST
> 
> I think those might be caused by introduction of:
> "ref_tracker: automatically register a file in debugfs for a ref_tracker_dir".
> 
> Current version of "ref_tracker: add a static classname string
> to each ref_tracker_dir" further in this series should prevent
> multiple calls to "ref_tracker_dir_init()", so this patch could
> be dropped I think.
> If my reasoning is wrong however, then please add a note to the
> commit message which explains why this is needed in more detail
> or/and move this patch right before it is necessary. Otherwise
> it looks like a vague workaround.
> 

I'm fine with dropping this patch.

Those are the messages that demonstrate the problem, but the problem is
potentially bigger than those messages. ref_tracker_dir_init() is being
called (at least) twice:

struct ref_tracker_dir {                                              
#ifdef CONFIG_REF_TRACKER                                             
        spinlock_t              lock;                                 
        unsigned int            quarantine_avail;                     
        refcount_t              untracked;                            
        refcount_t              no_tracker;                           
        bool                    dead;                                 
        struct list_head        list; /* List of active trackers */   
        struct list_head        quarantine; /* List of dead trackers */
        const char              *class; /* object classname */        
#ifdef CONFIG_DEBUG_FS                                                
        struct dentry           *dentry;                              
        struct dentry           *symlink;                             
#endif                                                                
#endif                                                                
}; 

This structure contains two list_heads that can contain ref_tracker
objects. If that list was populated when ref_tracker_dir_init() is
called the second time, then those objects will now be sitting on a
corrupt list. At best they'll just leak, but with them sitting on a
now-corrupt list, they could cause a panic too.

It may be that there can be no objects on that list when it's called
the second time. But with this patchset initializing it twice will
cause dentry leaks at least.
-- 
Jeff Layton <jlayton@kernel.org>

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

* Re: [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream()
  2025-05-30 11:13   ` Krzysztof Karas
@ 2025-05-30 11:47     ` Jeff Layton
  0 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-05-30 11:47 UTC (permalink / raw)
  To: Krzysztof Karas
  Cc: Andrew Morton, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Kuniyuki Iwashima,
	Qasim Ijaz, Nathan Chancellor, Andrew Lunn, linux-kernel, netdev,
	dri-devel, intel-gfx

On Fri, 2025-05-30 at 11:13 +0000, Krzysztof Karas wrote:
> Hi Jeff,
> 
> [...]
> > +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);
> vsnprintf() technically may return a negative error code.
> In that case, we'd be adding some unwanted values to the
> stream->used. When we encounter an error we could skip
> modifying that field.
> 
> > +	va_end(args);
> > +	stream->used += min(ret, len);
> > +}
> > +
> [...]
> 

Good catch. I'll change this to be:

        va_start(args, fmt);
        ret = vsnprintf(stream->buf + stream->used, len, fmt, args);
        va_end(args);
        if (ret > 0)
                stream->used += min(ret, len);

-- 
Jeff Layton <jlayton@kernel.org>

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

* Re: [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker
  2025-05-29 15:20 ` [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
  2025-05-30 11:05   ` Krzysztof Karas
@ 2025-06-04  9:12   ` Jani Nikula
  2025-06-09 18:10     ` Jeff Layton
  1 sibling, 1 reply; 20+ messages in thread
From: Jani Nikula @ 2025-06-04  9:12 UTC (permalink / raw)
  To: Jeff Layton, Andrew Morton, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx, Jeff Layton

On Thu, 29 May 2025, Jeff Layton <jlayton@kernel.org> wrote:
> Add a new "ref_tracker" directory in debugfs. Each individual refcount
> tracker can register files under there to display info about
> currently-held references.
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  lib/ref_tracker.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
> index de71439e12a3bab6456910986fa611dfbdd97980..d374e5273e1497cac0d70c02c282baa2c3ab63fe 100644
> --- a/lib/ref_tracker.c
> +++ b/lib/ref_tracker.c
> @@ -273,3 +273,16 @@ 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 struct dentry *ref_tracker_debug_dir = (struct dentry *)-ENOENT;

Nitpick, please prefer ERR_PTR(-ENOENT) over casting inline.

BR,
Jani.


> +
> +static int __init ref_tracker_debugfs_init(void)
> +{
> +	ref_tracker_debug_dir = debugfs_create_dir("ref_tracker", NULL);
> +	return 0;
> +}
> +late_initcall(ref_tracker_debugfs_init);
> +#endif /* CONFIG_DEBUG_FS */

-- 
Jani Nikula, Intel

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

* Re: [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker
  2025-06-04  9:12   ` Jani Nikula
@ 2025-06-09 18:10     ` Jeff Layton
  0 siblings, 0 replies; 20+ messages in thread
From: Jeff Layton @ 2025-06-09 18:10 UTC (permalink / raw)
  To: Jani Nikula, Andrew Morton, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin
  Cc: Kuniyuki Iwashima, Qasim Ijaz, Nathan Chancellor, Andrew Lunn,
	linux-kernel, netdev, dri-devel, intel-gfx

On Wed, 2025-06-04 at 12:12 +0300, Jani Nikula wrote:
> On Thu, 29 May 2025, Jeff Layton <jlayton@kernel.org> wrote:
> > Add a new "ref_tracker" directory in debugfs. Each individual refcount
> > tracker can register files under there to display info about
> > currently-held references.
> > 
> > Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > ---
> >  lib/ref_tracker.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c
> > index de71439e12a3bab6456910986fa611dfbdd97980..d374e5273e1497cac0d70c02c282baa2c3ab63fe 100644
> > --- a/lib/ref_tracker.c
> > +++ b/lib/ref_tracker.c
> > @@ -273,3 +273,16 @@ 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 struct dentry *ref_tracker_debug_dir = (struct dentry *)-ENOENT;
> 
> Nitpick, please prefer ERR_PTR(-ENOENT) over casting inline.
> 
> 
Sorry I didn't respond to this earlier. I'd prefer that too, but when I
try that, I get:

lib/ref_tracker.c:327:47: error: initializer element is not constant
  327 | static struct dentry *ref_tracker_debug_dir = ERR_PTR(-ENOENT);
      |                                               ^~~~~~~


> 
> > +
> > +static int __init ref_tracker_debugfs_init(void)
> > +{
> > +	ref_tracker_debug_dir = debugfs_create_dir("ref_tracker", NULL);
> > +	return 0;
> > +}
> > +late_initcall(ref_tracker_debugfs_init);
> > +#endif /* CONFIG_DEBUG_FS */

-- 
Jeff Layton <jlayton@kernel.org>

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

end of thread, other threads:[~2025-06-09 18:10 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-29 15:20 [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jeff Layton
2025-05-29 15:20 ` [PATCH v12 01/10] i915: only initialize struct ref_tracker_dir once Jeff Layton
2025-05-30 11:01   ` Krzysztof Karas
2025-05-30 11:39     ` Jeff Layton
2025-05-29 15:20 ` [PATCH v12 02/10] ref_tracker: don't use %pK in pr_ostream() output Jeff Layton
2025-05-30 11:03   ` Krzysztof Karas
2025-05-29 15:20 ` [PATCH v12 03/10] ref_tracker: add a top level debugfs directory for ref_tracker Jeff Layton
2025-05-30 11:05   ` Krzysztof Karas
2025-06-04  9:12   ` Jani Nikula
2025-06-09 18:10     ` Jeff Layton
2025-05-29 15:20 ` [PATCH v12 04/10] ref_tracker: have callers pass output function to pr_ostream() Jeff Layton
2025-05-30 11:13   ` Krzysztof Karas
2025-05-30 11:47     ` Jeff Layton
2025-05-29 15:20 ` [PATCH v12 05/10] ref_tracker: add a static classname string to each ref_tracker_dir Jeff Layton
2025-05-29 15:20 ` [PATCH v12 06/10] ref_tracker: allow pr_ostream() to print directly to a seq_file Jeff Layton
2025-05-29 15:20 ` [PATCH v12 07/10] ref_tracker: automatically register a file in debugfs for a ref_tracker_dir Jeff Layton
2025-05-29 15:20 ` [PATCH v12 08/10] ref_tracker: add a way to create a symlink to the ref_tracker_dir debugfs file Jeff Layton
2025-05-29 15:20 ` [PATCH v12 09/10] net: add symlinks to ref_tracker_dir for netns Jeff Layton
2025-05-29 15:20 ` [PATCH v12 10/10] ref_tracker: eliminate the ref_tracker_dir name field Jeff Layton
2025-05-29 23:24 ` [PATCH v12 00/10] ref_tracker: add ability to register a debugfs file for a ref_tracker_dir Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).