Linux Modules
 help / color / mirror / Atom feed
* [PATCH v14 15/92] dyndbg: refactor param_set_dyndbg_classes and below
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

Refactor callchain below param_set_dyndbg_classes(1) to allow mod-name
specific settings.  Split (1) into upper/lower fns, adding modname
param to lower, and passing NULL in from upper.  Below that, add the
same param to ddebug_apply_class_bitmap(), and pass it thru to
_ddebug_queries(), replacing NULL with the param.

This allows the callchain to update the classmap in just one module,
vs just all as currently done.  While the sysfs param is unlikely to
ever update just one module, the callchain will be used for modprobe
handling, which should update only that just-probed module.

In ddebug_apply_class_bitmap(), also check for actual changes to the
bits before announcing them, to declutter logs.

No functional change.

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/dynamic_debug.c | 65 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 25 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 3ae9ecabdad1..4313c8803007 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -605,9 +605,10 @@ static int ddebug_exec_queries(char *query, const char *modname)
 	return nfound;
 }
 
-/* apply a new bitmap to the sys-knob's current bit-state */
+/* apply a new class-param setting */
 static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
-				     unsigned long *new_bits, unsigned long *old_bits)
+				     unsigned long *new_bits, unsigned long *old_bits,
+				     const char *query_modname)
 {
 #define QUERY_SIZE 128
 	char query[QUERY_SIZE];
@@ -615,7 +616,9 @@ static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
 	int matches = 0;
 	int bi, ct;
 
-	v2pr_info("apply: 0x%lx to: 0x%lx\n", *new_bits, *old_bits);
+	if (*new_bits != *old_bits)
+		v2pr_info("apply bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits,
+			  *old_bits, query_modname ?: "'*'");
 
 	for (bi = 0; bi < map->length; bi++) {
 		if (test_bit(bi, new_bits) == test_bit(bi, old_bits))
@@ -624,12 +627,16 @@ static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
 		snprintf(query, QUERY_SIZE, "class %s %c%s", map->class_names[bi],
 			 test_bit(bi, new_bits) ? '+' : '-', dcp->flags);
 
-		ct = ddebug_exec_queries(query, NULL);
+		ct = ddebug_exec_queries(query, query_modname);
 		matches += ct;
 
 		v2pr_info("bit_%d: %d matches on class: %s -> 0x%lx\n", bi,
 			  ct, map->class_names[bi], *new_bits);
 	}
+	if (*new_bits != *old_bits)
+		v2pr_info("applied bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits,
+			  *old_bits, query_modname ?: "'*'");
+
 	return matches;
 }
 
@@ -684,7 +691,7 @@ static int param_set_dyndbg_classnames(const char *instr, const struct kernel_pa
 				continue;
 			}
 			curr_bits ^= BIT(cls_id);
-			totct += ddebug_apply_class_bitmap(dcp, &curr_bits, dcp->bits);
+			totct += ddebug_apply_class_bitmap(dcp, &curr_bits, dcp->bits, NULL);
 			*dcp->bits = curr_bits;
 			v2pr_info("%s: changed bit %d:%s\n", KP_NAME(kp), cls_id,
 				  map->class_names[cls_id]);
@@ -694,7 +701,7 @@ static int param_set_dyndbg_classnames(const char *instr, const struct kernel_pa
 			old_bits = CLASSMAP_BITMASK(*dcp->lvl);
 			curr_bits = CLASSMAP_BITMASK(cls_id + (wanted ? 1 : 0 ));
 
-			totct += ddebug_apply_class_bitmap(dcp, &curr_bits, &old_bits);
+			totct += ddebug_apply_class_bitmap(dcp, &curr_bits, &old_bits, NULL);
 			*dcp->lvl = (cls_id + (wanted ? 1 : 0));
 			v2pr_info("%s: changed bit-%d: \"%s\" %lx->%lx\n", KP_NAME(kp), cls_id,
 				  map->class_names[cls_id], old_bits, curr_bits);
@@ -708,18 +715,9 @@ static int param_set_dyndbg_classnames(const char *instr, const struct kernel_pa
 	return 0;
 }
 
-/**
- * param_set_dyndbg_classes - class FOO >control
- * @instr: string echo>d to sysfs, input depends on map_type
- * @kp:    kp->arg has state: bits/lvl, map, map_type
- *
- * Enable/disable prdbgs by their class, as given in the arguments to
- * DECLARE_DYNDBG_CLASSMAP.  For LEVEL map-types, enforce relative
- * levels by bitpos.
- *
- * Returns: 0 or <0 if error.
- */
-int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
+static int param_set_dyndbg_module_classes(const char *instr,
+					   const struct kernel_param *kp,
+					   const char *mod_name)
 {
 	const struct ddebug_class_param *dcp = kp->arg;
 	const struct ddebug_class_map *map = dcp->map;
@@ -756,8 +754,8 @@ int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
 				KP_NAME(kp), inrep, CLASSMAP_BITMASK(map->length));
 			inrep &= CLASSMAP_BITMASK(map->length);
 		}
-		v2pr_info("bits:%lx > %s\n", inrep, KP_NAME(kp));
-		totct += ddebug_apply_class_bitmap(dcp, &inrep, dcp->bits);
+		v2pr_info("bits:0x%lx > %s.%s\n", inrep, mod_name ?: "*", KP_NAME(kp));
+		totct += ddebug_apply_class_bitmap(dcp, &inrep, dcp->bits, mod_name);
 		*dcp->bits = inrep;
 		break;
 	case DD_CLASS_TYPE_LEVEL_NUM:
@@ -770,7 +768,7 @@ int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
 		old_bits = CLASSMAP_BITMASK(*dcp->lvl);
 		new_bits = CLASSMAP_BITMASK(inrep);
 		v2pr_info("lvl:%ld bits:0x%lx > %s\n", inrep, new_bits, KP_NAME(kp));
-		totct += ddebug_apply_class_bitmap(dcp, &new_bits, &old_bits);
+		totct += ddebug_apply_class_bitmap(dcp, &new_bits, &old_bits, mod_name);
 		*dcp->lvl = inrep;
 		break;
 	default:
@@ -779,16 +777,33 @@ int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
 	vpr_info("%s: total matches: %d\n", KP_NAME(kp), totct);
 	return 0;
 }
+
+/**
+ * param_set_dyndbg_classes - classmap kparam setter
+ * @instr: string echo>d to sysfs, input depends on map_type
+ * @kp:    kp->arg has state: bits/lvl, map, map_type
+ *
+ * enable/disable all class'd pr_debugs in the classmap. For LEVEL
+ * map-types, enforce * relative levels by bitpos.
+ *
+ * Returns: 0 or <0 if error.
+ */
+int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
+{
+	return param_set_dyndbg_module_classes(instr, kp, NULL);
+}
 EXPORT_SYMBOL(param_set_dyndbg_classes);
 
 /**
- * param_get_dyndbg_classes - classes reader
+ * param_get_dyndbg_classes - classmap kparam getter
  * @buffer: string description of controlled bits -> classes
  * @kp:     kp->arg has state: bits, map
  *
- * Reads last written state, underlying prdbg state may have been
- * altered by direct >control.  Displays 0x for DISJOINT, 0-N for
- * LEVEL Returns: #chars written or <0 on error
+ * Reads last written state, underlying pr_debug states may have been
+ * altered by direct >control.  Displays 0x for DISJOINT classmap
+ * types, 0-N for LEVEL types.
+ *
+ * Returns: ct of chars written or <0 on error
  */
 int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
 {

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 14/92] dyndbg: reduce verbose/debug clutter
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

currently, for verbose=3, these are logged (blank lines for clarity):

 dyndbg: query 0: "class DRM_UT_CORE +p" mod:*
 dyndbg: split into words: "class" "DRM_UT_CORE" "+p"

 dyndbg: op='+'
 dyndbg: flags=0x1
 dyndbg: *flagsp=0x1 *maskp=0xffffffff

 dyndbg: parsed: func="" file="" module="" format="" lineno=0-0 class=...
 dyndbg: no matches for query
 dyndbg: no-match: func="" file="" module="" format="" lineno=0-0 class=...
 dyndbg: processed 1 queries, with 0 matches, 0 errs

That is excessive, so this patch:
 - shrinks 3 lines of 2nd stanza to single line
 - drops 1st 2 lines of 3rd stanza
   3rd line is like 1st, with result, not procedure.
   2nd line is just status, retold in 4th, with more info.

New output:

 dyndbg: query 0: "class DRM_UT_CORE +p" mod:*
 dyndbg: split into words: "class" "DRM_UT_CORE" "+p"
 dyndbg: op='+' flags=0x1 *flagsp=0x1 *maskp=0xffffffff
 dyndbg: no-match: func="" file="" module="" format="" lineno=0-0 class=...
 dyndbg: processed 1 queries, with 0 matches, 0 errs

Also reduce verbose=3 messages in ddebug_add_module

When modprobing a module, dyndbg currently logs/says "add-module", and
then "skipping" if the module has no prdbgs.  Instead just check 1st
and return quietly.

no functional change

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/dynamic_debug.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 9575b92a8deb..3ae9ecabdad1 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -276,9 +276,6 @@ static int ddebug_change(const struct ddebug_query *query,
 	}
 	mutex_unlock(&ddebug_lock);
 
-	if (!nfound && verbose)
-		pr_info("no matches for query\n");
-
 	return nfound;
 }
 
@@ -511,7 +508,6 @@ static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
 		pr_err("bad flag-op %c, at start of %s\n", *str, str);
 		return -EINVAL;
 	}
-	v3pr_info("op='%c'\n", op);
 
 	for (; *str ; ++str) {
 		for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
@@ -525,7 +521,6 @@ static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
 			return -EINVAL;
 		}
 	}
-	v3pr_info("flags=0x%x\n", modifiers->flags);
 
 	/* calculate final flags, mask based upon op */
 	switch (op) {
@@ -541,7 +536,7 @@ static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
 		modifiers->flags = 0;
 		break;
 	}
-	v3pr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);
+	v3pr_info("op='%c' flags=0x%x maskp=0x%x\n", op, modifiers->flags, modifiers->mask);
 
 	return 0;
 }
@@ -551,7 +546,7 @@ static int ddebug_exec_query(char *query_string, const char *modname)
 	struct flag_settings modifiers = {};
 	struct ddebug_query query = {};
 #define MAXWORDS 9
-	int nwords, nfound;
+	int nwords;
 	char *words[MAXWORDS];
 
 	nwords = ddebug_tokenize(query_string, words, MAXWORDS);
@@ -569,10 +564,7 @@ static int ddebug_exec_query(char *query_string, const char *modname)
 		return -EINVAL;
 	}
 	/* actually go and implement the change */
-	nfound = ddebug_change(&query, &modifiers);
-	vpr_info_dq(&query, nfound ? "applied" : "no-match");
-
-	return nfound;
+	return ddebug_change(&query, &modifiers);
 }
 
 /* handle multiple queries in query string, continue on error, return
@@ -1246,11 +1238,10 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
 {
 	struct ddebug_table *dt;
 
-	v3pr_info("add-module: %s.%d sites\n", modname, di->num_descs);
-	if (!di->num_descs) {
-		v3pr_info(" skip %s\n", modname);
+	if (!di->num_descs)
 		return 0;
-	}
+
+	v3pr_info("add-module: %s %d sites\n", modname, di->num_descs);
 
 	dt = kzalloc_obj(*dt);
 	if (dt == NULL) {

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 13/92] dyndbg: tweak pr_fmt to avoid expansion conflicts
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

Disambiguate pr_fmt(fmt) arg, by changing it to _FMT_, to avoid naming
confusion with many later macros also using that argname.

no functional change

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/dynamic_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index ffa1cf7c2c72..9575b92a8deb 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -11,7 +11,7 @@
  * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
  */
 
-#define pr_fmt(fmt) "dyndbg: " fmt
+#define pr_fmt(_FMT_) "dyndbg: " _FMT_
 
 #include <linux/kernel.h>
 #include <linux/module.h>

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 12/92] dyndbg: drop NUM_TYPE_ARRAY
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

ARRAY_SIZE works here, since array decl is complete.

no functional change

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/linux/dynamic_debug.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 441305277914..92627a03b4d1 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -132,11 +132,9 @@ struct ddebug_class_param {
 		.mod_name = KBUILD_MODNAME,				\
 		.base = _base,						\
 		.map_type = _maptype,					\
-		.length = NUM_TYPE_ARGS(char*, __VA_ARGS__),		\
+		.length = ARRAY_SIZE(_var##_classnames),		\
 		.class_names = _var##_classnames,			\
 	}
-#define NUM_TYPE_ARGS(eltype, ...)				\
-	(sizeof((eltype[]) {__VA_ARGS__}) / sizeof(eltype))
 
 extern __printf(2, 3)
 void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 11/92] dyndbg: make ddebug_class_param union members same size
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

struct ddebug_class_param keeps a ref to the state-storage of the
param; make both class-types use the same unsigned long storage type.

ISTM this is simpler and safer; it avoids an irrelevant difference,
and if 2 users somehow get class-type mixed up (or refer to the wrong
union member), at least they will both see the same value.

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/linux/dynamic_debug.h | 2 +-
 lib/dynamic_debug.c           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index a10adac8e8f0..441305277914 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -104,7 +104,7 @@ struct _ddebug_info {
 struct ddebug_class_param {
 	union {
 		unsigned long *bits;
-		unsigned int *lvl;
+		unsigned long *lvl;
 	};
 	char flags[8];
 	const struct ddebug_class_map *map;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index a9caf84ddb22..ffa1cf7c2c72 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -811,7 +811,7 @@ int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
 
 	case DD_CLASS_TYPE_LEVEL_NAMES:
 	case DD_CLASS_TYPE_LEVEL_NUM:
-		return scnprintf(buffer, PAGE_SIZE, "%d\n", *dcp->lvl);
+		return scnprintf(buffer, PAGE_SIZE, "%ld\n", *dcp->lvl);
 	default:
 		return -1;
 	}

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 10/92] dyndbg: reword "class unknown," to "class:_UNKNOWN_"
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

When a dyndbg classname is unknown to a kernel module (as before
previous patch), the callsite is un-addressable via >control queries.

The control-file displays this condition as "class unknown,"
currently.  That spelling is sub-optimal/too-generic, so change it to
"class:_UNKNOWN_" to loudly announce the erroneous situation, and to
make it uniquely greppable.

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/dynamic_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 6b1e983cfedc..a9caf84ddb22 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1166,7 +1166,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
 		if (class)
 			seq_printf(m, " class:%s", class);
 		else
-			seq_printf(m, " class unknown, _id:%d", dp->class_id);
+			seq_printf(m, " class:_UNKNOWN_ _id:%d", dp->class_id);
 	}
 	seq_putc(m, '\n');
 

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 09/92] test-dyndbg: fixup CLASSMAP usage error
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

commit 6ea3bf466ac6 ("dyndbg: test DECLARE_DYNDBG_CLASSMAP, sysfs nodes")

A closer look at test_dynamic_debug.ko logging output reveals a macro
usage error:

lib/test_dynamic_debug.c:105 [test_dynamic_debug]do_cats =p "LOW msg\n" class:MID
lib/test_dynamic_debug.c:106 [test_dynamic_debug]do_cats =p "MID msg\n" class:HI
lib/test_dynamic_debug.c:107 [test_dynamic_debug]do_cats =_ "HI msg\n" class unknown, _id:13

107 says: HI is unknown, and 105,106 have a LOW/MID and MID/HI skew.

DECLARE_DYNDBG_CLASSMAP() _base arg must equal the enum's 1st value,
in this case it was _base + 1.  This leaves HI class un-selectable.

NB: the macro could better validate its arguments.

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Tested-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/test_dynamic_debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 77c2a669b6af..396144cf351b 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -75,7 +75,7 @@ DD_SYS_WRAP(disjoint_bits, p);
 DD_SYS_WRAP(disjoint_bits, T);
 
 /* symbolic input, independent bits */
-enum cat_disjoint_names { LOW = 11, MID, HI };
+enum cat_disjoint_names { LOW = 10, MID, HI };
 DECLARE_DYNDBG_CLASSMAP(map_disjoint_names, DD_CLASS_TYPE_DISJOINT_NAMES, 10,
 			"LOW", "MID", "HI");
 DD_SYS_WRAP(disjoint_names, p);

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 08/92] docs/dyndbg: explain flags parse 1st
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

When writing queries to >control, flags are parsed 1st, since they are
the only required field, and they require specific compositions.  So
if the flags draw an error (on those specifics), then keyword errors
aren't reported.  This can be mildly confusing/annoying, so explain it
instead.

cc: linux-doc@vger.kernel.org
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 Documentation/admin-guide/dynamic-debug-howto.rst | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index 4b14d9fd0300..9c2f096ed1d8 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -109,10 +109,19 @@ The match-spec's select *prdbgs* from the catalog, upon which to apply
 the flags-spec, all constraints are ANDed together.  An absent keyword
 is the same as keyword "*".
 
-
-A match specification is a keyword, which selects the attribute of
-the callsite to be compared, and a value to compare against.  Possible
-keywords are:::
+Note that since the match-spec can be empty, the flags are checked 1st,
+then the pairs of keyword and value.  Flag errs will hide keyword errs::
+
+  bash-5.2# ddcmd mod bar +foo
+  dyndbg: read 13 bytes from userspace
+  dyndbg: query 0: "mod bar +foo" mod:*
+  dyndbg: unknown flag 'o'
+  dyndbg: flags parse failed
+  dyndbg: processed 1 queries, with 0 matches, 1 errs
+
+So a match-spec is a keyword, which selects the attribute of the
+callsite to be compared, and a value to compare against.  Possible
+keywords are::
 
   match-spec ::= 'func' string |
 		 'file' string |

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 07/92] docs/dyndbg: update examples \012 to \n
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

commit 47ea6f99d06e ("dyndbg: use ESCAPE_SPACE for cat control")
changed the control-file to display format strings with "\n" rather
than "\012".  Update the docs to match the new reality.

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Tested-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 Documentation/admin-guide/dynamic-debug-howto.rst | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index 095a63892257..4b14d9fd0300 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -38,12 +38,12 @@ You can view the currently configured behaviour in the *prdbg* catalog::
 
   :#> head -n7 /proc/dynamic_debug/control
   # filename:lineno [module]function flags format
-  init/main.c:1179 [main]initcall_blacklist =_ "blacklisting initcall %s\012
-  init/main.c:1218 [main]initcall_blacklisted =_ "initcall %s blacklisted\012"
-  init/main.c:1424 [main]run_init_process =_ "  with arguments:\012"
-  init/main.c:1426 [main]run_init_process =_ "    %s\012"
-  init/main.c:1427 [main]run_init_process =_ "  with environment:\012"
-  init/main.c:1429 [main]run_init_process =_ "    %s\012"
+  init/main.c:1179 [main]initcall_blacklist =_ "blacklisting initcall %s\n"
+  init/main.c:1218 [main]initcall_blacklisted =_ "initcall %s blacklisted\n"
+  init/main.c:1424 [main]run_init_process =_ "  with arguments:\n"
+  init/main.c:1426 [main]run_init_process =_ "    %s\n"
+  init/main.c:1427 [main]run_init_process =_ "  with environment:\n"
+  init/main.c:1429 [main]run_init_process =_ "    %s\n"
 
 The 3rd space-delimited column shows the current flags, preceded by
 a ``=`` for easy use with grep/cut. ``=p`` shows enabled callsites.
@@ -59,10 +59,10 @@ query/commands to the control file.  Example::
 
   :#> ddcmd '-p; module main func run* +p'
   :#> grep =p /proc/dynamic_debug/control
-  init/main.c:1424 [main]run_init_process =p "  with arguments:\012"
-  init/main.c:1426 [main]run_init_process =p "    %s\012"
-  init/main.c:1427 [main]run_init_process =p "  with environment:\012"
-  init/main.c:1429 [main]run_init_process =p "    %s\012"
+  init/main.c:1424 [main]run_init_process =p "  with arguments:\n"
+  init/main.c:1426 [main]run_init_process =p "    %s\n"
+  init/main.c:1427 [main]run_init_process =p "  with environment:\n"
+  init/main.c:1429 [main]run_init_process =p "    %s\n"
 
 Error messages go to console/syslog::
 

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 06/92] dyndbg: add stub macro for DECLARE_DYNDBG_CLASSMAP
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

Add the stub macro for !DYNAMIC_DEBUG builds, after moving the
original macro-defn down under the big ifdef.  Do it now so future
changes have a cleaner starting point.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/linux/dynamic_debug.h | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 05743900a116..a10adac8e8f0 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -93,27 +93,6 @@ struct ddebug_class_map {
 	enum class_map_type map_type;
 };
 
-/**
- * DECLARE_DYNDBG_CLASSMAP - declare classnames known by a module
- * @_var:   a struct ddebug_class_map, passed to module_param_cb
- * @_type:  enum class_map_type, chooses bits/verbose, numeric/symbolic
- * @_base:  offset of 1st class-name. splits .class_id space
- * @classes: class-names used to control class'd prdbgs
- */
-#define DECLARE_DYNDBG_CLASSMAP(_var, _maptype, _base, ...)		\
-	static const char *_var##_classnames[] = { __VA_ARGS__ };	\
-	static struct ddebug_class_map __aligned(8) __used		\
-		__section("__dyndbg_classes") _var = {			\
-		.mod = THIS_MODULE,					\
-		.mod_name = KBUILD_MODNAME,				\
-		.base = _base,						\
-		.map_type = _maptype,					\
-		.length = NUM_TYPE_ARGS(char*, __VA_ARGS__),		\
-		.class_names = _var##_classnames,			\
-	}
-#define NUM_TYPE_ARGS(eltype, ...)				\
-        (sizeof((eltype[]){__VA_ARGS__}) / sizeof(eltype))
-
 /* encapsulate linker provided built-in (or module) dyndbg data */
 struct _ddebug_info {
 	struct _ddebug *descs;
@@ -138,6 +117,27 @@ struct ddebug_class_param {
 #if defined(CONFIG_DYNAMIC_DEBUG) || \
 	(defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))
 
+/**
+ * DECLARE_DYNDBG_CLASSMAP - declare classnames known by a module
+ * @_var:   a struct ddebug_class_map, passed to module_param_cb
+ * @_type:  enum class_map_type, chooses bits/verbose, numeric/symbolic
+ * @_base:  offset of 1st class-name. splits .class_id space
+ * @classes: class-names used to control class'd prdbgs
+ */
+#define DECLARE_DYNDBG_CLASSMAP(_var, _maptype, _base, ...)		\
+	static const char *_var##_classnames[] = { __VA_ARGS__ };	\
+	static struct ddebug_class_map __aligned(8) __used		\
+		__section("__dyndbg_classes") _var = {			\
+		.mod = THIS_MODULE,					\
+		.mod_name = KBUILD_MODNAME,				\
+		.base = _base,						\
+		.map_type = _maptype,					\
+		.length = NUM_TYPE_ARGS(char*, __VA_ARGS__),		\
+		.class_names = _var##_classnames,			\
+	}
+#define NUM_TYPE_ARGS(eltype, ...)				\
+	(sizeof((eltype[]) {__VA_ARGS__}) / sizeof(eltype))
+
 extern __printf(2, 3)
 void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
 
@@ -314,6 +314,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)
 #define DYNAMIC_DEBUG_BRANCH(descriptor) false
+#define DECLARE_DYNDBG_CLASSMAP(...)
 
 #define dynamic_pr_debug(fmt, ...)					\
 	no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 05/92] dyndbg: factor ddebug_match_desc out from ddebug_change
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

ddebug_change() is a big (~100 lines) function with a nested for loop.

The outer loop walks the per-module ddebug_tables list, and does
module stuff: it filters on a query's "module FOO*" and "class BAR",
failures here skip the entire inner loop.

The inner loop (60 lines) scans a module's descriptors.  It starts
with a long block of filters on function, line, format, and the
validated "BAR" class (or the legacy/_DPRINTK_CLASS_DFLT).

These filters "continue" past pr_debugs that don't match the query
criteria, before it falls through the code below that counts matches,
then adjusts the flags and static-keys.  This is unnecessarily hard to
think about.

So move the per-descriptor filter-block into a boolean function:
ddebug_match_desc(desc), and change each "continue" to "return false".
This puts a clear interface in place, so any future changes are either
inside, outside, or across this interface.

also fix checkpatch complaints about spaces and braces.

Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 lib/dynamic_debug.c | 83 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 18a71a9108d3..6b1e983cfedc 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -172,6 +172,52 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
  * callsites, normally the same as number of changes.  If verbose,
  * logs the changes.  Takes ddebug_lock.
  */
+static bool ddebug_match_desc(const struct ddebug_query *query,
+			      struct _ddebug *dp,
+			      int valid_class)
+{
+	/* match site against query-class */
+	if (dp->class_id != valid_class)
+		return false;
+
+	/* match against the source filename */
+	if (query->filename &&
+	    !match_wildcard(query->filename, dp->filename) &&
+	    !match_wildcard(query->filename,
+			    kbasename(dp->filename)) &&
+	    !match_wildcard(query->filename,
+			    trim_prefix(dp->filename)))
+		return false;
+
+	/* match against the function */
+	if (query->function &&
+	    !match_wildcard(query->function, dp->function))
+		return false;
+
+	/* match against the format */
+	if (query->format) {
+		if (*query->format == '^') {
+			char *p;
+			/* anchored search. match must be at beginning */
+			p = strstr(dp->format, query->format + 1);
+			if (p != dp->format)
+				return false;
+		} else if (!strstr(dp->format, query->format)) {
+			return false;
+		}
+	}
+
+	/* match against the line number range */
+	if (query->first_lineno &&
+	    dp->lineno < query->first_lineno)
+		return false;
+	if (query->last_lineno &&
+	    dp->lineno > query->last_lineno)
+		return false;
+
+	return true;
+}
+
 static int ddebug_change(const struct ddebug_query *query,
 			 struct flag_settings *modifiers)
 {
@@ -204,42 +250,7 @@ static int ddebug_change(const struct ddebug_query *query,
 		for (i = 0; i < dt->num_ddebugs; i++) {
 			struct _ddebug *dp = &dt->ddebugs[i];
 
-			/* match site against query-class */
-			if (dp->class_id != valid_class)
-				continue;
-
-			/* match against the source filename */
-			if (query->filename &&
-			    !match_wildcard(query->filename, dp->filename) &&
-			    !match_wildcard(query->filename,
-					   kbasename(dp->filename)) &&
-			    !match_wildcard(query->filename,
-					   trim_prefix(dp->filename)))
-				continue;
-
-			/* match against the function */
-			if (query->function &&
-			    !match_wildcard(query->function, dp->function))
-				continue;
-
-			/* match against the format */
-			if (query->format) {
-				if (*query->format == '^') {
-					char *p;
-					/* anchored search. match must be at beginning */
-					p = strstr(dp->format, query->format+1);
-					if (p != dp->format)
-						continue;
-				} else if (!strstr(dp->format, query->format))
-					continue;
-			}
-
-			/* match against the line number range */
-			if (query->first_lineno &&
-			    dp->lineno < query->first_lineno)
-				continue;
-			if (query->last_lineno &&
-			    dp->lineno > query->last_lineno)
+			if (!ddebug_match_desc(query, dp, valid_class))
 				continue;
 
 			nfound++;

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 04/92] vmlinux.lds.h: drop unused HEADERED_SECTION* macros
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

These macros are unused, no point in carrying them any more.

NB: these macros were just moved to bounded_sections.lds.h, from
vmlinux.lds.h, which is the known entity, and therefore more
meaningful in the 1-line summary, so thats what I used as the topic.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/asm-generic/bounded_sections.lds.h | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/include/asm-generic/bounded_sections.lds.h b/include/asm-generic/bounded_sections.lds.h
index 43e79603d4af..f5876e68cbe7 100644
--- a/include/asm-generic/bounded_sections.lds.h
+++ b/include/asm-generic/bounded_sections.lds.h
@@ -20,19 +20,4 @@
 
 #define BOUNDED_SECTION(_sec)	 BOUNDED_SECTION_BY(_sec, _sec)
 
-#define HEADERED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \
-	_HDR_##_label_	= .;						\
-	KEEP(*(.gnu.linkonce.##_sec_))					\
-	BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)
-
-#define HEADERED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \
-	_label_##_HDR_ = .;						\
-	KEEP(*(.gnu.linkonce.##_sec_))					\
-	BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)
-
-#define HEADERED_SECTION_BY(_sec_, _label_)				\
-	HEADERED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop)
-
-#define HEADERED_SECTION(_sec)	 HEADERED_SECTION_BY(_sec, _sec)
-
 #endif /* _ASM_GENERIC_BOUNDED_SECTIONS_H */

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 03/92] dyndbg.lds.S: fix lost dyndbg sections in modules
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

In an (unused) experimental variation of this series, I had trouble
with __dyndbg* sections getting lost in drm drivers.  While it didn't
happen in this series, it exposed a non-obvious weakness.  So fix it,
by following the model demonstrated in codetag.lds.h.

Introduce include/asm-generic/dyndbg.lds.h, with 2 macros:

DYNDBG_SECTIONS() gets the 2 BOUNDED_SECTION_BY(__yndbg*) calls from
vmlinux.lds.h DATA_DATA, which now includes the new file and calls the
new macro.

MOD_DYNDBG_SECTIONS also has the 2 BOUNDED_SECTION_BY calls, but wraps
them with output section syntax to keep them as known and separate ELF
sections in the module.ko.

dyndbg.lds.h includes (reuses) bounded-section.lds.h

scripts/module.lds.S: now calls MOD_DYNDBG_SECTIONS right before the
CODETAG macro (consistent with their placements in vmlinux.lds.h), and
also includes dyndbg.lds.h

This isolates vmlinux.lds.h from further __dyndbg section additions.

CC: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 MAINTAINERS                       |  1 +
 include/asm-generic/dyndbg.lds.h  | 19 +++++++++++++++++++
 include/asm-generic/vmlinux.lds.h |  6 ++----
 scripts/module.lds.S              |  2 ++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5fcb7b991776..5c75109d2ee3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9069,6 +9069,7 @@ DYNAMIC DEBUG
 M:	Jason Baron <jbaron@akamai.com>
 M:	Jim Cromie <jim.cromie@gmail.com>
 S:	Maintained
+F:	include/asm-generic/dyndbg.lds.h
 F:	include/linux/dynamic_debug.h
 F:	lib/dynamic_debug.c
 F:	lib/test_dynamic_debug.c
diff --git a/include/asm-generic/dyndbg.lds.h b/include/asm-generic/dyndbg.lds.h
new file mode 100644
index 000000000000..f95683aa16b6
--- /dev/null
+++ b/include/asm-generic/dyndbg.lds.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_GENERIC_DYNDBG_LDS_H
+#define __ASM_GENERIC_DYNDBG_LDS_H
+
+#include <asm-generic/bounded_sections.lds.h>
+#define DYNDBG_SECTIONS()					\
+	. = ALIGN(8);						\
+	BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)			\
+	BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)
+
+#define MOD_DYNDBG_SECTIONS()                                           \
+	__dyndbg : {							\
+		BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)			\
+	}								\
+	__dyndbg_classes : {						\
+		BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)	\
+	}
+
+#endif /* __ASM_GENERIC_DYNDBG_LDS_H */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index acb4aadd74da..9324066aab51 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -340,6 +340,7 @@
 /*
  * .data section
  */
+#include <asm-generic/dyndbg.lds.h>
 #define DATA_DATA							\
 	*(.xiptext)							\
 	*(DATA_MAIN)							\
@@ -353,10 +354,7 @@
 	*(.data..do_once)						\
 	STRUCT_ALIGN();							\
 	*(__tracepoints)						\
-	/* implement dynamic printk debug */				\
-	. = ALIGN(8);							\
-	BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)		\
-	BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)				\
+	DYNDBG_SECTIONS()						\
 	CODETAG_SECTIONS()						\
 	LIKELY_PROFILE()		       				\
 	BRANCH_PROFILE()						\
diff --git a/scripts/module.lds.S b/scripts/module.lds.S
index 2dc4c8c3e667..027c5c286ea0 100644
--- a/scripts/module.lds.S
+++ b/scripts/module.lds.S
@@ -10,6 +10,7 @@
 #endif
 
 #include <asm-generic/codetag.lds.h>
+#include <asm-generic/dyndbg.lds.h>
 
 SECTIONS {
 	/DISCARD/ : {
@@ -59,6 +60,7 @@ SECTIONS {
 		*(.rodata..L*)
 	}
 
+	MOD_DYNDBG_SECTIONS()
 	MOD_SEPARATE_CODETAG_SECTIONS()
 }
 

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 02/92] vmlinux.lds.h: move BOUNDED_SECTION_* macros to reuse later
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

Move BOUNDED_SECTION_* macros to a new helper file:
include/asm-generic/bounded_sections.lds.h
and include it back into vmlinux.lds.h

This allows its reuse later to fix a future problem with modules
failing to keep dyndbg sections in some circumstances.

NB: this ignores a checkpatch warning, because new file is covered by
GENERIC INCLUDE/ASM HEADER FILES

CC: Arnd Bergmann <arnd@arndb.de>
CC: linux-arch@vger.kernel.org
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/asm-generic/bounded_sections.lds.h | 38 ++++++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h          | 32 +------------------------
 2 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/include/asm-generic/bounded_sections.lds.h b/include/asm-generic/bounded_sections.lds.h
new file mode 100644
index 000000000000..43e79603d4af
--- /dev/null
+++ b/include/asm-generic/bounded_sections.lds.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef _ASM_GENERIC_BOUNDED_SECTIONS_H
+#define _ASM_GENERIC_BOUNDED_SECTIONS_H
+
+#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)	\
+	. = ALIGN(8);							\
+	_BEGIN_##_label_ = .;						\
+	KEEP(*(_sec_))							\
+	_END_##_label_ = .;
+
+#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)	\
+	. = ALIGN(8);							\
+	_label_##_BEGIN_ = .;						\
+	KEEP(*(_sec_))							\
+	_label_##_END_ = .;
+
+#define BOUNDED_SECTION_BY(_sec_, _label_)				\
+	BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop)
+
+#define BOUNDED_SECTION(_sec)	 BOUNDED_SECTION_BY(_sec, _sec)
+
+#define HEADERED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \
+	_HDR_##_label_	= .;						\
+	KEEP(*(.gnu.linkonce.##_sec_))					\
+	BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)
+
+#define HEADERED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \
+	_label_##_HDR_ = .;						\
+	KEEP(*(.gnu.linkonce.##_sec_))					\
+	BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)
+
+#define HEADERED_SECTION_BY(_sec_, _label_)				\
+	HEADERED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop)
+
+#define HEADERED_SECTION(_sec)	 HEADERED_SECTION_BY(_sec, _sec)
+
+#endif /* _ASM_GENERIC_BOUNDED_SECTIONS_H */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index db38f52035f3..acb4aadd74da 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -211,37 +211,7 @@
 # endif
 #endif
 
-#define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)	\
-	. = ALIGN(8);							\
-	_BEGIN_##_label_ = .;						\
-	KEEP(*(_sec_))							\
-	_END_##_label_ = .;
-
-#define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)	\
-	. = ALIGN(8);							\
-	_label_##_BEGIN_ = .;						\
-	KEEP(*(_sec_))							\
-	_label_##_END_ = .;
-
-#define BOUNDED_SECTION_BY(_sec_, _label_)				\
-	BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop)
-
-#define BOUNDED_SECTION(_sec)	 BOUNDED_SECTION_BY(_sec, _sec)
-
-#define HEADERED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \
-	_HDR_##_label_	= .;						\
-	KEEP(*(.gnu.linkonce.##_sec_))					\
-	BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)
-
-#define HEADERED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_, _HDR_) \
-	_label_##_HDR_ = .;						\
-	KEEP(*(.gnu.linkonce.##_sec_))					\
-	BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)
-
-#define HEADERED_SECTION_BY(_sec_, _label_)				\
-	HEADERED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop)
-
-#define HEADERED_SECTION(_sec)	 HEADERED_SECTION_BY(_sec, _sec)
+#include <asm-generic/bounded_sections.lds.h>
 
 #ifdef CONFIG_TRACE_BRANCH_PROFILING
 #define LIKELY_PROFILE()						\

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 01/92] dyndbg: fix NULL ptr on i386 due to section mis-alignment
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie, kernel test robot
In-Reply-To: <20260423-submit-dyndbg-classmap-foundation-v14-0-2b809a8019d0@gmail.com>

When dyndbg classmaps get used (later in this series), the
__dyndbg_classes section (which has 28 byte structs on i386), causes
mis-alignment of the following __dyndbg section, resulting in a NULL
pointer deref in dynamic_debug_init().

Fix this by:

Adding ALIGN(8) to the BOUNDED_SECTION* macros.  This aligns all
sections using those macros, including the problem section above.
Almost all the other macro uses are already ALIGN(8), either
directly or by being below one.

Removing BOUNDED_SECTION* uses in ORC_UNWINDER sections.  These
explicitly have smaller alignments, and using the modified macros here
would override that alignment, which scripts/sorttable.c does not
tolerate.

Move __dyndbg section back above __dyndbg_classes, restoring its
original position.  This is cosmetic, given the alignment added to the
macros.

Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202601211325.7e1f336-lkp@intel.com
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/asm-generic/vmlinux.lds.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 60c8c22fd3e4..db38f52035f3 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -212,11 +212,13 @@
 #endif
 
 #define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)	\
+	. = ALIGN(8);							\
 	_BEGIN_##_label_ = .;						\
 	KEEP(*(_sec_))							\
 	_END_##_label_ = .;
 
 #define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)	\
+	. = ALIGN(8);							\
 	_label_##_BEGIN_ = .;						\
 	KEEP(*(_sec_))							\
 	_label_##_END_ = .;
@@ -862,15 +864,21 @@
 #ifdef CONFIG_UNWINDER_ORC
 #define ORC_UNWIND_TABLE						\
 	.orc_header : AT(ADDR(.orc_header) - LOAD_OFFSET) {		\
-		BOUNDED_SECTION_BY(.orc_header, _orc_header)		\
+		__start_orc_header = .;					\
+		KEEP(*(.orc_header))					\
+		__stop_orc_header = .;					\
 	}								\
 	. = ALIGN(4);							\
 	.orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) {	\
-		BOUNDED_SECTION_BY(.orc_unwind_ip, _orc_unwind_ip)	\
+		__start_orc_unwind_ip = .;				\
+		KEEP(*(.orc_unwind_ip))					\
+		__stop_orc_unwind_ip = .;				\
 	}								\
 	. = ALIGN(2);							\
 	.orc_unwind : AT(ADDR(.orc_unwind) - LOAD_OFFSET) {		\
-		BOUNDED_SECTION_BY(.orc_unwind, _orc_unwind)		\
+		__start_orc_unwind = .;					\
+		KEEP(*(.orc_unwind))					\
+		__stop_orc_unwind = .;					\
 	}								\
 	text_size = _etext - _stext;					\
 	. = ALIGN(4);							\

-- 
2.53.0


^ permalink raw reply related

* [PATCH v14 00/92] dyndbg: enable 0-off-cost for all of __drm_debug
From: Jim Cromie @ 2026-04-23 20:53 UTC (permalink / raw)
  To: Arnd Bergmann, Jason Baron, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Andrew Morton,
	Jonathan Corbet, Shuah Khan, Shuah Khan, Greg Kroah-Hartman,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, David Airlie,
	Gerd Hoffmann, Dmitry Osipenko, Gurchetan Singh, Chia-I Wu,
	Matthew Brost, Thomas Hellström, Lyude Paul,
	Danilo Krummrich, Patrik Jakobsson, Zack Rusin,
	Broadcom internal kernel review list, Louis Chauvet,
	Haneen Mohammed, Melissa Wen, Sean Paul, Jocelyn Falempe,
	Ruben Wauters, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance, Rob Clark, Dmitry Baryshkov,
	Abhinav Kumar, Jessica Zhang, Marijn Suijten, Xinliang Liu,
	Tian Tao, Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
	Philipp Zabel, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Chun-Kuang Hu, Matthias Brugger,
	AngeloGioacchino Del Regno, Sandy Huang, Heiko Stübner,
	Andy Yan, Alain Volmat, Raphael Gallais-Pou, Yannick Fertre,
	Raphael Gallais-Pou, Philippe Cornu, Maxime Coquelin,
	Alexandre Torgue, Oded Gabbay, Maciej Falkowski, Karol Wachowski,
	Rob Herring (Arm), Tomeu Vizoso, Liviu Dudau, Andrzej Hajda,
	Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
	Jernej Skrabec, Liu Ying, Laurentiu Palcu, Lucas Stach,
	Paul Kocialkowski, Jianmin Lv, Qianhai Wu, Huacai Chen,
	Mingcong Bai, Xi Ruoyao, Icenowy Zheng, Laurent Pinchart,
	Tomi Valkeinen, Kieran Bingham, Geert Uytterhoeven, Magnus Damm,
	Javier Martinez Canillas, Huang Rui, Matthew Auld, Jani Nikula,
	Luca Coelho, Russell King, Christian Gmeiner
  Cc: linux-arch, linux-kernel, linux-modules, linux-doc,
	linux-kselftest, dri-devel, intel-gfx, amd-gfx, virtualization,
	intel-xe, nouveau, spice-devel, linux-arm-msm, freedreno, imx,
	linux-arm-kernel, linux-mediatek, linux-rockchip, linux-stm32,
	linux-renesas-soc, etnaviv, Jim Cromie, kernel test robot,
	Łukasz Bartosik, Philipp Hahn

Since Feb 2023, DRM_USE_DYNAMIC_DEBUG has been marked BROKEN [1].
Although classmaps worked in normal operation (via sysfs), the "v1"
POC implementation failed to propagate drm.debug boot-args to built-in
drivers and helpers.

The API Fix:

The root cause was a "Define vs Refer" design error. By using
DECLARE_DYNDBG_CLASSMAP in both core and drivers, the implementation
lacked the formal linkage required for dyndbg to associate driver
callsites with the core's controlling parameter during early boot
init.

This series introduces a proper module-scoped API:
- DYNDBG_CLASSMAP_DEFINE: Invoked once in drm_print.c (exported by drm.ko).
- DYNDBG_CLASSMAP_USE: Invoked by 20+ DRM/Accel modules to reference the core.

This linkage allows dyndbg to trace a driver's USE back to the core's
DEFINE. At boot-time, dyndbg can now correctly apply drm.debug
settings to all referencing modules as they are initialized, restoring
full functionality for built-in drivers.

The Benefit and Evidence (+c flag):

While the instructions saved by replacing bit-tests with NOOPs are
individually small, the scale of DRM's debug activity makes the
aggregate impact substantial.  In particular, dyndbg elides the fetch
of __drm_debug for every drm_debug_enabled() bit test, eliminating the
fetch from main memory and cache-line thrashing.

To measure the call-counts, the final patch in this series adds +c
flag to dyndbg, whereby enabled pr_debug* callsites increment a
per-cpu counter.

The benchmark (in last patch) sets +c flag on all drm_dbg_*s,
and runs 12 vkcubes for 30 sec:

  root@frodo:/home/jimc/projects/lx# count_hits 30 hammer_vk --
  Banging on: hammer_vk (&)
  [1] 100847
  [1]+  Done                       hammer_vk
  #: total hits: 2295401

This ran 1 vkcube for 10sec each, counting 1 DRM_UT_* class at a time:

root@frodo:/home/jimc/projects/lx# isolate_drm_hits 2> /dev/null
Starting isolation study: 10s per class using vkcube
----------------------------------------------------------
DRM CLASS            | TOTAL HITS
----------------------------------------------------------
DRM_UT_CORE          | 85305
DRM_UT_DRIVER        | 0
DRM_UT_KMS           | 1435
DRM_UT_PRIME         | 0
DRM_UT_ATOMIC        | 13645
DRM_UT_VBL           | 4071
DRM_UT_STATE         | 1780
DRM_UT_LEASE         | 0
DRM_UT_DP            | 0
DRM_UT_DRMRES        | 0
FOO                  | 0

Replacing this frequent memory fetch & bit-test with static-key NOOPs
could save approximately 200 peta-instructions per year across the
Steam Deck install base alone.

Series Organization:

1. vmlinux.lds.h fix and cleanup (patches 1-4)
   fix section alignment of 32 bit arches

2. dyndbg internal refactorings (5-24)
   internal callchaing grooming,
   struct refactoring, __section renames
   drop linked-list, use existing vector/array

3. core API fix (25-30)
   replace flawed DECLARE_DYNDBG_CLASSMAP with the DEFINE/USE model.
   fix boot-time propagation of drm.debug to built-in drivers/helpers.
   add compile-time validation of classmaps

4. interface improvements, documentation (31-38)
   query improvments: commas as token separators, % as query separators
   control-file epilogue

5. apply API to DRM
   call DYNAMIC_DEBUG_CLASSMAP_DEFINE(drm_debug_classes ...) in drm_drv.c
   call DYNAMIC_DEBUG_CLASSMAP_USE(drm_debug_classes) in drivers, helpers

6. New additions in v14
   add +c flag for benchmarking
   add DYNAMIC_DEBUG_CLASSMAP_USEs to more drivers, helpers
   drm/nouveau: Fix NULL pointer dereferences in GETPARAM ioctl (RFC)

In v13, to focus the review, I sent only the dyndbg core, and skipped
the DRM uses.  But the value of the optimization is best seen in
context; it presented GregKH a "maze with no cheese".

For v14, I've recombined them to show the full scale of the benefit.
While the performance gains accrue to DRM, the infrastructure resides
in dyndbg.

So Id like to add some "cheese" (later); ie patchsets to:

1. reduce __dyndbg_* .data by 40%.

This uses 3 maple trees to store module, filename, function, which
collapses 1st 2 columns by 90%.  Looped `cat control` tests indicate
a minor cost increase.

2. cache dynamic-prefixes, to avoid repeated work.

This assembles the prefix from maple trees, and stores the prefix into
another maple tree.  The cache is minimal; for +m callsites, it keeps
just 1 prefix per enabled module, for +mf prefixes just 1 per function.

Preliminary benchmarking suggests positive ROI on these.

Fixes: bb2ff6c27bc9 ("drm: Disable dynamic debug as broken")

Assisted-by: google gemini
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
Jim Cromie (91):
      dyndbg: fix NULL ptr on i386 due to section mis-alignment
      vmlinux.lds.h: move BOUNDED_SECTION_* macros to reuse later
      dyndbg.lds.S: fix lost dyndbg sections in modules
      vmlinux.lds.h: drop unused HEADERED_SECTION* macros
      dyndbg: factor ddebug_match_desc out from ddebug_change
      dyndbg: add stub macro for DECLARE_DYNDBG_CLASSMAP
      docs/dyndbg: update examples \012 to \n
      docs/dyndbg: explain flags parse 1st
      test-dyndbg: fixup CLASSMAP usage error
      dyndbg: reword "class unknown," to "class:_UNKNOWN_"
      dyndbg: make ddebug_class_param union members same size
      dyndbg: drop NUM_TYPE_ARRAY
      dyndbg: tweak pr_fmt to avoid expansion conflicts
      dyndbg: reduce verbose/debug clutter
      dyndbg: refactor param_set_dyndbg_classes and below
      dyndbg: tighten fn-sig of ddebug_apply_class_bitmap
      dyndbg: replace classmap list with a vector
      dyndbg: macrofy a 2-index for-loop pattern
      dyndbg,module: make proper substructs in _ddebug_info
      dyndbg: move mod_name down from struct ddebug_table to _ddebug_info
      dyndbg: hoist classmap-filter-by-modname up to ddebug_add_module
      dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code
      selftests-dyndbg: add a dynamic_debug run_tests target
      dyndbg: change __dynamic_func_call_cls* macros into expressions
      dyndbg-API: replace DECLARE_DYNDBG_CLASSMAP
      dyndbg: detect class_id reservation conflicts
      dyndbg: check DYNAMIC_DEBUG_CLASSMAP_{DEFINE,USE_} args at compile-time
      dyndbg-test: change do_prints testpoint to accept a loopct
      dyndbg-API: promote DYNAMIC_DEBUG_CLASSMAP_PARAM to API
      dyndbg: treat comma as a token separator
      dyndbg: split multi-query strings with %
      selftests-dyndbg: add test_mod_submod
      dyndbg: resolve "protection" of class'd pr_debug
      dyndbg: harden classmap and descriptor validation
      docs/dyndbg: add classmap info to howto
      dyndbg: add epilogue to dynamic_debug/control file
      drm: use correct ccflags-y spelling
      drm-dyndbg: adapt drm core to use dyndbg classmaps-v2
      drm-dyndbg: adapt DRM to invoke DYNAMIC_DEBUG_CLASSMAP_PARAM
      drm/i915: Register DRM_CLASSMAP_USE(drm_debug_classes)
      drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver
      drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu
      drm-dyndbg: add DRM_CLASSMAP_USE to Xe
      drm/drm_crtc_helper: Register DRM_CLASSMAP_USE(drm_debug_classes)
      drm/drm_dp_helper: Register DRM_CLASSMAP_USE(drm_debug_classes)
      drm/nouveau: Register DRM_CLASSMAP_USE(drm_debug_classes)
      drm/gma500: Register DRM classmap
      drm/radeon: Register DRM classmap
      drm/vmwgfx: Register DRM classmap
      drm/vkms: Register DRM classmap
      drm/udl: Register DRM classmap
      drm/mgag200: Register DRM classmap
      drm/gud: Register DRM classmap
      drm/qxl: Register DRM classmap
      drm/shmem-helper: Register DRM classmap
      drm/ttm-helper: DRM_CLASSMAP_USE(drm_debug_classes);
      drm/nouveau: Fix NULL pointer dereferences in GETPARAM ioctl
      drm/vc4: Register DRM classmap
      drm/msm: Register DRM classmap
      drm/hibmc: Register DRM classmap
      drm/imx: Register DRM classmap
      drm/mediatek: Register DRM classmap
      drm/rockchip: Register DRM classmap
      drm/sti: Register DRM classmap
      drm/stm: Register DRM classmap
      accel: add -DDYNAMIC_DEBUG_MODULE to subdir-ccflags
      accel/ivpu: implement IVPU_DBG_* as a dyndbg classmap
      accel/ethosu: enable drm.debug control
      accel/rocket: enable drm.debug control
      drm/komeda: Register DRM classmap
      drm/bridge/analogix: Register DRM classmap
      drm/bridge/dw-hdmi: Register DRM classmap
      drm/hisilicon/kirin: Register DRM classmap
      drm/imx/dc: Register DRM classmap
      drm/imx/dcss: Register DRM classmap
      drm/logicvc: Register DRM classmap
      drm/loongson: Register DRM classmap
      drm/renesas/rcar-du: Register DRM classmap
      drm/sysfb/simpledrm: Register DRM classmap
      drm/tests: Register DRM classmap in drm_mm_test
      drm/ttm: Register DRM classmap
      drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN
      drm-print: fix config-dependent unused variable
      drm_print: fix drm_printer dynamic debug bypass
      drm: enable DRM_USE_DYNAMIC_DEBUG by default (for testing)
      drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv
      drm/tiny: panel-mipi-dbi: Add DRM_CLASSMAP_USE
      drm/bridge: ite-it6505: Add DRM_CLASSMAP_USE
      drm/mipi-dbi: Add DRM_CLASSMAP_USE
      drm/clients: Add DRM_CLASSMAP_USE to drm_client_setup
      dyndbg: add +c flag to demonstrate advantage of classmaps for DRM

Philipp Hahn (1):
      dyndbg: Ignore additional arguments from pr_fmt

 Documentation/admin-guide/dynamic-debug-howto.rst  | 184 ++++-
 MAINTAINERS                                        |   4 +-
 drivers/accel/Makefile                             |   7 +-
 drivers/accel/ethosu/ethosu_drv.c                  |   3 +
 drivers/accel/ivpu/ivpu_drv.c                      |  27 +-
 drivers/accel/ivpu/ivpu_drv.h                      |  45 +-
 drivers/accel/rocket/rocket_gem.c                  |   2 +
 drivers/gpu/drm/Kconfig.debug                      |   3 +-
 drivers/gpu/drm/Makefile                           |   3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c            |  12 +-
 drivers/gpu/drm/arm/display/komeda/komeda_drv.c    |   4 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |   2 +
 drivers/gpu/drm/bridge/ite-it6505.c                |   2 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c          |   2 +
 drivers/gpu/drm/clients/drm_client_setup.c         |   2 +
 drivers/gpu/drm/display/drm_dp_helper.c            |  12 +-
 drivers/gpu/drm/drm_crtc_helper.c                  |  12 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c             |   1 +
 drivers/gpu/drm/drm_gem_ttm_helper.c               |   2 +
 drivers/gpu/drm/drm_mipi_dbi.c                     |   2 +
 drivers/gpu/drm/drm_print.c                        |  40 +-
 drivers/gpu/drm/etnaviv/etnaviv_drv.c              |   2 +
 drivers/gpu/drm/gma500/psb_drv.c                   |   2 +
 drivers/gpu/drm/gud/gud_drv.c                      |   2 +
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c    |   2 +
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c    |   2 +
 drivers/gpu/drm/i915/i915_params.c                 |  12 +-
 drivers/gpu/drm/imx/dc/dc-drv.c                    |   3 +
 drivers/gpu/drm/imx/dcss/dcss-drv.c                |   3 +
 drivers/gpu/drm/imx/ipuv3/imx-drm-core.c           |   2 +
 drivers/gpu/drm/logicvc/logicvc_drm.c              |   2 +
 drivers/gpu/drm/loongson/lsdc_drv.c                |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c             |   3 +
 drivers/gpu/drm/mgag200/mgag200_drv.c              |   2 +
 drivers/gpu/drm/msm/msm_drv.c                      |   3 +
 drivers/gpu/drm/nouveau/nouveau_abi16.c            |  25 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c              |  12 +-
 drivers/gpu/drm/qxl/qxl_drv.c                      |   2 +
 drivers/gpu/drm/radeon/radeon_drv.c                |   2 +
 drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c      |   2 +
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c        |   2 +
 drivers/gpu/drm/sti/sti_drv.c                      |   2 +
 drivers/gpu/drm/stm/drv.c                          |   2 +
 drivers/gpu/drm/sysfb/simpledrm.c                  |   2 +
 drivers/gpu/drm/tests/drm_mm_test.c                |   2 +
 drivers/gpu/drm/tiny/panel-mipi-dbi.c              |   2 +
 drivers/gpu/drm/ttm/ttm_device.c                   |   3 +
 drivers/gpu/drm/udl/udl_main.c                     |   2 +
 drivers/gpu/drm/vc4/vc4_drv.c                      |   2 +
 drivers/gpu/drm/virtio/virtgpu_drv.c               |   2 +
 drivers/gpu/drm/vkms/vkms_drv.c                    |   2 +
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c                |   2 +
 drivers/gpu/drm/xe/xe_module.c                     |   3 +
 include/asm-generic/bounded_sections.lds.h         |  23 +
 include/asm-generic/dyndbg.lds.h                   |  26 +
 include/asm-generic/vmlinux.lds.h                  |  48 +-
 include/drm/drm_print.h                            |  17 +-
 include/linux/dynamic_debug.h                      | 334 ++++++--
 kernel/module/main.c                               |  15 +-
 lib/Kconfig.debug                                  |  24 +-
 lib/Makefile                                       |   5 +
 lib/dynamic_debug.c                                | 889 ++++++++++++++-------
 lib/test_dynamic_debug.c                           | 211 +++--
 lib/test_dynamic_debug_submod.c                    |  21 +
 scripts/module.lds.S                               |   2 +
 tools/testing/selftests/Makefile                   |   1 +
 tools/testing/selftests/dynamic_debug/Makefile     |   9 +
 tools/testing/selftests/dynamic_debug/config       |   7 +
 .../selftests/dynamic_debug/dyndbg_selftest.sh     | 373 +++++++++
 69 files changed, 1891 insertions(+), 598 deletions(-)
---
base-commit: d662a710c668a86a39ebaad334d9960a0cc776c2
change-id: 20260419-submit-dyndbg-classmap-foundation-a3c77652c054

Best regards,
-- 
Jim Cromie <jim.cromie@gmail.com>


^ permalink raw reply

* Re: [PATCH v2 2/2] module/kallsyms: sort function symbols and use binary search
From: Petr Pavlu @ 2026-04-23 14:00 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: linux-modules, Sami Tolvanen, Luis Chamberlain, linux-kernel,
	linux-trace-kernel, live-patching, Daniel Gomez, Aaron Tomlin,
	Steven Rostedt, Masami Hiramatsu, Jordan Rome, Viktor Malik
In-Reply-To: <20260327110005.16499-2-stf_xl@wp.pl>

On 3/27/26 12:00 PM, Stanislaw Gruszka wrote:
> Module symbol lookup via find_kallsyms_symbol() performs a linear scan
> over the entire symtab when resolving an address. The number of symbols
> in module symtabs has grown over the years, largely due to additional
> metadata in non-standard sections, making this lookup very slow.
> 
> Improve this by separating function symbols during module load, placing
> them at the beginning of the symtab, sorting them by address, and using
> binary search when resolving addresses in module text.
> 
> This also should improve times for linear symbol name lookups, as valid
> function symbols are now located at the beginning of the symtab.
> 
> The cost of sorting is small relative to module load time. In repeated
> module load tests [1], depending on .config options, this change
> increases load time between 2% and 4%. With cold caches, the difference
> is not measurable, as memory access latency dominates.
> 
> The sorting theoretically could be done in compile time, but much more
> complicated as we would have to simulate kernel addresses resolution
> for symbols, and then correct relocation entries. That would be risky
> if get out of sync.
> 
> The improvement can be observed when listing ftrace filter functions.
> 
> Before:
> 
> root@nano:~# time cat /sys/kernel/tracing/available_filter_functions | wc -l
> 74908
> 
> real	0m1.315s
> user	0m0.000s
> sys	0m1.312s
> 
> After:
> 
> root@nano:~# time cat /sys/kernel/tracing/available_filter_functions | wc -l
> 74911
> 
> real	0m0.167s
> user	0m0.004s
> sys	0m0.175s
> 
> (there are three more symbols introduced by the patch)
> 
> For livepatch modules, the symtab layout is preserved and the existing
> linear search is used. For this case, it should be possible to keep
> the original ELF symtab instead of copying it 1:1, but that is outside
> the scope of this patch.
> 
> Link: https://gist.github.com/sgruszka/09f3fb1dad53a97b1aad96e1927ab117 [1]
> Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>

Sorry for the delay reviewing this patch.

> ---
> v1 -> v2: 
>  - fix searching data symbols for CONFIG_KALLSYMS_ALL
>  - use kallsyms_symbol_value() in elf_sym_cmp()
> 
>  include/linux/module.h   |   1 +
>  kernel/module/internal.h |   1 +
>  kernel/module/kallsyms.c | 171 +++++++++++++++++++++++++++++----------
>  3 files changed, 130 insertions(+), 43 deletions(-)
> 
> diff --git a/include/linux/module.h b/include/linux/module.h
> index ac254525014c..67c053afa882 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -379,6 +379,7 @@ struct module_memory {
>  struct mod_kallsyms {
>  	Elf_Sym *symtab;
>  	unsigned int num_symtab;
> +	unsigned int num_func_syms;
>  	char *strtab;
>  	char *typetab;
>  };
> diff --git a/kernel/module/internal.h b/kernel/module/internal.h
> index 618202578b42..6a4d498619b1 100644
> --- a/kernel/module/internal.h
> +++ b/kernel/module/internal.h
> @@ -73,6 +73,7 @@ struct load_info {
>  	bool sig_ok;
>  #ifdef CONFIG_KALLSYMS
>  	unsigned long mod_kallsyms_init_off;
> +	unsigned long num_func_syms;
>  #endif
>  #ifdef CONFIG_MODULE_DECOMPRESS
>  #ifdef CONFIG_MODULE_STATS
> diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
> index f23126d804b2..d69e99e67707 100644
> --- a/kernel/module/kallsyms.c
> +++ b/kernel/module/kallsyms.c
> @@ -10,6 +10,7 @@
>  #include <linux/kallsyms.h>
>  #include <linux/buildid.h>
>  #include <linux/bsearch.h>
> +#include <linux/sort.h>
>  #include "internal.h"
>  
>  /* Lookup exported symbol in given range of kernel_symbols */
> @@ -103,6 +104,95 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
>  	return true;
>  }
>  
> +static inline bool is_func_symbol(const Elf_Sym *sym)
> +{
> +	return sym->st_shndx != SHN_UNDEF && sym->st_size != 0 &&
> +	       ELF_ST_TYPE(sym->st_info) == STT_FUNC;
> +}
> +
> +static unsigned int bsearch_func_symbol(struct mod_kallsyms *kallsyms,
> +					unsigned long addr,
> +					unsigned long *bestval,
> +					unsigned long *nextval)
> +
> +{
> +	unsigned int mid, low = 1, high = kallsyms->num_func_syms + 1;
> +	unsigned int best = 0;
> +	unsigned long thisval;
> +
> +	while (low < high) {
> +		mid = low + (high - low) / 2;
> +		thisval = kallsyms_symbol_value(&kallsyms->symtab[mid]);
> +
> +		if (thisval <= addr) {
> +			*bestval = thisval;
> +			best = mid;
> +			low = mid + 1;

If thisval == addr, the search moves to the right and finds the last
symbol with the same address. I believe it should do the opposite and
return the first symbol to match the behavior of
search_kallsyms_symbol().

> +		} else {
> +			*nextval = thisval;
> +			high = mid;
> +		}
> +	}
> +
> +	return best;
> +}
> +
> +static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms,
> +					unsigned int symnum)
> +{
> +	return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
> +}
> +
> +static unsigned int search_kallsyms_symbol(struct mod_kallsyms *kallsyms,
> +					   unsigned long addr,
> +					   unsigned long *bestval,
> +					   unsigned long *nextval)
> +{
> +	unsigned int i, best = 0;
> +
> +	/*
> +	 * Scan for closest preceding symbol and next symbol. (ELF starts
> +	 * real symbols at 1). Skip the initial function symbols range
> +	 * if num_func_syms is non-zero, those are handled separately for
> +	 * the core TEXT segment lookup.
> +	 */
> +	for (i = 1 + kallsyms->num_func_syms; i < kallsyms->num_symtab; i++) {
> +		const Elf_Sym *sym = &kallsyms->symtab[i];
> +		unsigned long thisval = kallsyms_symbol_value(sym);
> +
> +		if (sym->st_shndx == SHN_UNDEF)
> +			continue;
> +
> +		/*
> +		 * We ignore unnamed symbols: they're uninformative
> +		 * and inserted at a whim.
> +		 */
> +		if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
> +		    is_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
> +			continue;
> +
> +		if (thisval <= addr && thisval > *bestval) {
> +			best = i;
> +			*bestval = thisval;
> +		}
> +		if (thisval > addr && thisval < *nextval)
> +			*nextval = thisval;
> +	}
> +
> +	return best;
> +}
> +
> +static int elf_sym_cmp(const void *a, const void *b)
> +{
> +	unsigned long val_a = kallsyms_symbol_value((const Elf_Sym *)a);
> +	unsigned long val_b = kallsyms_symbol_value((const Elf_Sym *)b);
> +
> +	if (val_a < val_b)
> +		return -1;
> +
> +	return val_a > val_b;

Does this comparison function and the sort() call result in stable
sorting? If val_a and val_b are the same, the sorting should preserve
the original order.

> +}
> +
>  /*
>   * We only allocate and copy the strings needed by the parts of symtab
>   * we keep.  This is simple, but has the effect of making multiple
> @@ -115,9 +205,10 @@ void layout_symtab(struct module *mod, struct load_info *info)
>  	Elf_Shdr *symsect = info->sechdrs + info->index.sym;
>  	Elf_Shdr *strsect = info->sechdrs + info->index.str;
>  	const Elf_Sym *src;
> -	unsigned int i, nsrc, ndst, strtab_size = 0;
> +	unsigned int i, nsrc, ndst, nfunc, strtab_size = 0;
>  	struct module_memory *mod_mem_data = &mod->mem[MOD_DATA];
>  	struct module_memory *mod_mem_init_data = &mod->mem[MOD_INIT_DATA];
> +	bool is_lp_mod = is_livepatch_module(mod);
>  
>  	/* Put symbol section at end of init part of module. */
>  	symsect->sh_flags |= SHF_ALLOC;
> @@ -129,12 +220,14 @@ void layout_symtab(struct module *mod, struct load_info *info)
>  	nsrc = symsect->sh_size / sizeof(*src);
>  
>  	/* Compute total space required for the core symbols' strtab. */
> -	for (ndst = i = 0; i < nsrc; i++) {
> -		if (i == 0 || is_livepatch_module(mod) ||
> +	for (ndst = nfunc = i = 0; i < nsrc; i++) {
> +		if (i == 0 || is_lp_mod ||
>  		    is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
>  				   info->index.pcpu)) {
>  			strtab_size += strlen(&info->strtab[src[i].st_name]) + 1;
>  			ndst++;
> +			if (!is_lp_mod && is_func_symbol(src + i))
> +				nfunc++;
>  		}
>  	}
>  
> @@ -156,6 +249,7 @@ void layout_symtab(struct module *mod, struct load_info *info)
>  	mod_mem_init_data->size = ALIGN(mod_mem_init_data->size,
>  					__alignof__(struct mod_kallsyms));
>  	info->mod_kallsyms_init_off = mod_mem_init_data->size;
> +	info->num_func_syms = nfunc;
>  
>  	mod_mem_init_data->size += sizeof(struct mod_kallsyms);
>  	info->init_typeoffs = mod_mem_init_data->size;
> @@ -169,7 +263,7 @@ void layout_symtab(struct module *mod, struct load_info *info)
>   */
>  void add_kallsyms(struct module *mod, const struct load_info *info)
>  {
> -	unsigned int i, ndst;
> +	unsigned int i, di, nfunc, ndst;
>  	const Elf_Sym *src;
>  	Elf_Sym *dst;
>  	char *s;
> @@ -178,6 +272,7 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
>  	void *data_base = mod->mem[MOD_DATA].base;
>  	void *init_data_base = mod->mem[MOD_INIT_DATA].base;
>  	struct mod_kallsyms *kallsyms;
> +	bool is_lp_mod = is_livepatch_module(mod);
>  
>  	kallsyms = init_data_base + info->mod_kallsyms_init_off;

This code is followed by the initialization of kallsyms:

	kallsyms->symtab = (void *)symsec->sh_addr;
	kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
	/* Make sure we get permanent strtab: don't use info->strtab. */
	kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
	kallsyms->typetab = init_data_base + info->init_typeoffs;

I suggest adding 'kallsyms->num_func_syms = 0;' after the initialization
of kallsyms->num_symtab.

>  
> @@ -194,19 +289,28 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
>  	mod->core_kallsyms.symtab = dst = data_base + info->symoffs;
>  	mod->core_kallsyms.strtab = s = data_base + info->stroffs;
>  	mod->core_kallsyms.typetab = data_base + info->core_typeoffs;
> +
>  	strtab_size = info->core_typeoffs - info->stroffs;
>  	src = kallsyms->symtab;
> -	for (ndst = i = 0; i < kallsyms->num_symtab; i++) {
> +	ndst = info->num_func_syms + 1;
> +
> +	for (nfunc = i = 0; i < kallsyms->num_symtab; i++) {
>  		kallsyms->typetab[i] = elf_type(src + i, info);
> -		if (i == 0 || is_livepatch_module(mod) ||
> +		if (i == 0 || is_lp_mod ||
>  		    is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
>  				   info->index.pcpu)) {
>  			ssize_t ret;
>  
> -			mod->core_kallsyms.typetab[ndst] =
> -				kallsyms->typetab[i];
> -			dst[ndst] = src[i];
> -			dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
> +			if (i == 0)
> +				di = 0;
> +			else if (!is_lp_mod && is_func_symbol(src + i))
> +				di = 1 + nfunc++;
> +			else
> +				di = ndst++;
> +
> +			mod->core_kallsyms.typetab[di] = kallsyms->typetab[i];
> +			dst[di] = src[i];
> +			dst[di].st_name = s - mod->core_kallsyms.strtab;
>  			ret = strscpy(s, &kallsyms->strtab[src[i].st_name],
>  				      strtab_size);
>  			if (ret < 0)
> @@ -216,9 +320,13 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
>  		}
>  	}
>  
> +	WARN_ON_ONCE(nfunc != info->num_func_syms);
> +	sort(dst + 1, nfunc, sizeof(Elf_Sym), elf_sym_cmp, NULL);
> +

The code sorts mod->core_kallsyms.symtab but mod->core_kallsyms.typetab
is not reordered accordingly.

>  	/* Set up to point into init section. */
>  	rcu_assign_pointer(mod->kallsyms, kallsyms);
>  	mod->core_kallsyms.num_symtab = ndst;
> +	mod->core_kallsyms.num_func_syms = nfunc;
>  }
>  
>  #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
> @@ -241,11 +349,6 @@ void init_build_id(struct module *mod, const struct load_info *info)
>  }
>  #endif
>  
> -static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, unsigned int symnum)
> -{
> -	return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
> -}
> -
>  /*
>   * Given a module and address, find the corresponding symbol and return its name
>   * while providing its size and offset if needed.
> @@ -255,7 +358,10 @@ static const char *find_kallsyms_symbol(struct module *mod,
>  					unsigned long *size,
>  					unsigned long *offset)
>  {
> -	unsigned int i, best = 0;
> +	unsigned int (*search)(struct mod_kallsyms *kallsyms,
> +			       unsigned long addr, unsigned long *bestval,
> +			       unsigned long *nextval);
> +	unsigned int best;
>  	unsigned long nextval, bestval;
>  	struct mod_kallsyms *kallsyms = rcu_dereference(mod->kallsyms);
>  	struct module_memory *mod_mem = NULL;
> @@ -266,6 +372,11 @@ static const char *find_kallsyms_symbol(struct module *mod,
>  			continue;
>  #endif
>  		if (within_module_mem_type(addr, mod, type)) {
> +			if (type == MOD_TEXT && kallsyms->num_func_syms > 0)
> +				search = bsearch_func_symbol;

I'm not sure if it is ok to limit the search only to function symbols
when the address lies in MOD_TEXT. The text can theoretically contain
non-function symbols. Could this optimization be adjusted to sort all
MOD_TEXT symbols (excluding anonymous and mapping symbols) and move them
to the front of the symbol table?

> +			else
> +				search = search_kallsyms_symbol;
> +
>  			mod_mem = &mod->mem[type];
>  			break;
>  		}
> @@ -278,33 +389,7 @@ static const char *find_kallsyms_symbol(struct module *mod,
>  	nextval = (unsigned long)mod_mem->base + mod_mem->size;
>  	bestval = (unsigned long)mod_mem->base - 1;
>  
> -	/*
> -	 * Scan for closest preceding symbol, and next symbol. (ELF
> -	 * starts real symbols at 1).
> -	 */
> -	for (i = 1; i < kallsyms->num_symtab; i++) {
> -		const Elf_Sym *sym = &kallsyms->symtab[i];
> -		unsigned long thisval = kallsyms_symbol_value(sym);
> -
> -		if (sym->st_shndx == SHN_UNDEF)
> -			continue;
> -
> -		/*
> -		 * We ignore unnamed symbols: they're uninformative
> -		 * and inserted at a whim.
> -		 */
> -		if (*kallsyms_symbol_name(kallsyms, i) == '\0' ||
> -		    is_mapping_symbol(kallsyms_symbol_name(kallsyms, i)))
> -			continue;
> -
> -		if (thisval <= addr && thisval > bestval) {
> -			best = i;
> -			bestval = thisval;
> -		}
> -		if (thisval > addr && thisval < nextval)
> -			nextval = thisval;
> -	}
> -
> +	best = search(kallsyms, addr, &bestval, &nextval);
>  	if (!best)
>  		return NULL;
>  

-- 
Thanks,
Petr

^ permalink raw reply

* Re: [PATCH] params: bound array element output to the caller's page buffer
From: Petr Pavlu @ 2026-04-23  9:34 UTC (permalink / raw)
  To: Pengpeng Hou
  Cc: Daniel Gomez, Sami Tolvanen, Kees Cook, Aaron Tomlin,
	Dmitry Antipov, Thorsten Blum, Andreas Hindborg,
	Greg Kroah-Hartman, linux-modules, linux-kernel, stable
In-Reply-To: <20260417075042.26632-1-pengpeng@iscas.ac.cn>

On 4/17/26 9:50 AM, Pengpeng Hou wrote:
> param_array_get() appends each element's string representation into the
> shared sysfs page buffer by passing buffer + off to the element getter.
> 
> That works for getters that only write a small bounded string, but
> param_get_charp() and similar helpers format against PAGE_SIZE from the
> pointer they receive. Once off is non-zero, an element getter can
> therefore write past the end of the original sysfs page buffer.
> 
> Collect each element into a temporary PAGE_SIZE buffer first and then
> copy only the remaining space into the caller's page buffer.

The underlying issue is that the kernel_param_ops::get() callback only
takes a pointer to a buffer where the result should be stored, with the
implicit knowledge that it is at least PAGE_SIZE in size. The params
code apparently borrows this from the sysfs code, which is
understandable because only sysfs can currently print module parameters.

Nonetheless, the question is whether it would be better to rework the
kernel_param_ops::get() callback to also include a size argument. This
modification would prevent the copying in param_array_get() and having
an explicit size is generally a better interface. It could also be
useful for Rust integration, even though the current code doesn't
support reading module parameters via sysfs. However, this change would
require more work to update all current implementations of this
callback.

-- 
Thanks,
Petr

> 
> Fixes: 9bbb9e5a3310 ("param: use ops in struct kernel_param, rather than get and set fns directly")
> Cc: stable@vger.kernel.org
> 
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
>  kernel/params.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/params.c b/kernel/params.c
> index 74d620bc2521..8910daa12816 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -475,22 +475,34 @@ static int param_array_set(const char *val, const struct kernel_param *kp)
>  static int param_array_get(char *buffer, const struct kernel_param *kp)
>  {
>  	int i, off, ret;
> +	char *elem_buf;
>  	const struct kparam_array *arr = kp->arr;
>  	struct kernel_param p = *kp;
>  
> +	elem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
> +	if (!elem_buf)
> +		return -ENOMEM;
> +
>  	for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
>  		/* Replace \n with comma */
>  		if (i)
>  			buffer[off - 1] = ',';
>  		p.arg = arr->elem + arr->elemsize * i;
>  		check_kparam_locked(p.mod);
> -		ret = arr->ops->get(buffer + off, &p);
> +		ret = arr->ops->get(elem_buf, &p);
>  		if (ret < 0)
> -			return ret;
> +			goto out;
> +		ret = min(ret, (int)(PAGE_SIZE - 1 - off));
> +		memcpy(buffer + off, elem_buf, ret);
>  		off += ret;
> +		if (off == PAGE_SIZE - 1)
> +			break;
>  	}
>  	buffer[off] = '\0';
> -	return off;
> +	ret = off;
> +out:
> +	kfree(elem_buf);
> +	return ret;
>  }
>  
>  static void param_array_free(void *arg)


^ permalink raw reply

* Re: [RFC] btf: split core BTF parsing out of BPF subsystem into kernel/btf/
From: Alexei Starovoitov @ 2026-04-22 14:48 UTC (permalink / raw)
  To: Alan Maguire
  Cc: Sasha Levin, James Bottomley, Alexey Dobriyan, Andrew Morton,
	Alexei Starovoitov, Borislav Petkov, bpf, Jonathan Corbet,
	Dave Hansen, David Gow, Helge Deller, Geert Uytterhoeven,
	Greg Kroah-Hartman, H. Peter Anvin, Juergen Gross, Josh Poimboeuf,
	Kees Cook, Laurent Pinchart, open list:DOCUMENTATION,
	Linux Kbuild mailing list, LKML, linux-modules, Masahiro Yamada,
	Luis R. Rodriguez, Ingo Molnar, Nathan Chancellor, Nicolas Schier,
	Peter Zijlstra, Petr Pavlu, Petr Mladek, Randy Dunlap,
	Steven Rostedt, Thomas Gleixner, Vlastimil Babka, X86 ML
In-Reply-To: <c7a8310e-501f-48a8-8ad5-0a40d8b3836b@oracle.com>

On Wed, Apr 22, 2026 at 3:44 AM Alan Maguire <alan.maguire@oracle.com> wrote:
>
> On 25/03/2026 01:18, Sasha Levin wrote:
> > Move BTF type format parsing and inspection code out of the BPF
> > subsystem into its own kernel/bf/ directory, separating core BTF
> > functionality from BPF-specific extensions.
> >
> > CONFIG_DEBUG_INFO_BTF currently depends on CONFIG_BPF_SYSCALL, which
> > prevents embedded, automotive, and safety-critical environments from
> > using BTF. These platforms often disable BPF for security and size
> > reasons but would benefit from BTF type information for crash
> > diagnostics and debugging.
> >
>
> I had a go at a refactor in this area too, and it's pretty tricky. How about
> we start with a smaller goal; making /sys/kernel/btf available to userspace
> on systems without CONFIG_BPF_SYSCALL? This would just involve a small refactor
> of the BTF module-related stuff in kernel/bpf/btf.c, moving it to btf_module.c
> or similar say. No need to split out BTF parsing APIs from those actively used in
> validating BPF etc, since a non-BPF_SYSCALL system would not need to parse BTF
> in the kernel (just make it available in sysfs.

Small refactor is ok, but in general I'm not interested
in complicating code for systems without CONFIG_BPF_SYSCALL.

^ permalink raw reply

* Re: [RFC] btf: split core BTF parsing out of BPF subsystem into kernel/btf/
From: Alan Maguire @ 2026-04-22 10:44 UTC (permalink / raw)
  To: Sasha Levin
  Cc: James.Bottomley, adobriyan, akpm, alexei.starovoitov, ast, bp,
	bpf, corbet, dave.hansen, davidgow, deller, geert, gregkh, hpa,
	jgross, jpoimboe, kees, laurent.pinchart, linux-doc, linux-kbuild,
	linux-kernel, linux-modules, masahiroy, mcgrof, mingo, nathan,
	nsc, peterz, petr.pavlu, pmladek, rdunlap, rostedt, tglx, vbabka,
	x86
In-Reply-To: <20260325011853.657295-1-sashal@kernel.org>

On 25/03/2026 01:18, Sasha Levin wrote:
> Move BTF type format parsing and inspection code out of the BPF
> subsystem into its own kernel/bf/ directory, separating core BTF
> functionality from BPF-specific extensions.
> 
> CONFIG_DEBUG_INFO_BTF currently depends on CONFIG_BPF_SYSCALL, which
> prevents embedded, automotive, and safety-critical environments from
> using BTF. These platforms often disable BPF for security and size
> reasons but would benefit from BTF type information for crash
> diagnostics and debugging.
> 

I had a go at a refactor in this area too, and it's pretty tricky. How about
we start with a smaller goal; making /sys/kernel/btf available to userspace
on systems without CONFIG_BPF_SYSCALL? This would just involve a small refactor 
of the BTF module-related stuff in kernel/bpf/btf.c, moving it to btf_module.c 
or similar say. No need to split out BTF parsing APIs from those actively used in 
validating BPF etc, since a non-BPF_SYSCALL system would not need to parse BTF 
in the kernel (just make it available in sysfs.

^ permalink raw reply

* Re: [PATCH] kernel/trace/ftrace: introduce ftrace module notifier
From: Song Liu @ 2026-04-21 22:40 UTC (permalink / raw)
  To: Song Chen
  Cc: Petr Mladek, Steven Rostedt, Miroslav Benes, mcgrof, petr.pavlu,
	da.gomez, samitolvanen, atomlin, mhiramat, mark.rutland,
	mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, live-patching
In-Reply-To: <4037aa19-1b01-4076-b823-5cc0e43becac@189.cn>

Hi,

I am replying partially to make sure folks know there are two
persons with the same first name.

On Sun, Apr 12, 2026 at 7:11 AM Song Chen <chensong_2000@189.cn> wrote:
[...]
> >
> >    + We would need to make sure that it does not break some
> >      existing "hidden" dependencies.
> >
> Thanks so much, this is the solution i'm working on. I replaced next
> with a list_head in notifier_block and implemented
> anotifier_call_chain_reverse to address the order issues, like your
> suggestion. And a new robust revision for rolling back.

I personally don't think there is strong enough motivation to make
changes like the following. If there is indeed strong motivations,
please make it clear in the next revision.

Thanks,
Song

^ permalink raw reply

* Re: [RFC PATCH 1/2] kernel/notifier: replace single-linked list with double-linked list for reverse traversal
From: Petr Mladek @ 2026-04-21  9:05 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: chensong_2000, rafael, lenb, mturquette, sboyd, viresh.kumar, agk,
	snitzer, mpatocka, bmarzins, song, yukuai, linan122, jason.wessel,
	danielt, dianders, horms, davem, edumazet, kuba, pabeni, paulmck,
	frederic, mcgrof, petr.pavlu, da.gomez, samitolvanen, atomlin,
	jpoimboe, jikos, mbenes, joe.lawrence, rostedt, mark.rutland,
	mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <20260420144429.57b45f2beece690bceea96ec@kernel.org>

On Mon 2026-04-20 14:44:29, Masami Hiramatsu wrote:
> Hi Song,
> 
> On Wed, 15 Apr 2026 15:01:37 +0800
> chensong_2000@189.cn wrote:
> 
> > From: Song Chen <chensong_2000@189.cn>
> > 
> > The current notifier chain implementation uses a single-linked list
> > (struct notifier_block *next), which only supports forward traversal
> > in priority order. This makes it difficult to handle cleanup/teardown
> > scenarios that require notifiers to be called in reverse priority order.
> 
> What about introducing a new notification callback API that allows you
> to describe dependencies between callback functions?
> 
> For example, when registering a callback, you could register a string
> as an ID and specify whether to call it before or after that ID,
> or you could register a comparison function that is called when adding
> to a list. (I prefer @name and @depends fields so that it can be easily
> maintained.)

This looks too complex. It would make sense only
when this API has more users.

Also this won't be enough for the ftrace/livepatch callbacks.
They need to be ordered against against each other. But they
also need to be called before/after all other callbacks.
For example, when the module is loaded:

   + 1st frace
   + 2nd livepatch
   + then other notifiers

See the commit c1bf08ac26e92122 ("ftrace: Be first to run code
modification on modules").

> This would allow for better dependency building when adding to the list.
 
> > 
> > A concrete example is the ordering dependency between ftrace and
> > livepatch during module load/unload. see the detail here [1].
> 
> If this only concerns notification callback issues with the ftrace
> and livepatch modules, it's far more robust to simply call the
> necessary processing directly when the modules load and unload,
> rather than registering notification callbacks externally.
> 
> There are fprobe, kprobe and its trace-events, all of them are using
> ftrace as its fundation layer. In this case, I always needs to
> consider callback order when a module is unloaded.
> 
> If ftrace is working as a part of module callbacks, it will conflict
> with fprobe/kprobe module callback. Of course we can reorder it with
> modifying its priority. But this is ugly, because when we introduce
> a new other feature which depends on another layer, we need to
> reorder the callback's priority number on the list.
> 
> Based on the above, I don't think this can be resolved simply by
> changing the list of notification callbacks to a bidirectional list.

I agree. I would keep it as is (hardcoded).

Best Regards,
Petr

^ permalink raw reply

* [PATCH AUTOSEL 7.0-5.15] module: Override -EEXIST module return
From: Sasha Levin @ 2026-04-20 13:18 UTC (permalink / raw)
  To: patches, stable
  Cc: Lucas De Marchi, Greg Kroah-Hartman, Aaron Tomlin, Petr Pavlu,
	Daniel Gomez, Phil Sutter, Christophe Leroy, Sami Tolvanen,
	Sasha Levin, mcgrof, da.gomez, linux-modules, linux-kernel
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>

From: Lucas De Marchi <demarchi@kernel.org>

[ Upstream commit 743f8cae549affe8eafb021b8c0e78a9f3bc23fa ]

The -EEXIST errno is reserved by the module loading functionality. When
userspace calls [f]init_module(), it expects a -EEXIST to mean that the
module is already loaded in the kernel. If module_init() returns it,
that is not true anymore.

Override the error when returning to userspace: it doesn't make sense to
change potentially long error propagation call chains just because it's
will end up as the return of module_init().

Closes: https://lore.kernel.org/all/aKLzsAX14ybEjHfJ@orbyte.nwl.cc/
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Aaron Tomlin <atomlin@atomlin.com>
Cc: Petr Pavlu <petr.pavlu@suse.com>
Cc: Daniel Gomez <da.gomez@samsung.com>
Cc: Phil Sutter <phil@nwl.cc>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Lucas De Marchi <demarchi@kernel.org>
[Sami: Fixed a typo.]
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Now I have comprehensive context. Let me compile the final analysis.

---

## PHASE 1: COMMIT MESSAGE FORENSICS

### Step 1.1: PARSE THE SUBJECT LINE
- **Subsystem:** module (kernel/module)
- **Action verb:** "Override" — correcting incorrect behavior
- **Summary:** Override module_init's -EEXIST return to prevent
  userspace confusion
- Record: [module] [override/correct] [Prevent -EEXIST from module_init
  reaching userspace, where it's misinterpreted as "module already
  loaded"]

### Step 1.2: PARSE ALL COMMIT MESSAGE TAGS
- **Closes:**
  https://lore.kernel.org/all/aKLzsAX14ybEjHfJ@orbyte.nwl.cc/ — Phil
  Sutter's bug report
- **Cc:** Greg Kroah-Hartman, Aaron Tomlin, Petr Pavlu, Daniel Gomez,
  Phil Sutter, Christophe Leroy — multiple well-known kernel developers
- **Signed-off-by:** Lucas De Marchi (author), Sami Tolvanen (picked up,
  fixed typo)
- **No Fixes: tag** — expected for manual review candidates
- Record: Notable that Phil Sutter (netfilter maintainer) is CC'd and
  the bug report is his. Greg KH is CC'd (he suggested this approach).

### Step 1.3: ANALYZE THE COMMIT BODY TEXT
The commit explains: `-EEXIST` is **reserved** by the module loading
infrastructure. When userspace calls `[f]init_module()`, it expects
`-EEXIST` to mean "module is already loaded." The man page explicitly
documents `EEXIST - A module with this name is already loaded.` If a
module's init() returns -EEXIST (e.g., because a registration function
found a duplicate), this error reaches userspace where kmod/modprobe
interprets it as "already loaded" and reports **success** (0) to the
user. The module actually failed to initialize but the user is told it
succeeded.

Record: [Bug: init failures returning -EEXIST are silently swallowed by
userspace tools] [Symptom: modprobe reports success when module init
actually failed] [Root cause: collision between kernel-internal -EEXIST
meaning and module loader's reserved -EEXIST meaning]

### Step 1.4: DETECT HIDDEN BUG FIXES
This is an explicit bug fix — the commit clearly describes incorrect
behavior visible to users.
Record: [Not hidden — clearly a bug fix for incorrect error propagation
to userspace]

---

## PHASE 2: DIFF ANALYSIS - LINE BY LINE

### Step 2.1: INVENTORY THE CHANGES
- **Files:** `kernel/module/main.c` — single file
- **Lines added:** +8 (5 comment lines + 3 code lines)
- **Lines removed:** 0
- **Function modified:** `do_init_module()`
- Record: [kernel/module/main.c +8 lines] [do_init_module()] [single-
  file surgical fix]

### Step 2.2: UNDERSTAND THE CODE FLOW CHANGE
In the `if (ret < 0)` block after `do_one_initcall(mod->init)`:
- **Before:** ret passes through unchanged to `fail_free_freeinit` error
  path, eventually returned to userspace via `load_module()` → syscall
- **After:** If `ret == -EEXIST`, it's changed to `-EBUSY` before
  proceeding to the error path
- This ensures userspace never sees `-EEXIST` from a module init failure
Record: [Error path change: -EEXIST is remapped to -EBUSY before
reaching userspace]

### Step 2.3: IDENTIFY THE BUG MECHANISM
Category: **Logic/correctness fix**
- The kernel module loader uses `-EEXIST` as a special sentinel to mean
  "module already loaded" (in `module_patient_check_exists()`)
- Userspace tools (kmod/modprobe) rely on this convention to silently
  succeed when a module is loaded twice
- When `module_init()` returns `-EEXIST` for an unrelated reason (e.g.,
  registration collision), userspace misinterprets it
- Fix: translate `-EEXIST` to `-EBUSY` at the boundary between module
  init and error reporting
Record: [Logic/correctness: -EEXIST overloading causes userspace to
misinterpret module init failures as success]

### Step 2.4: ASSESS THE FIX QUALITY
- **Obviously correct:** Yes — simple conditional check and error code
  substitution
- **Minimal:** Yes — 3 lines of code + 5 lines of comment
- **Regression risk:** Extremely low — changes behavior only when module
  init returns -EEXIST (which is already a failure), and the change is
  from "silently succeed" to "properly report failure"
- **Approach endorsed by Greg KH:** He explicitly suggested this
  approach instead of the "whack-a-mole" approach of fixing every
  individual module
Record: [Fix quality: excellent — minimal, obviously correct, low
regression risk, approach endorsed by GKH]

---

## PHASE 3: GIT HISTORY INVESTIGATION

### Step 3.1: BLAME THE CHANGED LINES
The modified code (`do_one_initcall` + `if (ret < 0) { goto
fail_free_freeinit; }`) was introduced by commit `34e1169d996ab1` by
Kees Cook in October 2012. This code has been stable since v3.7+.
Record: [Buggy code pattern present since 2012 (v3.7), exists in ALL
active stable trees]

### Step 3.2: FOLLOW THE FIXES TAG
No Fixes: tag present (expected for autosel candidates). The underlying
issue is as old as the module loader's use of -EEXIST, which has been in
the kernel for many years.

### Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES
Recent module/main.c changes are unrelated: panic fix, lockdep cleanup,
kmalloc_obj conversion. No conflicting changes near the modified code
area.
Record: [No related changes, standalone fix]

### Step 3.4: CHECK THE AUTHOR'S OTHER COMMITS
Lucas De Marchi is a well-known kernel developer (xe/i915 DRM
maintainer, kmod maintainer). He has deep understanding of module
loading. Sami Tolvanen co-signed (known for module/CFI work).
Record: [Author is kmod maintainer — very authoritative on this topic]

### Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS
No dependencies. The fix adds a simple conditional inside an existing
`if` block. The code pattern exists identically in v5.15, v6.1, v6.6,
and all active stable trees.
Record: [Fully standalone, applies cleanly to all stable trees]

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

### Step 4.1-4.2: PATCH DISCUSSION
From the mailing list discussion found:
- Phil Sutter (netfilter maintainer) reported this bug when
  `nf_conntrack_helper_register()` returned -EEXIST to init_module,
  causing kmod to treat the failure as success
- Daniel Gomez attempted to fix individual modules, but Greg KH
  explicitly said "let the module loader do the translation" rather than
  playing whack-a-mole
- Lucas De Marchi agreed and implemented the module loader approach
- This patch is the consensus solution agreed upon by GKH, Lucas De
  Marchi, and Daniel Gomez
Record: [Greg KH explicitly suggested this approach; multiple
maintainers agreed]

### Step 4.3: BUG REPORT
Phil Sutter's report (aKLzsAX14ybEjHfJ@orbyte.nwl.cc) demonstrates this
is a real user-visible bug. The precedent fix (commit 54416fd76770 for
netfilter) was already merged in August 2025. At least 40+ modules
across the kernel tree can potentially hit this issue.
Record: [Real bug reported by netfilter maintainer; 40+ modules
affected]

### Step 4.5: STABLE MAILING LIST
The "dm: replace -EEXIST with -EBUSY" commit was already selected for
stable 6.19.y backporting, showing this class of bugs is considered
stable-worthy.
Record: [Related fixes (individual module -EEXIST → -EBUSY) already in
stable queues]

---

## PHASE 5: CODE SEMANTIC ANALYSIS

### Step 5.1-5.2: KEY FUNCTIONS AND CALLERS
- `do_init_module()` is called from `load_module()`
- `load_module()` is called from `init_module` syscall and
  `finit_module` syscall
- Every module load in the system passes through this code path
Record: [Universal code path — affects every module load operation]

### Step 5.4: CALL CHAIN
`finit_module()` syscall → `idempotent_init_module()` →
`init_module_from_file()` → `load_module()` → `do_init_module()` →
`do_one_initcall(mod->init)` → ret flows back to userspace
Record: [ret from module init reaches userspace directly — any -EEXIST
is seen by kmod]

---

## PHASE 6: CROSS-REFERENCING AND STABLE TREE ANALYSIS

### Step 6.1: DOES THE BUGGY CODE EXIST IN STABLE TREES?
Verified: The exact same code pattern exists in v6.6 and v5.15:

```c
if (mod->init != NULL)
    ret = do_one_initcall(mod->init);
if (ret < 0) {
    goto fail_free_freeinit;
}
```

This code has been unchanged since 2012. It exists in ALL active stable
trees.
Record: [Buggy code present in all stable trees: 5.15.y, 6.1.y, 6.6.y,
6.12.y, 6.19.y]

### Step 6.2: CHECK FOR BACKPORT COMPLICATIONS
The patch adds code inside the `if (ret < 0)` block which is identical
across all stable trees. Should apply cleanly with no conflicts.
Record: [Clean apply expected across all stable trees]

---

## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT

### Step 7.1: SUBSYSTEM CRITICALITY
- **Subsystem:** kernel/module (CORE)
- Module loading affects every kernel user who loads any module
- Criticality: **CORE** — every system loads modules
Record: [CORE subsystem; affects all users who load kernel modules]

---

## PHASE 8: IMPACT AND RISK ASSESSMENT

### Step 8.1: WHO IS AFFECTED
ALL users who load kernel modules — universal. Specifically affects
users whose modules' init functions return -EEXIST from internal
registration functions (documented: 40+ modules identified).
Record: [Universal impact — all module loading users]

### Step 8.2: TRIGGER CONDITIONS
Any module whose init() path returns -EEXIST (e.g., due to registration
collision). Phil Sutter triggered it with netfilter conntrack helpers.
At least 40+ modules can potentially hit this.
Record: [Triggered by any module init returning -EEXIST; multiple known
triggering modules]

### Step 8.3: FAILURE MODE SEVERITY
When triggered: userspace reports **success** for a module that **failed
to initialize**. The user has no indication the module isn't working.
For netfilter, this means conntrack helpers silently don't register and
connection tracking breaks.
Record: [Severity: HIGH — silent failure, user unaware their module
isn't functional]

### Step 8.4: RISK-BENEFIT RATIO
- **Benefit:** HIGH — fixes silent module init failures across 40+
  modules
- **Risk:** VERY LOW — 3 lines of code, simple error code translation,
  only affects error paths where init already failed
- **Ratio:** Strongly favorable for backporting
Record: [High benefit, very low risk]

---

## PHASE 9: FINAL SYNTHESIS

### Step 9.1: EVIDENCE
**FOR backporting:**
- Fixes a real, user-reported bug (Phil Sutter, netfilter maintainer)
- Silent failures are dangerous — users believe module is loaded when it
  isn't
- Affects ALL stable trees (code unchanged since 2012)
- Tiny patch: 3 lines of code + comment
- Obviously correct: simple error code translation
- Approach explicitly endorsed by Greg Kroah-Hartman
- Author is kmod maintainer (Lucas De Marchi)
- Related individual module fixes already selected for stable
- Clean apply expected across all stable trees

**AGAINST backporting:**
- None identified

### Step 9.2: STABLE RULES CHECKLIST
1. Obviously correct and tested? **YES** — trivial code, endorsed by GKH
2. Fixes a real bug that affects users? **YES** — module init failures
   silently ignored
3. Important issue? **YES** — silent failure can cause unexpected broken
   functionality
4. Small and contained? **YES** — 8 lines, single file, single function
5. No new features or APIs? **YES** — pure bug fix
6. Can apply to stable trees? **YES** — identical code pattern in all
   trees

### Step 9.3: EXCEPTION CATEGORIES
Not an exception case — this is a straightforward bug fix that meets all
standard criteria.

---

## Verification

- [Phase 1] Parsed commit message: Closes: tag to Phil Sutter's bug
  report, CCs to GKH and module developers
- [Phase 2] Diff analysis: +8 lines in do_init_module(), adds -EEXIST →
  -EBUSY translation in error path
- [Phase 3] git blame: buggy code introduced by 34e1169d996ab1 (Kees
  Cook, 2012, v3.7), present in all stable trees
- [Phase 3] Verified same code in v6.6: `git show
  v6.6:kernel/module/main.c` — identical pattern at line 2531
- [Phase 3] Verified same code in v5.15: `git show
  v5.15:kernel/module.c` — identical pattern at line 3696
- [Phase 3] No dependencies: fix is standalone
- [Phase 4] Mailing list: GKH explicitly suggested the module-loader-
  level approach (lkml.iu.edu/2601.1/00694.html)
- [Phase 4] Related dm -EEXIST fix already in stable 6.19 queue
  (spinics.net)
- [Phase 4] man page confirms: EEXIST = "module with this name is
  already loaded" (kernel.org man page)
- [Phase 5] Call chain: syscall → load_module → do_init_module → ret
  reaches userspace directly
- [Phase 6] Clean apply: code pattern identical in
  v5.15/v6.1/v6.6/v6.12/v6.19
- [Phase 8] Severity: HIGH — silent failure, user unaware module isn't
  functional
- [Phase 8] Risk: VERY LOW — 3 lines, only affects already-failing error
  path

This is a small, obviously correct bug fix for a real user-reported
issue. It prevents userspace tools from silently treating module
initialization failures as successes. The fix was developed at Greg
Kroah-Hartman's explicit suggestion, implemented by the kmod maintainer,
and applies cleanly to all stable trees. The benefit (preventing silent
module failures) far outweighs the negligible risk.

**YES**

 kernel/module/main.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/module/main.c b/kernel/module/main.c
index c3ce106c70af1..f6704856249df 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -3045,6 +3045,14 @@ static noinline int do_init_module(struct module *mod)
 	if (mod->init != NULL)
 		ret = do_one_initcall(mod->init);
 	if (ret < 0) {
+		/*
+		 * -EEXIST is reserved by [f]init_module() to signal to userspace that
+		 * a module with this name is already loaded. Use something else if the
+		 * module itself is returning that.
+		 */
+		if (ret == -EEXIST)
+			ret = -EBUSY;
+
 		goto fail_free_freeinit;
 	}
 	if (ret > 0) {
-- 
2.53.0


^ permalink raw reply related

* Re: [RFC PATCH 1/2] kernel/notifier: replace single-linked list with double-linked list for reverse traversal
From: Masami Hiramatsu @ 2026-04-20  5:44 UTC (permalink / raw)
  To: chensong_2000
  Cc: rafael, lenb, mturquette, sboyd, viresh.kumar, agk, snitzer,
	mpatocka, bmarzins, song, yukuai, linan122, jason.wessel, danielt,
	dianders, horms, davem, edumazet, kuba, pabeni, paulmck, frederic,
	mcgrof, petr.pavlu, da.gomez, samitolvanen, atomlin, jpoimboe,
	jikos, mbenes, pmladek, joe.lawrence, rostedt, mark.rutland,
	mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <20260415070137.17860-1-chensong_2000@189.cn>

Hi Song,

On Wed, 15 Apr 2026 15:01:37 +0800
chensong_2000@189.cn wrote:

> From: Song Chen <chensong_2000@189.cn>
> 
> The current notifier chain implementation uses a single-linked list
> (struct notifier_block *next), which only supports forward traversal
> in priority order. This makes it difficult to handle cleanup/teardown
> scenarios that require notifiers to be called in reverse priority order.

What about introducing a new notification callback API that allows you
to describe dependencies between callback functions?

For example, when registering a callback, you could register a string
as an ID and specify whether to call it before or after that ID,
or you could register a comparison function that is called when adding
to a list. (I prefer @name and @depends fields so that it can be easily
maintained.)

This would allow for better dependency building when adding to the list.

> 
> A concrete example is the ordering dependency between ftrace and
> livepatch during module load/unload. see the detail here [1].

If this only concerns notification callback issues with the ftrace
and livepatch modules, it's far more robust to simply call the
necessary processing directly when the modules load and unload,
rather than registering notification callbacks externally.

There are fprobe, kprobe and its trace-events, all of them are using
ftrace as its fundation layer. In this case, I always needs to
consider callback order when a module is unloaded.

If ftrace is working as a part of module callbacks, it will conflict
with fprobe/kprobe module callback. Of course we can reorder it with
modifying its priority. But this is ugly, because when we introduce
a new other feature which depends on another layer, we need to
reorder the callback's priority number on the list.

Based on the above, I don't think this can be resolved simply by
changing the list of notification callbacks to a bidirectional list.

Thank you,

-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [RFC PATCH 2/2] kernel/module: Decouple klp and ftrace from load_module
From: Masami Hiramatsu @ 2026-04-20  2:27 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Petr Pavlu, Song Chen, rafael, lenb, mturquette, sboyd,
	viresh.kumar, agk, snitzer, mpatocka, bmarzins, song, yukuai,
	linan122, jason.wessel, danielt, dianders, horms, davem, edumazet,
	kuba, pabeni, paulmck, frederic, mcgrof, da.gomez, samitolvanen,
	atomlin, jpoimboe, jikos, mbenes, joe.lawrence, rostedt, mhiramat,
	mark.rutland, mathieu.desnoyers, linux-modules, linux-kernel,
	linux-trace-kernel, linux-acpi, linux-clk, linux-pm,
	live-patching, dm-devel, linux-raid, kgdb-bugreport, netdev
In-Reply-To: <aeD2_FrFL6E3dbAC@pathway.suse.cz>

On Thu, 16 Apr 2026 16:49:32 +0200
Petr Mladek <pmladek@suse.com> wrote:

> On Thu 2026-04-16 13:18:30, Petr Pavlu wrote:
> > On 4/15/26 8:43 AM, Song Chen wrote:
> > > On 4/14/26 22:33, Petr Pavlu wrote:
> > >> On 4/13/26 10:07 AM, chensong_2000@189.cn wrote:
> > >>> diff --git a/include/linux/module.h b/include/linux/module.h
> > >>> index 14f391b186c6..0bdd56f9defd 100644
> > >>> --- a/include/linux/module.h
> > >>> +++ b/include/linux/module.h
> > >>> @@ -308,6 +308,14 @@ enum module_state {
> > >>>       MODULE_STATE_COMING,    /* Full formed, running module_init. */
> > >>>       MODULE_STATE_GOING,    /* Going away. */
> > >>>       MODULE_STATE_UNFORMED,    /* Still setting it up. */
> > >>> +    MODULE_STATE_FORMED,
> > >>
> > >> I don't see a reason to add a new module state. Why is it necessary and
> > >> how does it fit with the existing states?
> > >>
> > > because once notifier fails in state MODULE_STATE_UNFORMED (now only ftrace has someting to do in this state), notifier chain will roll back by calling blocking_notifier_call_chain_robust, i'm afraid MODULE_STATE_GOING is going to jeopardise the notifers which don't handle it appropriately, like:
> > > 
> > > case MODULE_STATE_COMING:
> > >      kmalloc();
> > > case MODULE_STATE_GOING:
> > >      kfree();
> > 
> > My understanding is that the current module "state machine" operates as
> > follows. Transitions marked with an asterisk (*) are announced via the
> > module notifier.
> > 
> > ---> UNFORMED --*> COMING --*> LIVE --*> GOING -.
> >         ^            |                     ^    |
> >         |            '---------------------*    |
> >         '---------------------------------------'
> > 
> > The new code aims to replace the current ftrace_module_init() call in
> > load_module(). To achieve this, it adds a notification for the UNFORMED
> > state (only when loading a module) and introduces a new FORMED state for
> > rollback. FORMED is purely a fake state because it never appears in
> > module::state. The new structure is as follows:
> > 
> >         ,--*> (FORMED)
> >         |
> > --*> UNFORMED --*> COMING --*> LIVE --*> GOING -.
> >         ^            |                     ^    |
> >         |            '---------------------*    |
> >         '---------------------------------------'
> > 
> > I'm afraid this is quite complex and inconsistent. Unless it can be kept
> > simple, we would be just replacing one special handling with a different
> > complexity, which is not worth it.
> 
> > >>
> > >>> +    if (err)
> > >>> +        goto ddebug_cleanup;
> > >>>         /* Finally it's fully formed, ready to start executing. */
> > >>>       err = complete_formation(mod, info);
> > >>> -    if (err)
> > >>> +    if (err) {
> > >>> +        blocking_notifier_call_chain_reverse(&module_notify_list,
> > >>> +                MODULE_STATE_FORMED, mod);
> > >>>           goto ddebug_cleanup;
> > >>> +    }
> > >>>   -    err = prepare_coming_module(mod);
> > >>> +    err = prepare_module_state_transaction(mod,
> > >>> +                MODULE_STATE_COMING, MODULE_STATE_GOING);
> > >>>       if (err)
> > >>>           goto bug_cleanup;
> > >>>   @@ -3522,7 +3519,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
> > >>>       destroy_params(mod->kp, mod->num_kp);
> > >>>       blocking_notifier_call_chain(&module_notify_list,
> > >>>                        MODULE_STATE_GOING, mod);
> > >>
> > >> My understanding is that all notifier chains for MODULE_STATE_GOING
> > >> should be reversed.
> > > yes, all, from lowest priority notifier to highest.
> > > I will resend patch 1 which was failed due to my proxy setting.
> > 
> > What I meant here is that the call:
> > 
> > blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod);
> > 
> > should be replaced with:
> > 
> > blocking_notifier_call_chain_reverse(&module_notify_list, MODULE_STATE_GOING, mod);
> > 
> > > 
> > >>
> > >>> -    klp_module_going(mod);
> > >>>    bug_cleanup:
> > >>>       mod->state = MODULE_STATE_GOING;
> > >>>       /* module_bug_cleanup needs module_mutex protection */
> > >>
> > >> The patch removes the klp_module_going() cleanup call in load_module().
> > >> Similarly, the ftrace_release_mod() call under the ddebug_cleanup label
> > >> should be removed and appropriately replaced with a cleanup via
> > >> a notifier.
> > >>
> > >     err = prepare_module_state_transaction(mod,
> > >                 MODULE_STATE_UNFORMED, MODULE_STATE_FORMED);
> > >     if (err)
> > >         goto ddebug_cleanup;
> > > 
> > > ftrace will be cleanup in blocking_notifier_call_chain_robust rolling back.
> > > 
> > >     err = prepare_module_state_transaction(mod,
> > >                 MODULE_STATE_COMING, MODULE_STATE_GOING);
> > > 
> > > each notifier including ftrace and klp will be cleanup in blocking_notifier_call_chain_robust rolling back.
> > > 
> > > if all notifiers are successful in MODULE_STATE_COMING, they all will be clean up in
> > >  coming_cleanup:
> > >     mod->state = MODULE_STATE_GOING;
> > >     destroy_params(mod->kp, mod->num_kp);
> > >     blocking_notifier_call_chain(&module_notify_list,
> > >                      MODULE_STATE_GOING, mod);
> > > 
> > > if  something wrong underneath.
> > 
> > My point is that the patch leaves a call to ftrace_release_mod() in
> > load_module(), which I expected to be handled via a notifier.
> 
> I think that I have got it. The ftrace code needs two notifiers when
> the module is being loaded and two when it is going.
> 
> This is why Sond added the new state. But I think that we would
> need two new states to call:
> 
>     + ftrace_module_init() in MODULE_STATE_UNFORMED
>     + ftrace_module_enable() in MODULE_STATE_FORMED
> 
> and
> 
>     + ftrace_free_mem() in MODULE_STATE_PRE_GOING
>     + ftrace_free_mem() in MODULE_STATE_GOING
> 
> 
> By using the ascii art:
> 
>  -*> UNFORMED -*> FORMED -> COMING -*> LIVE -*> PRE_GOING -*> GOING -.
>               |          |         |                ^           ^    ^
>               |          |         '----------------'           |    |
>               |          '--------------------------------------'    |
>               '------------------------------------------------------'
> 
> 
> But I think that this is not worth it.

Agree.

If this needs to be ordered so strictly, why we will use a "single"
module notifier chain for this complex situation?

I think the notifier call chain is just for notice a single signal,
instead of sending several different signals, especially if there is
any dependency among the callbacks.

If notification callbacks need to be ordered, they are currently
sorted by representing priority numerically, but this is quite
fragile for updating. It has to look up other registered priorities
and adjust the order among dependencies each time. For this reason,
this mechanism is not suitable for global ordering. (It's like line
numbers in BASIC.)
It is probably only useful for representing dependencies between
two components maintained by the same maintainer.

I'm against a general-purpose system that makes everything modular.
It unnecessarily complicates things. If there are processes that
require strict ordering, especially processes that must be performed
before each stage as part of the framework, they should be called
directly from the framework, not via notification callbacks.

This makes it simpler and more robust to maintain.

Only the framework's end users should utilize notification callbacks.

Thank you,


> 
> Best Regards,
> Petr
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply


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