* [PATCH v2 01/59] vmlinux.lds.h: fixup HEADERED_SECTION{,_BY} macros
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 02/59] docs/dyndbg: update examples \012 to \n Jim Cromie
` (57 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
commit 1d926e259d8f ("vmlinux.lds.h: add HEADERED_SECTION_* macros")
I flubbed the defn of the outer 2 macros; they missed the extra arg
needed: _front/_hdr. Fix it now, before anyone notices.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
include/asm-generic/vmlinux.lds.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 0d5b186abee8..c9c66089ea2f 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -219,10 +219,11 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
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_BY(_sec_, _label_, _front) \
+ HEADERED_SECTION_PRE_LABEL(_sec_, _label_, __start, __stop, _front)
-#define HEADERED_SECTION(_sec) HEADERED_SECTION_BY(_sec, _sec)
+#define HEADERED_SECTION(_sec, _front) \
+ HEADERED_SECTION_BY(_sec, _sec, _front)
#ifdef CONFIG_TRACE_BRANCH_PROFILING
#define LIKELY_PROFILE() \
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 02/59] docs/dyndbg: update examples \012 to \n
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
2025-03-20 18:51 ` [PATCH v2 01/59] vmlinux.lds.h: fixup HEADERED_SECTION{,_BY} macros Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 03/59] test-dyndbg: fixup CLASSMAP usage error Jim Cromie
` (56 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
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.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Tested-by: Louis Chauvet<louis.chauvet@bootlin.com>
---
-v2 fix missed \012's
---
.../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 7c036590cd07..4ac18c0a1d95 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.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 03/59] test-dyndbg: fixup CLASSMAP usage error
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
2025-03-20 18:51 ` [PATCH v2 01/59] vmlinux.lds.h: fixup HEADERED_SECTION{,_BY} macros Jim Cromie
2025-03-20 18:51 ` [PATCH v2 02/59] docs/dyndbg: update examples \012 to \n Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 04/59] dyndbg: reword "class unknown, " to "class:_UNKNOWN_" Jim Cromie
` (55 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
commit 6ea3bf466ac6 ("dyndbg: test DECLARE_DYNDBG_CLASSMAP, sysfs nodes")
A closer look at test_dynamic_debug.ko logging output reveals 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.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Tested-by: Louis Chauvet<louis.chauvet@bootlin.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.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 04/59] dyndbg: reword "class unknown, " to "class:_UNKNOWN_"
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (2 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 03/59] test-dyndbg: fixup CLASSMAP usage error Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 05/59] dyndbg: make ddebug_class_param union members same size Jim Cromie
` (54 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
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.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.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 5a007952f7f2..147540c57154 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1154,7 +1154,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.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 05/59] dyndbg: make ddebug_class_param union members same size
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (3 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 04/59] dyndbg: reword "class unknown, " to "class:_UNKNOWN_" Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 06/59] dyndbg: drop NUM_TYPE_ARRAY Jim Cromie
` (53 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
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.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.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 ff44ec346162..b9afc7731b7c 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -124,7 +124,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 147540c57154..55df35df093b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -799,7 +799,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.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 06/59] dyndbg: drop NUM_TYPE_ARRAY
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (4 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 05/59] dyndbg: make ddebug_class_param union members same size Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 07/59] dyndbg: reduce verbose/debug clutter Jim Cromie
` (52 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
ARRAY_SIZE works here, since array decl is complete.
no functional change
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.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 b9afc7731b7c..ac199293d203 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -107,11 +107,9 @@ struct ddebug_class_map {
.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))
/* encapsulate linker provided built-in (or module) dyndbg data */
struct _ddebug_info {
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 07/59] dyndbg: reduce verbose/debug clutter
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (5 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 06/59] dyndbg: drop NUM_TYPE_ARRAY Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 08/59] dyndbg: refactor param_set_dyndbg_classes and below Jim Cromie
` (51 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
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
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
-v2 squash several verbose cleanups together
---
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 55df35df093b..c609ff873224 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -264,9 +264,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;
}
@@ -499,7 +496,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--) {
@@ -513,7 +509,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) {
@@ -529,7 +524,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;
}
@@ -539,7 +534,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);
@@ -557,10 +552,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
@@ -1234,11 +1226,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(sizeof(*dt), GFP_KERNEL);
if (dt == NULL) {
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 08/59] dyndbg: refactor param_set_dyndbg_classes and below
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (6 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 07/59] dyndbg: reduce verbose/debug clutter Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 09/59] dyndbg: tighten fn-sig of ddebug_apply_class_bitmap Jim Cromie
` (50 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
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.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.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 c609ff873224..4b001309bb6a 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -593,9 +593,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];
@@ -603,7 +604,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))
@@ -612,12 +615,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;
}
@@ -672,7 +679,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]);
@@ -682,7 +689,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);
@@ -696,18 +703,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 *modnm)
{
const struct ddebug_class_param *dcp = kp->arg;
const struct ddebug_class_map *map = dcp->map;
@@ -744,8 +742,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, modnm ?: "*", KP_NAME(kp));
+ totct += ddebug_apply_class_bitmap(dcp, &inrep, dcp->bits, modnm);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -758,7 +756,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, modnm);
*dcp->lvl = inrep;
break;
default:
@@ -767,16 +765,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.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 09/59] dyndbg: tighten fn-sig of ddebug_apply_class_bitmap
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (7 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 08/59] dyndbg: refactor param_set_dyndbg_classes and below Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 10/59] dyndbg: replace classmap list with a vector Jim Cromie
` (49 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
old_bits arg is currently a pointer to the input bits, but this could
allow inadvertent changes to the input by the fn. Disallow this.
And constify new_bits while here.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
lib/dynamic_debug.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 4b001309bb6a..dd7320b9616d 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -595,7 +595,8 @@ static int ddebug_exec_queries(char *query, const char *modname)
/* 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,
+ const unsigned long *new_bits,
+ const unsigned long old_bits,
const char *query_modname)
{
#define QUERY_SIZE 128
@@ -604,12 +605,12 @@ static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
int matches = 0;
int bi, ct;
- if (*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 ?: "'*'");
+ old_bits, query_modname ?: "'*'");
for (bi = 0; bi < map->length; bi++) {
- if (test_bit(bi, new_bits) == test_bit(bi, old_bits))
+ if (test_bit(bi, new_bits) == test_bit(bi, &old_bits))
continue;
snprintf(query, QUERY_SIZE, "class %s %c%s", map->class_names[bi],
@@ -621,9 +622,9 @@ static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
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)
+ if (*new_bits != old_bits)
v2pr_info("applied bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits,
- *old_bits, query_modname ?: "'*'");
+ old_bits, query_modname ?: "'*'");
return matches;
}
@@ -679,7 +680,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, NULL);
+ 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]);
@@ -689,7 +690,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, NULL);
+ 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);
@@ -743,7 +744,7 @@ static int param_set_dyndbg_module_classes(const char *instr,
inrep &= CLASSMAP_BITMASK(map->length);
}
v2pr_info("bits:0x%lx > %s.%s\n", inrep, modnm ?: "*", KP_NAME(kp));
- totct += ddebug_apply_class_bitmap(dcp, &inrep, dcp->bits, modnm);
+ totct += ddebug_apply_class_bitmap(dcp, &inrep, *dcp->bits, modnm);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -756,7 +757,7 @@ static int param_set_dyndbg_module_classes(const char *instr,
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, modnm);
+ totct += ddebug_apply_class_bitmap(dcp, &new_bits, old_bits, modnm);
*dcp->lvl = inrep;
break;
default:
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 10/59] dyndbg: replace classmap list with a vector
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (8 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 09/59] dyndbg: tighten fn-sig of ddebug_apply_class_bitmap Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:08 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 11/59] dyndbg: macrofy a 2-index for-loop pattern Jim Cromie
` (48 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Classmaps are stored in an elf section/array, but currently are
individually list-linked onto dyndbg's per-module ddebug_table for
operation. This is unnecessary.
Just like dyndbg's descriptors, classes are packed in compile order;
so even with many builtin modules employing multiple classmaps, each
modules' maps are packed contiguously, and can be treated as a
array-start-address & array-length.
So this drops the whole list building operation done in
ddebug_attach_module_classes(), and removes the list-head members.
The "select-by-modname" condition is reused to find the start,end of
the subrange.
NOTE: This "filter-by-modname" on classmaps should really be done in
ddebug_add_module(1); ie at least one step closer to ddebug_init(2),
which already splits up pr-debug descriptors into subranges by
modname, then calls (1) on each. (2) knows nothing of classmaps
currently, and doesn't need to. For now, just add comment.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
include/linux/dynamic_debug.h | 1 -
lib/dynamic_debug.c | 61 ++++++++++++++++++-----------------
2 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index ac199293d203..e458d4b838ac 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -83,7 +83,6 @@ enum class_map_type {
};
struct ddebug_class_map {
- struct list_head link;
struct module *mod;
const char *mod_name; /* needed for builtins */
const char **class_names;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dd7320b9616d..d5572712ce55 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -45,10 +45,11 @@ extern struct ddebug_class_map __start___dyndbg_classes[];
extern struct ddebug_class_map __stop___dyndbg_classes[];
struct ddebug_table {
- struct list_head link, maps;
+ struct list_head link;
const char *mod_name;
- unsigned int num_ddebugs;
struct _ddebug *ddebugs;
+ struct ddebug_class_map *classes;
+ unsigned int num_ddebugs, num_classes;
};
struct ddebug_query {
@@ -147,13 +148,15 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
query->first_lineno, query->last_lineno, query->class_string);
}
+#define __outvar /* filled by callee */
static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
- const char *class_string, int *class_id)
+ const char *class_string,
+ __outvar int *class_id)
{
struct ddebug_class_map *map;
- int idx;
+ int i, idx;
- list_for_each_entry(map, &dt->maps, link) {
+ for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
idx = match_string(map->class_names, map->length, class_string);
if (idx >= 0) {
*class_id = idx + map->base;
@@ -164,7 +167,6 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
return NULL;
}
-#define __outvar /* filled by callee */
/*
* Search the tables for _ddebug's which match the given `query' and
* apply the `flags' and `mask' to them. Returns number of matching
@@ -1122,9 +1124,10 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug *dp)
{
- struct ddebug_class_map *map;
+ struct ddebug_class_map *map = iter->table->classes;
+ int i, nc = iter->table->num_classes;
- list_for_each_entry(map, &iter->table->maps, link)
+ for (i = 0; i < nc; i++, map++)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
@@ -1208,30 +1211,31 @@ static const struct proc_ops proc_fops = {
.proc_write = ddebug_proc_write
};
-static void ddebug_attach_module_classes(struct ddebug_table *dt,
- struct ddebug_class_map *classes,
- int num_classes)
+static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
{
struct ddebug_class_map *cm;
- int i, j, ct = 0;
+ int i, nc = 0;
- for (cm = classes, i = 0; i < num_classes; i++, cm++) {
+ /*
+ * Find this module's classmaps in a subrange/wholerange of
+ * the builtin/modular classmap vector/section. Save the start
+ * and length of the subrange at its edges.
+ */
+ for (cm = di->classes, i = 0; i < di->num_classes; i++, cm++) {
if (!strcmp(cm->mod_name, dt->mod_name)) {
-
- v2pr_info("class[%d]: module:%s base:%d len:%d ty:%d\n", i,
- cm->mod_name, cm->base, cm->length, cm->map_type);
-
- for (j = 0; j < cm->length; j++)
- v3pr_info(" %d: %d %s\n", j + cm->base, j,
- cm->class_names[j]);
-
- list_add(&cm->link, &dt->maps);
- ct++;
+ if (!nc) {
+ v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
+ i, cm->mod_name, cm->base, cm->length, cm->map_type);
+ dt->classes = cm;
+ }
+ nc++;
}
}
- if (ct)
- vpr_info("module:%s attached %d classes\n", dt->mod_name, ct);
+ if (nc) {
+ dt->num_classes = nc;
+ vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
+ }
}
/*
@@ -1263,10 +1267,9 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
dt->num_ddebugs = di->num_descs;
INIT_LIST_HEAD(&dt->link);
- INIT_LIST_HEAD(&dt->maps);
if (di->classes && di->num_classes)
- ddebug_attach_module_classes(dt, di->classes, di->num_classes);
+ ddebug_attach_module_classes(dt, di);
mutex_lock(&ddebug_lock);
list_add_tail(&dt->link, &ddebug_tables);
@@ -1379,8 +1382,8 @@ static void ddebug_remove_all_tables(void)
mutex_lock(&ddebug_lock);
while (!list_empty(&ddebug_tables)) {
struct ddebug_table *dt = list_entry(ddebug_tables.next,
- struct ddebug_table,
- link);
+ struct ddebug_table,
+ link);
ddebug_table_free(dt);
}
mutex_unlock(&ddebug_lock);
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 10/59] dyndbg: replace classmap list with a vector
2025-03-20 18:51 ` [PATCH v2 10/59] dyndbg: replace classmap list with a vector Jim Cromie
@ 2025-03-24 15:08 ` Louis Chauvet
2025-03-24 22:33 ` jim.cromie
0 siblings, 1 reply; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:08 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> Classmaps are stored in an elf section/array, but currently are
> individually list-linked onto dyndbg's per-module ddebug_table for
> operation. This is unnecessary.
>
> Just like dyndbg's descriptors, classes are packed in compile order;
> so even with many builtin modules employing multiple classmaps, each
> modules' maps are packed contiguously, and can be treated as a
> array-start-address & array-length.
>
> So this drops the whole list building operation done in
> ddebug_attach_module_classes(), and removes the list-head members.
> The "select-by-modname" condition is reused to find the start,end of
> the subrange.
>
> NOTE: This "filter-by-modname" on classmaps should really be done in
> ddebug_add_module(1); ie at least one step closer to ddebug_init(2),
> which already splits up pr-debug descriptors into subranges by
> modname, then calls (1) on each. (2) knows nothing of classmaps
> currently, and doesn't need to. For now, just add comment.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> include/linux/dynamic_debug.h | 1 -
> lib/dynamic_debug.c | 61 ++++++++++++++++++-----------------
> 2 files changed, 32 insertions(+), 30 deletions(-)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index ac199293d203..e458d4b838ac 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -83,7 +83,6 @@ enum class_map_type {
> };
>
> struct ddebug_class_map {
> - struct list_head link;
> struct module *mod;
> const char *mod_name; /* needed for builtins */
> const char **class_names;
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index dd7320b9616d..d5572712ce55 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -45,10 +45,11 @@ extern struct ddebug_class_map __start___dyndbg_classes[];
> extern struct ddebug_class_map __stop___dyndbg_classes[];
>
> struct ddebug_table {
> - struct list_head link, maps;
> + struct list_head link;
> const char *mod_name;
> - unsigned int num_ddebugs;
> struct _ddebug *ddebugs;
> + struct ddebug_class_map *classes;
> + unsigned int num_ddebugs, num_classes;
> };
>
> struct ddebug_query {
> @@ -147,13 +148,15 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> query->first_lineno, query->last_lineno, query->class_string);
> }
>
> +#define __outvar /* filled by callee */
> static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
> - const char *class_string, int *class_id)
> + const char *class_string,
> + __outvar int *class_id)
Thanks for your explanation of __outvar! It makes sense. I never seen
this pattern anywhere in the kernel, maybe a simple doc comment is
enough to carry the information:
/**
* ddebug_find_valid_class - Find a valid class for a
* given string
* @dt: debug table to inspect
* @class_string: string to match on
* @class_id: output pointer for the class_id value
*
* Returns: Pointer to the ddebug_class_map instance, if found.
* @class_id will be set to the id of this class. If no class
* matching @class_string is found, returns NULL and class_id is
* set to -ENOENT.
*/
Or at maybe change the documentation of __outvar to be a bit more
explicit about how it works (I had difficulties to understand because a
lot of "magic macro" exist in the kernel and sometimes carry information
to the compiler, but this one is always empty):
/**
* __outvar - Denotes that an argument is used as an output
* value
* This macro does nothing apart clarify for the reader that
* the parameter will be filled by the callee
*/
With any of the modifications (feel free to reword them as you want):
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> {
> struct ddebug_class_map *map;
> - int idx;
> + int i, idx;
>
> - list_for_each_entry(map, &dt->maps, link) {
> + for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
> idx = match_string(map->class_names, map->length, class_string);
> if (idx >= 0) {
> *class_id = idx + map->base;
> @@ -164,7 +167,6 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
> return NULL;
> }
>
> -#define __outvar /* filled by callee */
> /*
> * Search the tables for _ddebug's which match the given `query' and
> * apply the `flags' and `mask' to them. Returns number of matching
> @@ -1122,9 +1124,10 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
>
> static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug *dp)
> {
> - struct ddebug_class_map *map;
> + struct ddebug_class_map *map = iter->table->classes;
> + int i, nc = iter->table->num_classes;
>
> - list_for_each_entry(map, &iter->table->maps, link)
> + for (i = 0; i < nc; i++, map++)
> if (class_in_range(dp->class_id, map))
> return map->class_names[dp->class_id - map->base];
>
> @@ -1208,30 +1211,31 @@ static const struct proc_ops proc_fops = {
> .proc_write = ddebug_proc_write
> };
>
> -static void ddebug_attach_module_classes(struct ddebug_table *dt,
> - struct ddebug_class_map *classes,
> - int num_classes)
> +static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
> {
> struct ddebug_class_map *cm;
> - int i, j, ct = 0;
> + int i, nc = 0;
>
> - for (cm = classes, i = 0; i < num_classes; i++, cm++) {
> + /*
> + * Find this module's classmaps in a subrange/wholerange of
> + * the builtin/modular classmap vector/section. Save the start
> + * and length of the subrange at its edges.
> + */
> + for (cm = di->classes, i = 0; i < di->num_classes; i++, cm++) {
>
> if (!strcmp(cm->mod_name, dt->mod_name)) {
> -
> - v2pr_info("class[%d]: module:%s base:%d len:%d ty:%d\n", i,
> - cm->mod_name, cm->base, cm->length, cm->map_type);
> -
> - for (j = 0; j < cm->length; j++)
> - v3pr_info(" %d: %d %s\n", j + cm->base, j,
> - cm->class_names[j]);
> -
> - list_add(&cm->link, &dt->maps);
> - ct++;
> + if (!nc) {
> + v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
> + i, cm->mod_name, cm->base, cm->length, cm->map_type);
> + dt->classes = cm;
> + }
> + nc++;
> }
> }
> - if (ct)
> - vpr_info("module:%s attached %d classes\n", dt->mod_name, ct);
> + if (nc) {
> + dt->num_classes = nc;
> + vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
> + }
> }
>
> /*
> @@ -1263,10 +1267,9 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> dt->num_ddebugs = di->num_descs;
>
> INIT_LIST_HEAD(&dt->link);
> - INIT_LIST_HEAD(&dt->maps);
>
> if (di->classes && di->num_classes)
> - ddebug_attach_module_classes(dt, di->classes, di->num_classes);
> + ddebug_attach_module_classes(dt, di);
>
> mutex_lock(&ddebug_lock);
> list_add_tail(&dt->link, &ddebug_tables);
> @@ -1379,8 +1382,8 @@ static void ddebug_remove_all_tables(void)
> mutex_lock(&ddebug_lock);
> while (!list_empty(&ddebug_tables)) {
> struct ddebug_table *dt = list_entry(ddebug_tables.next,
> - struct ddebug_table,
> - link);
> + struct ddebug_table,
> + link);
> ddebug_table_free(dt);
> }
> mutex_unlock(&ddebug_lock);
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 10/59] dyndbg: replace classmap list with a vector
2025-03-24 15:08 ` Louis Chauvet
@ 2025-03-24 22:33 ` jim.cromie
0 siblings, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-24 22:33 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
On Mon, Mar 24, 2025 at 9:08 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>
>
>
> Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> Thanks for your explanation of __outvar! It makes sense. I never seen
> this pattern anywhere in the kernel, maybe a simple doc comment is
> enough to carry the information:
Im gonna pull it - Ive decided its misleading,
since it looks like it does something that it cant do.
a plain old comment would be enough, if its needed at all.
__outvar was at least brief ;-)
In fact I did, but in a later patch. cleaning now.
> /**
> * ddebug_find_valid_class - Find a valid class for a
> * given string
> * @dt: debug table to inspect
> * @class_string: string to match on
> * @class_id: output pointer for the class_id value
> *
> * Returns: Pointer to the ddebug_class_map instance, if found.
> * @class_id will be set to the id of this class. If no class
> * matching @class_string is found, returns NULL and class_id is
> * set to -ENOENT.
> */
>
> Or at maybe change the documentation of __outvar to be a bit more
> explicit about how it works (I had difficulties to understand because a
> lot of "magic macro" exist in the kernel and sometimes carry information
> to the compiler, but this one is always empty):
>
> /**
> * __outvar - Denotes that an argument is used as an output
> * value
> * This macro does nothing apart clarify for the reader that
> * the parameter will be filled by the callee
> */
>
> With any of the modifications (feel free to reword them as you want):
>
> Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
>
> > {
> > struct ddebug_class_map *map;
> > - int idx;
> > + int i, idx;
> >
> > - list_for_each_entry(map, &dt->maps, link) {
> > + for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
> > idx = match_string(map->class_names, map->length, class_string);
> > if (idx >= 0) {
> > *class_id = idx + map->base;
> > @@ -164,7 +167,6 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
> > return NULL;
> > }
> >
> > -#define __outvar /* filled by callee */
> > /*
> > * Search the tables for _ddebug's which match the given `query' and
> > * apply the `flags' and `mask' to them. Returns number of matching
> > @@ -1122,9 +1124,10 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
> >
> > static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug *dp)
> > {
> > - struct ddebug_class_map *map;
> > + struct ddebug_class_map *map = iter->table->classes;
> > + int i, nc = iter->table->num_classes;
> >
> > - list_for_each_entry(map, &iter->table->maps, link)
> > + for (i = 0; i < nc; i++, map++)
> > if (class_in_range(dp->class_id, map))
> > return map->class_names[dp->class_id - map->base];
> >
> > @@ -1208,30 +1211,31 @@ static const struct proc_ops proc_fops = {
> > .proc_write = ddebug_proc_write
> > };
> >
> > -static void ddebug_attach_module_classes(struct ddebug_table *dt,
> > - struct ddebug_class_map *classes,
> > - int num_classes)
> > +static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
> > {
> > struct ddebug_class_map *cm;
> > - int i, j, ct = 0;
> > + int i, nc = 0;
> >
> > - for (cm = classes, i = 0; i < num_classes; i++, cm++) {
> > + /*
> > + * Find this module's classmaps in a subrange/wholerange of
> > + * the builtin/modular classmap vector/section. Save the start
> > + * and length of the subrange at its edges.
> > + */
> > + for (cm = di->classes, i = 0; i < di->num_classes; i++, cm++) {
> >
> > if (!strcmp(cm->mod_name, dt->mod_name)) {
> > -
> > - v2pr_info("class[%d]: module:%s base:%d len:%d ty:%d\n", i,
> > - cm->mod_name, cm->base, cm->length, cm->map_type);
> > -
> > - for (j = 0; j < cm->length; j++)
> > - v3pr_info(" %d: %d %s\n", j + cm->base, j,
> > - cm->class_names[j]);
> > -
> > - list_add(&cm->link, &dt->maps);
> > - ct++;
> > + if (!nc) {
> > + v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
> > + i, cm->mod_name, cm->base, cm->length, cm->map_type);
> > + dt->classes = cm;
> > + }
> > + nc++;
> > }
> > }
> > - if (ct)
> > - vpr_info("module:%s attached %d classes\n", dt->mod_name, ct);
> > + if (nc) {
> > + dt->num_classes = nc;
> > + vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
> > + }
> > }
> >
> > /*
> > @@ -1263,10 +1267,9 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> > dt->num_ddebugs = di->num_descs;
> >
> > INIT_LIST_HEAD(&dt->link);
> > - INIT_LIST_HEAD(&dt->maps);
> >
> > if (di->classes && di->num_classes)
> > - ddebug_attach_module_classes(dt, di->classes, di->num_classes);
> > + ddebug_attach_module_classes(dt, di);
> >
> > mutex_lock(&ddebug_lock);
> > list_add_tail(&dt->link, &ddebug_tables);
> > @@ -1379,8 +1382,8 @@ static void ddebug_remove_all_tables(void)
> > mutex_lock(&ddebug_lock);
> > while (!list_empty(&ddebug_tables)) {
> > struct ddebug_table *dt = list_entry(ddebug_tables.next,
> > - struct ddebug_table,
> > - link);
> > + struct ddebug_table,
> > + link);
> > ddebug_table_free(dt);
> > }
> > mutex_unlock(&ddebug_lock);
>
> --
> Louis Chauvet, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 11/59] dyndbg: macrofy a 2-index for-loop pattern
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (9 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 10/59] dyndbg: replace classmap list with a vector Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:10 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 12/59] dyndbg, module: make proper substructs in _ddebug_info Jim Cromie
` (47 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
dynamic-debug has several __sections, each with <vecname>,
num_<vecname>, and it iterates over these with a 2-index for-loop.
These loops are fiddly with the 2 names.
We have only 2 such loops now, but are getting more soon; lets
embed/abstract the fiddlyness in the for_subvec() macro, and avoid
repeating it going forward.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
lib/dynamic_debug.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index d5572712ce55..94f6c8fd787b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -128,6 +128,21 @@ do { \
#define v3pr_info(fmt, ...) vnpr_info(3, fmt, ##__VA_ARGS__)
#define v4pr_info(fmt, ...) vnpr_info(4, fmt, ##__VA_ARGS__)
+
+/*
+ * simplify a repeated for-loop pattern walking N steps in a T _vec
+ * member inside a struct _box. It expects int i and T *_sp to be
+ * declared in the caller.
+ * @_i: caller provided counter.
+ * @_sp: cursor into _vec, to examine each item.
+ * @_box: ptr to a struct containing @_vec member
+ * @_vec: name of a sub-struct member in _box, with array-ref and length
+ */
+#define for_subvec(_i, _sp, _box, _vec) \
+ for ((_i) = 0, (_sp) = (_box)->_vec; \
+ (_i) < (_box)->num_##_vec; \
+ (_i)++, (_sp)++)
+
static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
{
/* trim any trailing newlines */
@@ -156,7 +171,7 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
struct ddebug_class_map *map;
int i, idx;
- for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
+ for_subvec(i, map, dt, classes) {
idx = match_string(map->class_names, map->length, class_string);
if (idx >= 0) {
*class_id = idx + map->base;
@@ -1221,8 +1236,7 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
* the builtin/modular classmap vector/section. Save the start
* and length of the subrange at its edges.
*/
- for (cm = di->classes, i = 0; i < di->num_classes; i++, cm++) {
-
+ for_subvec(i, cm, di, classes) {
if (!strcmp(cm->mod_name, dt->mod_name)) {
if (!nc) {
v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 11/59] dyndbg: macrofy a 2-index for-loop pattern
2025-03-20 18:51 ` [PATCH v2 11/59] dyndbg: macrofy a 2-index for-loop pattern Jim Cromie
@ 2025-03-24 15:10 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:10 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> dynamic-debug has several __sections, each with <vecname>,
> num_<vecname>, and it iterates over these with a 2-index for-loop.
> These loops are fiddly with the 2 names.
>
> We have only 2 such loops now, but are getting more soon; lets
> embed/abstract the fiddlyness in the for_subvec() macro, and avoid
> repeating it going forward.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> lib/dynamic_debug.c | 20 +++++++++++++++++---
> 1 file changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index d5572712ce55..94f6c8fd787b 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -128,6 +128,21 @@ do { \
> #define v3pr_info(fmt, ...) vnpr_info(3, fmt, ##__VA_ARGS__)
> #define v4pr_info(fmt, ...) vnpr_info(4, fmt, ##__VA_ARGS__)
>
> +
> +/*
> + * simplify a repeated for-loop pattern walking N steps in a T _vec
> + * member inside a struct _box. It expects int i and T *_sp to be
> + * declared in the caller.
> + * @_i: caller provided counter.
> + * @_sp: cursor into _vec, to examine each item.
> + * @_box: ptr to a struct containing @_vec member
> + * @_vec: name of a sub-struct member in _box, with array-ref and length
> + */
Nice macro to make the code easier to read!
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> +#define for_subvec(_i, _sp, _box, _vec) \
> + for ((_i) = 0, (_sp) = (_box)->_vec; \
> + (_i) < (_box)->num_##_vec; \
> + (_i)++, (_sp)++)
> +
> static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> {
> /* trim any trailing newlines */
> @@ -156,7 +171,7 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
> struct ddebug_class_map *map;
> int i, idx;
>
> - for (map = dt->classes, i = 0; i < dt->num_classes; i++, map++) {
> + for_subvec(i, map, dt, classes) {
> idx = match_string(map->class_names, map->length, class_string);
> if (idx >= 0) {
> *class_id = idx + map->base;
> @@ -1221,8 +1236,7 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
> * the builtin/modular classmap vector/section. Save the start
> * and length of the subrange at its edges.
> */
> - for (cm = di->classes, i = 0; i < di->num_classes; i++, cm++) {
> -
> + for_subvec(i, cm, di, classes) {
> if (!strcmp(cm->mod_name, dt->mod_name)) {
> if (!nc) {
> v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 12/59] dyndbg, module: make proper substructs in _ddebug_info
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (10 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 11/59] dyndbg: macrofy a 2-index for-loop pattern Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:10 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 13/59] dyndbg: add 2 new _DPRINTK_FLAGS_: INCL_LOOKUP, PREFIX_CACHED Jim Cromie
` (46 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
recompose struct _ddebug_info, inserting proper sub-structs.
The struct currently has 2 pairs of fields: descs, num_descs and
classes, num_classes. Several for-loops operate on these field pairs,
soon many more will be added.
Looping over these blocks by respective field-pairs is repetitive and
fiddly, differing only by the field-names. Before adding a 3rd
section and compounding the fiddly details problem, make proper
substructs of each section, with the same named fields.
So this patch does:
Adds 3 "vector<T>" structs, each with { <T> *start, int len; }
components, for _ddebug_descriptors, _ddebug_class_maps, and
_ddebug_class_users respectively.
Invariant: These vectors ref a contiguous subrange of __section memory
in builtin/DATA or in loadable modules via mod->dyndbg_info; with
guaranteed life-time for us.
Bundles these 3 vectors (subrange-refs) struct (reformed) _ddebug_info,
where they're __packed to close the paholes introduced otherwise.
The common fields allow improving the for_subvec() macro by dropping
the ugly num_##<T> paste-up.
Also recompose struct ddebug_table to contain a _ddebug_info. This
reinforces its use as a cursor into relevant data for a builtin
module, and access to the full _ddebug state for modules.
NOTES:
Fixup names: section names improved, struct names normalized to
_ddebug_*
struct module contains a _ddebug_info field and module/main.c sets it
up, so that gets adjusted.
The __packed attribute on _ddebug_info and the 3 contained structs
closes the holes otherwise created by the structification (which was
my excuse for not doing it originally).
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
-v2 rework towards front of series
---
include/asm-generic/vmlinux.lds.h | 4 +-
include/linux/dynamic_debug.h | 28 +++++++---
kernel/module/main.c | 12 ++--
lib/dynamic_debug.c | 91 ++++++++++++++++---------------
4 files changed, 74 insertions(+), 61 deletions(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index c9c66089ea2f..f834ad1fb8c4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -366,8 +366,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
*(__tracepoints) \
/* implement dynamic printk debug */ \
. = ALIGN(8); \
- BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes) \
- BOUNDED_SECTION_BY(__dyndbg, ___dyndbg) \
+ BOUNDED_SECTION_BY(__dyndbg_class_maps, ___dyndbg_class_maps) \
+ BOUNDED_SECTION_BY(__dyndbg_descriptors, ___dyndbg_descs) \
CODETAG_SECTIONS() \
LIKELY_PROFILE() \
BRANCH_PROFILE() \
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e458d4b838ac..c388ab05a6e1 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -110,13 +110,23 @@ struct ddebug_class_map {
.class_names = _var##_classnames, \
}
-/* encapsulate linker provided built-in (or module) dyndbg data */
+/*
+ * @_ddebug_info: gathers module/builtin dyndbg_* __sections together.
+ * For builtins, it is used as a cursor, with the inner structs
+ * marking sub-vectors of the builtin __sections in DATA.
+ */
+struct _ddebug_descs {
+ struct _ddebug *start;
+ int len;
+} __packed;
+struct _ddebug_class_maps {
+ struct ddebug_class_map *start;
+ int len;
+} __packed;
struct _ddebug_info {
- struct _ddebug *descs;
- struct ddebug_class_map *classes;
- unsigned int num_descs;
- unsigned int num_classes;
-};
+ struct _ddebug_descs descs;
+ struct _ddebug_class_maps maps;
+} __packed;
struct ddebug_class_param {
union {
@@ -159,7 +169,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
#define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt) \
static struct _ddebug __aligned(8) \
- __section("__dyndbg") name = { \
+ __section("__dyndbg_descriptors") name = { \
.modname = KBUILD_MODNAME, \
.function = __func__, \
.filename = __FILE__, \
@@ -242,7 +252,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
* macro.
*/
#define _dynamic_func_call_cls(cls, fmt, func, ...) \
- __dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, ##__VA_ARGS__)
+ __dynamic_func_call_cls(__UNIQUE_ID(_ddebug), cls, fmt, func, ##__VA_ARGS__)
#define _dynamic_func_call(fmt, func, ...) \
_dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
@@ -252,7 +262,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
* with precisely the macro's varargs.
*/
#define _dynamic_func_call_cls_no_desc(cls, fmt, func, ...) \
- __dynamic_func_call_cls_no_desc(__UNIQUE_ID(ddebug), cls, fmt, \
+ __dynamic_func_call_cls_no_desc(__UNIQUE_ID(_ddebug), cls, fmt, \
func, ##__VA_ARGS__)
#define _dynamic_func_call_no_desc(fmt, func, ...) \
_dynamic_func_call_cls_no_desc(_DPRINTK_CLASS_DFLT, fmt, \
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 1fb9ad289a6f..b60f728e36ac 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2621,12 +2621,12 @@ static int find_module_sections(struct module *mod, struct load_info *info)
pr_warn("%s: Ignoring obsolete parameters\n", mod->name);
#ifdef CONFIG_DYNAMIC_DEBUG_CORE
- mod->dyndbg_info.descs = section_objs(info, "__dyndbg",
- sizeof(*mod->dyndbg_info.descs),
- &mod->dyndbg_info.num_descs);
- mod->dyndbg_info.classes = section_objs(info, "__dyndbg_classes",
- sizeof(*mod->dyndbg_info.classes),
- &mod->dyndbg_info.num_classes);
+ mod->dyndbg_info.descs.start = section_objs(info, "__dyndbg_descriptors",
+ sizeof(*mod->dyndbg_info.descs.start),
+ &mod->dyndbg_info.descs.len);
+ mod->dyndbg_info.maps.start = section_objs(info, "__dyndbg_class_maps",
+ sizeof(*mod->dyndbg_info.maps.start),
+ &mod->dyndbg_info.maps.len);
#endif
return 0;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 94f6c8fd787b..663c125006d0 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -39,17 +39,15 @@
#include <rdma/ib_verbs.h>
-extern struct _ddebug __start___dyndbg[];
-extern struct _ddebug __stop___dyndbg[];
-extern struct ddebug_class_map __start___dyndbg_classes[];
-extern struct ddebug_class_map __stop___dyndbg_classes[];
+extern struct _ddebug __start___dyndbg_descs[];
+extern struct _ddebug __stop___dyndbg_descs[];
+extern struct ddebug_class_map __start___dyndbg_class_maps[];
+extern struct ddebug_class_map __stop___dyndbg_class_maps[];
struct ddebug_table {
struct list_head link;
const char *mod_name;
- struct _ddebug *ddebugs;
- struct ddebug_class_map *classes;
- unsigned int num_ddebugs, num_classes;
+ struct _ddebug_info info;
};
struct ddebug_query {
@@ -128,7 +126,6 @@ do { \
#define v3pr_info(fmt, ...) vnpr_info(3, fmt, ##__VA_ARGS__)
#define v4pr_info(fmt, ...) vnpr_info(4, fmt, ##__VA_ARGS__)
-
/*
* simplify a repeated for-loop pattern walking N steps in a T _vec
* member inside a struct _box. It expects int i and T *_sp to be
@@ -139,8 +136,8 @@ do { \
* @_vec: name of a sub-struct member in _box, with array-ref and length
*/
#define for_subvec(_i, _sp, _box, _vec) \
- for ((_i) = 0, (_sp) = (_box)->_vec; \
- (_i) < (_box)->num_##_vec; \
+ for ((_i) = 0, (_sp) = (_box)->_vec.start; \
+ (_i) < (_box)->_vec.len; \
(_i)++, (_sp)++)
static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
@@ -163,6 +160,13 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
query->first_lineno, query->last_lineno, query->class_string);
}
+#define vpr_dt_info(dt_p, msg_p, ...) ({ \
+ struct ddebug_table const *_dt = dt_p; \
+ v2pr_info(msg_p " module:%s nd:%d nc:%d nu:%d\n", ##__VA_ARGS__, \
+ _dt->mod_name, _dt->info.descs.len, _dt->info.maps.len, \
+ _dt->info.users.len); \
+ })
+
#define __outvar /* filled by callee */
static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
const char *class_string,
@@ -171,7 +175,7 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
struct ddebug_class_map *map;
int i, idx;
- for_subvec(i, map, dt, classes) {
+ for_subvec(i, map, &dt->info, maps) {
idx = match_string(map->class_names, map->length, class_string);
if (idx >= 0) {
*class_id = idx + map->base;
@@ -217,8 +221,8 @@ static int ddebug_change(const struct ddebug_query *query,
valid_class = _DPRINTK_CLASS_DFLT;
}
- for (i = 0; i < dt->num_ddebugs; i++) {
- struct _ddebug *dp = &dt->ddebugs[i];
+ for (i = 0; i < dt->info.descs.len; i++) {
+ struct _ddebug *dp = &dt->info.descs.start[i];
/* match site against query-class */
if (dp->class_id != valid_class)
@@ -1065,8 +1069,8 @@ static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
}
iter->table = list_entry(ddebug_tables.next,
struct ddebug_table, link);
- iter->idx = iter->table->num_ddebugs;
- return &iter->table->ddebugs[--iter->idx];
+ iter->idx = iter->table->info.descs.len;
+ return &iter->table->info.descs.start[--iter->idx];
}
/*
@@ -1087,10 +1091,10 @@ static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
}
iter->table = list_entry(iter->table->link.next,
struct ddebug_table, link);
- iter->idx = iter->table->num_ddebugs;
+ iter->idx = iter->table->info.descs.len;
--iter->idx;
}
- return &iter->table->ddebugs[iter->idx];
+ return &iter->table->info.descs.start[iter->idx];
}
/*
@@ -1137,12 +1141,12 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
#define class_in_range(class_id, map) \
(class_id >= map->base && class_id < map->base + map->length)
-static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug *dp)
+static const char *ddebug_class_name(struct ddebug_table *dt, struct _ddebug *dp)
{
- struct ddebug_class_map *map = iter->table->classes;
- int i, nc = iter->table->num_classes;
+ struct ddebug_class_map *map;
+ int i;
- for (i = 0; i < nc; i++, map++)
+ for_subvec(i, map, &dt->info, maps)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
@@ -1176,7 +1180,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
seq_putc(m, '"');
if (dp->class_id != _DPRINTK_CLASS_DFLT) {
- class = ddebug_class_name(iter, dp);
+ class = ddebug_class_name(iter->table, dp);
if (class)
seq_printf(m, " class:%s", class);
else
@@ -1236,18 +1240,18 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
* the builtin/modular classmap vector/section. Save the start
* and length of the subrange at its edges.
*/
- for_subvec(i, cm, di, classes) {
+ for_subvec(i, cm, di, maps) {
if (!strcmp(cm->mod_name, dt->mod_name)) {
if (!nc) {
v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
i, cm->mod_name, cm->base, cm->length, cm->map_type);
- dt->classes = cm;
+ dt->info.maps.start = cm;
}
nc++;
}
}
if (nc) {
- dt->num_classes = nc;
+ dt->info.maps.len = nc;
vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
}
}
@@ -1260,10 +1264,10 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
{
struct ddebug_table *dt;
- if (!di->num_descs)
+ if (!di->descs.len)
return 0;
- v3pr_info("add-module: %s %d sites\n", modname, di->num_descs);
+ v3pr_info("add-module: %s %d sites\n", modname, di->descs.len);
dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL) {
@@ -1277,19 +1281,18 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
* this struct ddebug_table.
*/
dt->mod_name = modname;
- dt->ddebugs = di->descs;
- dt->num_ddebugs = di->num_descs;
+ dt->info = *di;
INIT_LIST_HEAD(&dt->link);
- if (di->classes && di->num_classes)
+ if (di->maps.len)
ddebug_attach_module_classes(dt, di);
mutex_lock(&ddebug_lock);
list_add_tail(&dt->link, &ddebug_tables);
mutex_unlock(&ddebug_lock);
- vpr_info("%3u debug prints in module %s\n", di->num_descs, modname);
+ vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
return 0;
}
@@ -1436,10 +1439,10 @@ static int __init dynamic_debug_init(void)
char *cmdline;
struct _ddebug_info di = {
- .descs = __start___dyndbg,
- .classes = __start___dyndbg_classes,
- .num_descs = __stop___dyndbg - __start___dyndbg,
- .num_classes = __stop___dyndbg_classes - __start___dyndbg_classes,
+ .descs.start = __start___dyndbg_descs,
+ .maps.start = __start___dyndbg_class_maps,
+ .descs.len = __stop___dyndbg_descs - __start___dyndbg_descs,
+ .maps.len = __stop___dyndbg_class_maps - __start___dyndbg_class_maps,
};
#ifdef CONFIG_MODULES
@@ -1450,7 +1453,7 @@ static int __init dynamic_debug_init(void)
}
#endif /* CONFIG_MODULES */
- if (&__start___dyndbg == &__stop___dyndbg) {
+ if (&__start___dyndbg_descs == &__stop___dyndbg_descs) {
if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
return 1;
@@ -1460,16 +1463,16 @@ static int __init dynamic_debug_init(void)
return 0;
}
- iter = iter_mod_start = __start___dyndbg;
+ iter = iter_mod_start = __start___dyndbg_descs;
modname = iter->modname;
i = mod_sites = mod_ct = 0;
- for (; iter < __stop___dyndbg; iter++, i++, mod_sites++) {
+ for (; iter < __stop___dyndbg_descs; iter++, i++, mod_sites++) {
if (strcmp(modname, iter->modname)) {
mod_ct++;
- di.num_descs = mod_sites;
- di.descs = iter_mod_start;
+ di.descs.len = mod_sites;
+ di.descs.start = iter_mod_start;
ret = ddebug_add_module(&di, modname);
if (ret)
goto out_err;
@@ -1479,8 +1482,8 @@ static int __init dynamic_debug_init(void)
iter_mod_start = iter;
}
}
- di.num_descs = mod_sites;
- di.descs = iter_mod_start;
+ di.descs.len = mod_sites;
+ di.descs.start = iter_mod_start;
ret = ddebug_add_module(&di, modname);
if (ret)
goto out_err;
@@ -1490,8 +1493,8 @@ static int __init dynamic_debug_init(void)
i, mod_ct, (int)((mod_ct * sizeof(struct ddebug_table)) >> 10),
(int)((i * sizeof(struct _ddebug)) >> 10));
- if (di.num_classes)
- v2pr_info(" %d builtin ddebug class-maps\n", di.num_classes);
+ if (di.maps.len)
+ v2pr_info(" %d builtin ddebug class-maps\n", di.maps.len);
/* now that ddebug tables are loaded, process all boot args
* again to find and activate queries given in dyndbg params.
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 12/59] dyndbg, module: make proper substructs in _ddebug_info
2025-03-20 18:51 ` [PATCH v2 12/59] dyndbg, module: make proper substructs in _ddebug_info Jim Cromie
@ 2025-03-24 15:10 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:10 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> recompose struct _ddebug_info, inserting proper sub-structs.
>
> The struct currently has 2 pairs of fields: descs, num_descs and
> classes, num_classes. Several for-loops operate on these field pairs,
> soon many more will be added.
>
> Looping over these blocks by respective field-pairs is repetitive and
> fiddly, differing only by the field-names. Before adding a 3rd
> section and compounding the fiddly details problem, make proper
> substructs of each section, with the same named fields.
>
> So this patch does:
>
> Adds 3 "vector<T>" structs, each with { <T> *start, int len; }
> components, for _ddebug_descriptors, _ddebug_class_maps, and
> _ddebug_class_users respectively.
>
> Invariant: These vectors ref a contiguous subrange of __section memory
> in builtin/DATA or in loadable modules via mod->dyndbg_info; with
> guaranteed life-time for us.
>
> Bundles these 3 vectors (subrange-refs) struct (reformed) _ddebug_info,
> where they're __packed to close the paholes introduced otherwise.
>
> The common fields allow improving the for_subvec() macro by dropping
> the ugly num_##<T> paste-up.
>
> Also recompose struct ddebug_table to contain a _ddebug_info. This
> reinforces its use as a cursor into relevant data for a builtin
> module, and access to the full _ddebug state for modules.
>
> NOTES:
>
> Fixup names: section names improved, struct names normalized to
> _ddebug_*
Maybe this should be in a separate patch?
> struct module contains a _ddebug_info field and module/main.c sets it
> up, so that gets adjusted.
>
> The __packed attribute on _ddebug_info and the 3 contained structs
> closes the holes otherwise created by the structification (which was
> my excuse for not doing it originally).
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> -v2 rework towards front of series
> ---
> include/asm-generic/vmlinux.lds.h | 4 +-
> include/linux/dynamic_debug.h | 28 +++++++---
> kernel/module/main.c | 12 ++--
> lib/dynamic_debug.c | 91 ++++++++++++++++---------------
> 4 files changed, 74 insertions(+), 61 deletions(-)
>
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index c9c66089ea2f..f834ad1fb8c4 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -366,8 +366,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
> *(__tracepoints) \
> /* implement dynamic printk debug */ \
> . = ALIGN(8); \
> - BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes) \
> - BOUNDED_SECTION_BY(__dyndbg, ___dyndbg) \
> + BOUNDED_SECTION_BY(__dyndbg_class_maps, ___dyndbg_class_maps) \
> + BOUNDED_SECTION_BY(__dyndbg_descriptors, ___dyndbg_descs) \
> CODETAG_SECTIONS() \
> LIKELY_PROFILE() \
> BRANCH_PROFILE() \
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index e458d4b838ac..c388ab05a6e1 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -110,13 +110,23 @@ struct ddebug_class_map {
> .class_names = _var##_classnames, \
> }
>
> -/* encapsulate linker provided built-in (or module) dyndbg data */
> +/*
> + * @_ddebug_info: gathers module/builtin dyndbg_* __sections together.
> + * For builtins, it is used as a cursor, with the inner structs
> + * marking sub-vectors of the builtin __sections in DATA.
> + */
> +struct _ddebug_descs {
> + struct _ddebug *start;
> + int len;
> +} __packed;
> +struct _ddebug_class_maps {
> + struct ddebug_class_map *start;
> + int len;
> +} __packed;
> struct _ddebug_info {
> - struct _ddebug *descs;
> - struct ddebug_class_map *classes;
> - unsigned int num_descs;
> - unsigned int num_classes;
> -};
> + struct _ddebug_descs descs;
> + struct _ddebug_class_maps maps;
> +} __packed;
>
> struct ddebug_class_param {
> union {
> @@ -159,7 +169,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
>
> #define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt) \
> static struct _ddebug __aligned(8) \
> - __section("__dyndbg") name = { \
> + __section("__dyndbg_descriptors") name = { \
> .modname = KBUILD_MODNAME, \
> .function = __func__, \
> .filename = __FILE__, \
> @@ -242,7 +252,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
> * macro.
> */
> #define _dynamic_func_call_cls(cls, fmt, func, ...) \
> - __dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, ##__VA_ARGS__)
> + __dynamic_func_call_cls(__UNIQUE_ID(_ddebug), cls, fmt, func, ##__VA_ARGS__)
> #define _dynamic_func_call(fmt, func, ...) \
> _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
>
> @@ -252,7 +262,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
> * with precisely the macro's varargs.
> */
> #define _dynamic_func_call_cls_no_desc(cls, fmt, func, ...) \
> - __dynamic_func_call_cls_no_desc(__UNIQUE_ID(ddebug), cls, fmt, \
> + __dynamic_func_call_cls_no_desc(__UNIQUE_ID(_ddebug), cls, fmt, \
> func, ##__VA_ARGS__)
> #define _dynamic_func_call_no_desc(fmt, func, ...) \
> _dynamic_func_call_cls_no_desc(_DPRINTK_CLASS_DFLT, fmt, \
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index 1fb9ad289a6f..b60f728e36ac 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -2621,12 +2621,12 @@ static int find_module_sections(struct module *mod, struct load_info *info)
> pr_warn("%s: Ignoring obsolete parameters\n", mod->name);
>
> #ifdef CONFIG_DYNAMIC_DEBUG_CORE
> - mod->dyndbg_info.descs = section_objs(info, "__dyndbg",
> - sizeof(*mod->dyndbg_info.descs),
> - &mod->dyndbg_info.num_descs);
> - mod->dyndbg_info.classes = section_objs(info, "__dyndbg_classes",
> - sizeof(*mod->dyndbg_info.classes),
> - &mod->dyndbg_info.num_classes);
> + mod->dyndbg_info.descs.start = section_objs(info, "__dyndbg_descriptors",
> + sizeof(*mod->dyndbg_info.descs.start),
> + &mod->dyndbg_info.descs.len);
> + mod->dyndbg_info.maps.start = section_objs(info, "__dyndbg_class_maps",
> + sizeof(*mod->dyndbg_info.maps.start),
> + &mod->dyndbg_info.maps.len);
> #endif
>
> return 0;
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index 94f6c8fd787b..663c125006d0 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -39,17 +39,15 @@
>
> #include <rdma/ib_verbs.h>
>
> -extern struct _ddebug __start___dyndbg[];
> -extern struct _ddebug __stop___dyndbg[];
> -extern struct ddebug_class_map __start___dyndbg_classes[];
> -extern struct ddebug_class_map __stop___dyndbg_classes[];
> +extern struct _ddebug __start___dyndbg_descs[];
> +extern struct _ddebug __stop___dyndbg_descs[];
> +extern struct ddebug_class_map __start___dyndbg_class_maps[];
> +extern struct ddebug_class_map __stop___dyndbg_class_maps[];
>
> struct ddebug_table {
> struct list_head link;
> const char *mod_name;
> - struct _ddebug *ddebugs;
> - struct ddebug_class_map *classes;
> - unsigned int num_ddebugs, num_classes;
> + struct _ddebug_info info;
> };
>
> struct ddebug_query {
> @@ -128,7 +126,6 @@ do { \
> #define v3pr_info(fmt, ...) vnpr_info(3, fmt, ##__VA_ARGS__)
> #define v4pr_info(fmt, ...) vnpr_info(4, fmt, ##__VA_ARGS__)
>
> -
> /*
> * simplify a repeated for-loop pattern walking N steps in a T _vec
> * member inside a struct _box. It expects int i and T *_sp to be
> @@ -139,8 +136,8 @@ do { \
> * @_vec: name of a sub-struct member in _box, with array-ref and length
> */
> #define for_subvec(_i, _sp, _box, _vec) \
> - for ((_i) = 0, (_sp) = (_box)->_vec; \
> - (_i) < (_box)->num_##_vec; \
> + for ((_i) = 0, (_sp) = (_box)->_vec.start; \
> + (_i) < (_box)->_vec.len; \
> (_i)++, (_sp)++)
>
> static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> @@ -163,6 +160,13 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> query->first_lineno, query->last_lineno, query->class_string);
> }
>
> +#define vpr_dt_info(dt_p, msg_p, ...) ({ \
> + struct ddebug_table const *_dt = dt_p; \
> + v2pr_info(msg_p " module:%s nd:%d nc:%d nu:%d\n", ##__VA_ARGS__, \
> + _dt->mod_name, _dt->info.descs.len, _dt->info.maps.len, \
> + _dt->info.users.len); \
> + })
> +
This macro is not used before PATCH 17/59, maybe move it there?
By curiosity, do you know why the `verbose` parameter was introduced? It
is not possible to use dyndbg on dyndbg?
> #define __outvar /* filled by callee */
> static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
> const char *class_string,
> @@ -171,7 +175,7 @@ static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
> struct ddebug_class_map *map;
> int i, idx;
>
> - for_subvec(i, map, dt, classes) {
> + for_subvec(i, map, &dt->info, maps) {
> idx = match_string(map->class_names, map->length, class_string);
> if (idx >= 0) {
> *class_id = idx + map->base;
> @@ -217,8 +221,8 @@ static int ddebug_change(const struct ddebug_query *query,
> valid_class = _DPRINTK_CLASS_DFLT;
> }
>
> - for (i = 0; i < dt->num_ddebugs; i++) {
> - struct _ddebug *dp = &dt->ddebugs[i];
> + for (i = 0; i < dt->info.descs.len; i++) {
> + struct _ddebug *dp = &dt->info.descs.start[i];
>
> /* match site against query-class */
> if (dp->class_id != valid_class)
> @@ -1065,8 +1069,8 @@ static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
> }
> iter->table = list_entry(ddebug_tables.next,
> struct ddebug_table, link);
> - iter->idx = iter->table->num_ddebugs;
> - return &iter->table->ddebugs[--iter->idx];
> + iter->idx = iter->table->info.descs.len;
> + return &iter->table->info.descs.start[--iter->idx];
> }
>
> /*
> @@ -1087,10 +1091,10 @@ static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
> }
> iter->table = list_entry(iter->table->link.next,
> struct ddebug_table, link);
> - iter->idx = iter->table->num_ddebugs;
> + iter->idx = iter->table->info.descs.len;
> --iter->idx;
> }
> - return &iter->table->ddebugs[iter->idx];
> + return &iter->table->info.descs.start[iter->idx];
> }
>
> /*
> @@ -1137,12 +1141,12 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
> #define class_in_range(class_id, map) \
> (class_id >= map->base && class_id < map->base + map->length)
>
> -static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug *dp)
> +static const char *ddebug_class_name(struct ddebug_table *dt, struct _ddebug *dp)
> {
> - struct ddebug_class_map *map = iter->table->classes;
> - int i, nc = iter->table->num_classes;
> + struct ddebug_class_map *map;
> + int i;
>
> - for (i = 0; i < nc; i++, map++)
> + for_subvec(i, map, &dt->info, maps)
This change can't be done in 11/59? (perhaps with classes and not maps).
> if (class_in_range(dp->class_id, map))
> return map->class_names[dp->class_id - map->base];
>
> @@ -1176,7 +1180,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
> seq_putc(m, '"');
>
> if (dp->class_id != _DPRINTK_CLASS_DFLT) {
> - class = ddebug_class_name(iter, dp);
> + class = ddebug_class_name(iter->table, dp);
> if (class)
> seq_printf(m, " class:%s", class);
> else
> @@ -1236,18 +1240,18 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
> * the builtin/modular classmap vector/section. Save the start
> * and length of the subrange at its edges.
> */
> - for_subvec(i, cm, di, classes) {
> + for_subvec(i, cm, di, maps) {
> if (!strcmp(cm->mod_name, dt->mod_name)) {
> if (!nc) {
> v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
> i, cm->mod_name, cm->base, cm->length, cm->map_type);
> - dt->classes = cm;
> + dt->info.maps.start = cm;
> }
> nc++;
> }
> }
> if (nc) {
> - dt->num_classes = nc;
> + dt->info.maps.len = nc;
> vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
> }
> }
> @@ -1260,10 +1264,10 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> {
> struct ddebug_table *dt;
>
> - if (!di->num_descs)
> + if (!di->descs.len)
> return 0;
>
> - v3pr_info("add-module: %s %d sites\n", modname, di->num_descs);
> + v3pr_info("add-module: %s %d sites\n", modname, di->descs.len);
>
> dt = kzalloc(sizeof(*dt), GFP_KERNEL);
> if (dt == NULL) {
> @@ -1277,19 +1281,18 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> * this struct ddebug_table.
> */
> dt->mod_name = modname;
> - dt->ddebugs = di->descs;
> - dt->num_ddebugs = di->num_descs;
> + dt->info = *di;
>
> INIT_LIST_HEAD(&dt->link);
>
> - if (di->classes && di->num_classes)
> + if (di->maps.len)
> ddebug_attach_module_classes(dt, di);
>
> mutex_lock(&ddebug_lock);
> list_add_tail(&dt->link, &ddebug_tables);
> mutex_unlock(&ddebug_lock);
>
> - vpr_info("%3u debug prints in module %s\n", di->num_descs, modname);
> + vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
> return 0;
> }
>
> @@ -1436,10 +1439,10 @@ static int __init dynamic_debug_init(void)
> char *cmdline;
>
> struct _ddebug_info di = {
> - .descs = __start___dyndbg,
> - .classes = __start___dyndbg_classes,
> - .num_descs = __stop___dyndbg - __start___dyndbg,
> - .num_classes = __stop___dyndbg_classes - __start___dyndbg_classes,
> + .descs.start = __start___dyndbg_descs,
> + .maps.start = __start___dyndbg_class_maps,
> + .descs.len = __stop___dyndbg_descs - __start___dyndbg_descs,
> + .maps.len = __stop___dyndbg_class_maps - __start___dyndbg_class_maps,
> };
>
> #ifdef CONFIG_MODULES
> @@ -1450,7 +1453,7 @@ static int __init dynamic_debug_init(void)
> }
> #endif /* CONFIG_MODULES */
>
> - if (&__start___dyndbg == &__stop___dyndbg) {
> + if (&__start___dyndbg_descs == &__stop___dyndbg_descs) {
> if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
> pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
> return 1;
> @@ -1460,16 +1463,16 @@ static int __init dynamic_debug_init(void)
> return 0;
> }
>
> - iter = iter_mod_start = __start___dyndbg;
> + iter = iter_mod_start = __start___dyndbg_descs;
> modname = iter->modname;
> i = mod_sites = mod_ct = 0;
>
> - for (; iter < __stop___dyndbg; iter++, i++, mod_sites++) {
> + for (; iter < __stop___dyndbg_descs; iter++, i++, mod_sites++) {
>
> if (strcmp(modname, iter->modname)) {
> mod_ct++;
> - di.num_descs = mod_sites;
> - di.descs = iter_mod_start;
> + di.descs.len = mod_sites;
> + di.descs.start = iter_mod_start;
> ret = ddebug_add_module(&di, modname);
> if (ret)
> goto out_err;
> @@ -1479,8 +1482,8 @@ static int __init dynamic_debug_init(void)
> iter_mod_start = iter;
> }
> }
> - di.num_descs = mod_sites;
> - di.descs = iter_mod_start;
> + di.descs.len = mod_sites;
> + di.descs.start = iter_mod_start;
> ret = ddebug_add_module(&di, modname);
> if (ret)
> goto out_err;
> @@ -1490,8 +1493,8 @@ static int __init dynamic_debug_init(void)
> i, mod_ct, (int)((mod_ct * sizeof(struct ddebug_table)) >> 10),
> (int)((i * sizeof(struct _ddebug)) >> 10));
>
> - if (di.num_classes)
> - v2pr_info(" %d builtin ddebug class-maps\n", di.num_classes);
> + if (di.maps.len)
> + v2pr_info(" %d builtin ddebug class-maps\n", di.maps.len);
>
> /* now that ddebug tables are loaded, process all boot args
> * again to find and activate queries given in dyndbg params.
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 13/59] dyndbg: add 2 new _DPRINTK_FLAGS_: INCL_LOOKUP, PREFIX_CACHED
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (11 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 12/59] dyndbg, module: make proper substructs in _ddebug_info Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:11 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 14/59] dyndbg: split _emit_lookup() out of dynamic_emit_prefix() Jim Cromie
` (45 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Add _INCL_LOOKUP condition to separate +mfsl flags from +t, allowing
(after refactoring) to avoid a needless call-return.
Add a PREFIX_CACHED bit to remember that a pr-debug callsite is:
- enabled, with +p
- wants a dynamic-prefix, with _INCL_LOOKUP
- was previously called
- was thus saved in the prefix cache. NOT YET.
This allows (later) to cache part/all of the dynamic-prefix for each
pr_debug that gets called.
NOTES:
dyndbg's dynamic prefixing can get expensive; each enabled callsite's
prefix is sprintf'd into stack-mem, every time a pr_debug is called.
A cache would help, if callsites mark _DPRINTK_FLAGS_PREFIX_CACHED
after saving the prefix string. But not yet.
-t thread-id. not part of the "callsite" info, derived from current.
doesn't belong in the cache. it would be wrong.
can be done in outer: dynamic_emit_prefix()
-mfsl module, function, source-file, line
we cache these, composed into a sub-string.
they are "lookups", currently to descriptor fields,.
could be accessor macros to "compressed" tables.
All enabled together, they compose a prefix string like:
# outer -----inner-------------------
"[tid] module:function:sourcfile:line: "
So this patch extracts _DPRINTK_FLAGS_INCL_LOOKUP macro out of
_DPRINTK_FLAGS_INCL_ANY macro, then redefs latter.
Next re-refactor dynamic_emit_prefix inner/outer fns accordingly.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
include/linux/dynamic_debug.h | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index c388ab05a6e1..82eabaa6e827 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -38,11 +38,13 @@ struct _ddebug {
#define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
#define _DPRINTK_FLAGS_INCL_TID (1<<4)
#define _DPRINTK_FLAGS_INCL_SOURCENAME (1<<5)
+#define _DPRINTK_FLAGS_PREFIX_CACHED (1<<7)
-#define _DPRINTK_FLAGS_INCL_ANY \
- (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
- _DPRINTK_FLAGS_INCL_LINENO | _DPRINTK_FLAGS_INCL_TID |\
- _DPRINTK_FLAGS_INCL_SOURCENAME)
+#define _DPRINTK_FLAGS_INCL_LOOKUP \
+ (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME | \
+ _DPRINTK_FLAGS_INCL_SOURCENAME | _DPRINTK_FLAGS_INCL_LINENO)
+#define _DPRINTK_FLAGS_INCL_ANY \
+ (_DPRINTK_FLAGS_INCL_TID | _DPRINTK_FLAGS_INCL_LOOKUP)
#if defined DEBUG
#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 13/59] dyndbg: add 2 new _DPRINTK_FLAGS_: INCL_LOOKUP, PREFIX_CACHED
2025-03-20 18:51 ` [PATCH v2 13/59] dyndbg: add 2 new _DPRINTK_FLAGS_: INCL_LOOKUP, PREFIX_CACHED Jim Cromie
@ 2025-03-24 15:11 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:11 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> Add _INCL_LOOKUP condition to separate +mfsl flags from +t, allowing
> (after refactoring) to avoid a needless call-return.
>
> Add a PREFIX_CACHED bit to remember that a pr-debug callsite is:
>
> - enabled, with +p
> - wants a dynamic-prefix, with _INCL_LOOKUP
> - was previously called
> - was thus saved in the prefix cache. NOT YET.
>
> This allows (later) to cache part/all of the dynamic-prefix for each
> pr_debug that gets called.
>
> NOTES:
>
> dyndbg's dynamic prefixing can get expensive; each enabled callsite's
> prefix is sprintf'd into stack-mem, every time a pr_debug is called.
>
> A cache would help, if callsites mark _DPRINTK_FLAGS_PREFIX_CACHED
> after saving the prefix string. But not yet.
>
> -t thread-id. not part of the "callsite" info, derived from current.
> doesn't belong in the cache. it would be wrong.
> can be done in outer: dynamic_emit_prefix()
>
> -mfsl module, function, source-file, line
> we cache these, composed into a sub-string.
> they are "lookups", currently to descriptor fields,.
> could be accessor macros to "compressed" tables.
>
> All enabled together, they compose a prefix string like:
>
> # outer -----inner-------------------
> "[tid] module:function:sourcfile:line: "
s/sourcfile/sourcesfile/
>
> So this patch extracts _DPRINTK_FLAGS_INCL_LOOKUP macro out of
> _DPRINTK_FLAGS_INCL_ANY macro, then redefs latter.
>
> Next re-refactor dynamic_emit_prefix inner/outer fns accordingly.
This commit introduces two things:
- introduction of _DPRINTK_FLAGS_INCL_LOOKUP, used in a future patch
- introduction of _DPRINTK_FLAGS_PREFIX_CACHED, not used in this series
I don't think those changes are needed to fix DYNDBG_CLASSMAP, it seems
to be an (unfinished?) optimization, so it could make sense to move it
to an independent series. Please tell me if I overlooked something!
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> include/linux/dynamic_debug.h | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index c388ab05a6e1..82eabaa6e827 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -38,11 +38,13 @@ struct _ddebug {
> #define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
> #define _DPRINTK_FLAGS_INCL_TID (1<<4)
> #define _DPRINTK_FLAGS_INCL_SOURCENAME (1<<5)
> +#define _DPRINTK_FLAGS_PREFIX_CACHED (1<<7)
Is there a reason to skip 1 << 6? I don't see any usage of this flag in
this series, maybe you can skip it for now and introduce it with the
actual implementation of the cache system?
Also, I think it make sense to add some documentation on this define.
All the other are controlled by the user, but PREFIX_CACHED is
controlled by the "dyndbg core", so maybe add something like:
/**
* _DPRINTK_FLAGS_PREFIX_CACHED - Mark a printk prefix as cached
* This bit is set by the callsite to avoid regenerating fixed
* part of the prefix at each call
*/
>
> -#define _DPRINTK_FLAGS_INCL_ANY \
> - (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
> - _DPRINTK_FLAGS_INCL_LINENO | _DPRINTK_FLAGS_INCL_TID |\
> - _DPRINTK_FLAGS_INCL_SOURCENAME)
> +#define _DPRINTK_FLAGS_INCL_LOOKUP \
> + (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME | \
> + _DPRINTK_FLAGS_INCL_SOURCENAME | _DPRINTK_FLAGS_INCL_LINENO)
> +#define _DPRINTK_FLAGS_INCL_ANY \
> + (_DPRINTK_FLAGS_INCL_TID | _DPRINTK_FLAGS_INCL_LOOKUP)
>
> #if defined DEBUG
> #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 14/59] dyndbg: split _emit_lookup() out of dynamic_emit_prefix()
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (12 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 13/59] dyndbg: add 2 new _DPRINTK_FLAGS_: INCL_LOOKUP, PREFIX_CACHED Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:14 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 15/59] dyndbg: hoist classmap-filter-by-modname up to ddebug_add_module Jim Cromie
` (44 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Split dynamic_emit_prefix() to separate out _INCL_LOOKUPs:
1. keep dynamic_emit_prefix() static inline
check _INCL_ANY flags before calling 2
2. __dynamic_emit_prefix()
prints [TID] or <intr> and trailing space if +t flag
check _INCL_LOOKUP flags before calling 3
3. __dynamic_emit_lookup()
prints ONLY module, function, src, line, and trailing space
TID isn't "callsite" specific info.
result is "cacheable"
Notes:
2,3 are gated, only called when theyve something to emit, so they just
add trailing space. This obsoletes the pos_after_tid var and logic.
__dynamic_emit_lookup() adds line too, so the result is "whole".
While this would enlarge a naive cache vs add-line-after-caching, we
dont even have a naive one yet.
And some clever indexing on store() might be able to fold the flags
setting in, such that the prefix stored with +mf flags only (-l),
could be returned for all pr_debugs in that function which also had
+mf flags. While still supporting +mfsl prefixes (with cache
expansion) as they're used.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
lib/dynamic_debug.c | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 663c125006d0..f7ec2365ab40 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -850,19 +850,8 @@ static int remaining(int wrote)
return 0;
}
-static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
+static int __dynamic_emit_lookup(const struct _ddebug *desc, char *buf, int pos)
{
- int pos_after_tid;
- int pos = 0;
-
- if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
- if (in_interrupt())
- pos += snprintf(buf + pos, remaining(pos), "<intr> ");
- else
- pos += snprintf(buf + pos, remaining(pos), "[%d] ",
- task_pid_vnr(current));
- }
- pos_after_tid = pos;
if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
desc->modname);
@@ -875,8 +864,29 @@ static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
desc->lineno);
- if (pos - pos_after_tid)
- pos += snprintf(buf + pos, remaining(pos), " ");
+
+ /* cuz LOOKUP, we've emitted, so add trailing space if room */
+ if (remaining(pos))
+ buf[pos++] = ' ';
+
+ return pos;
+}
+
+static char *__dynamic_emit_prefix(struct _ddebug *desc, char *buf)
+{
+ int pos = 0;
+
+ if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
+ if (in_interrupt())
+ pos += snprintf(buf + pos, remaining(pos), "<intr> ");
+ else
+ pos += snprintf(buf + pos, remaining(pos), "[%d] ",
+ task_pid_vnr(current));
+ }
+
+ if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_LOOKUP))
+ pos += __dynamic_emit_lookup(desc, buf, pos);
+
if (pos >= PREFIX_SIZE)
buf[PREFIX_SIZE - 1] = '\0';
@@ -885,7 +895,7 @@ static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
{
- if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))
+ if (desc->flags & _DPRINTK_FLAGS_INCL_ANY)
return __dynamic_emit_prefix(desc, buf);
return buf;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 14/59] dyndbg: split _emit_lookup() out of dynamic_emit_prefix()
2025-03-20 18:51 ` [PATCH v2 14/59] dyndbg: split _emit_lookup() out of dynamic_emit_prefix() Jim Cromie
@ 2025-03-24 15:14 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:14 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> Split dynamic_emit_prefix() to separate out _INCL_LOOKUPs:
>
> 1. keep dynamic_emit_prefix() static inline
> check _INCL_ANY flags before calling 2
>
> 2. __dynamic_emit_prefix()
> prints [TID] or <intr> and trailing space if +t flag
> check _INCL_LOOKUP flags before calling 3
>
> 3. __dynamic_emit_lookup()
> prints ONLY module, function, src, line, and trailing space
> TID isn't "callsite" specific info.
> result is "cacheable"
>
> Notes:
>
> 2,3 are gated, only called when theyve something to emit, so they just
> add trailing space. This obsoletes the pos_after_tid var and logic.
>
> __dynamic_emit_lookup() adds line too, so the result is "whole".
> While this would enlarge a naive cache vs add-line-after-caching, we
> dont even have a naive one yet.
>
> And some clever indexing on store() might be able to fold the flags
> setting in, such that the prefix stored with +mf flags only (-l),
> could be returned for all pr_debugs in that function which also had
> +mf flags. While still supporting +mfsl prefixes (with cache
> expansion) as they're used.
Like the previous patch: I think this should be a separate series.
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> lib/dynamic_debug.c | 40 +++++++++++++++++++++++++---------------
> 1 file changed, 25 insertions(+), 15 deletions(-)
>
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index 663c125006d0..f7ec2365ab40 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -850,19 +850,8 @@ static int remaining(int wrote)
> return 0;
> }
>
> -static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
> +static int __dynamic_emit_lookup(const struct _ddebug *desc, char *buf, int pos)
> {
> - int pos_after_tid;
> - int pos = 0;
> -
> - if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
> - if (in_interrupt())
> - pos += snprintf(buf + pos, remaining(pos), "<intr> ");
> - else
> - pos += snprintf(buf + pos, remaining(pos), "[%d] ",
> - task_pid_vnr(current));
> - }
> - pos_after_tid = pos;
> if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
> pos += snprintf(buf + pos, remaining(pos), "%s:",
> desc->modname);
> @@ -875,8 +864,29 @@ static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
> if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
> pos += snprintf(buf + pos, remaining(pos), "%d:",
> desc->lineno);
> - if (pos - pos_after_tid)
> - pos += snprintf(buf + pos, remaining(pos), " ");
> +
> + /* cuz LOOKUP, we've emitted, so add trailing space if room */
s/cuz/because/
> + if (remaining(pos))
> + buf[pos++] = ' ';
> +
> + return pos;
> +}
> +
> +static char *__dynamic_emit_prefix(struct _ddebug *desc, char *buf)
> +{
> + int pos = 0;
> +
> + if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
> + if (in_interrupt())
> + pos += snprintf(buf + pos, remaining(pos), "<intr> ");
> + else
> + pos += snprintf(buf + pos, remaining(pos), "[%d] ",
> + task_pid_vnr(current));
> + }
> +
> + if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_LOOKUP))
> + pos += __dynamic_emit_lookup(desc, buf, pos);
> +
> if (pos >= PREFIX_SIZE)
> buf[PREFIX_SIZE - 1] = '\0';
>
> @@ -885,7 +895,7 @@ static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
>
> static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
> {
> - if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))
> + if (desc->flags & _DPRINTK_FLAGS_INCL_ANY)
Why do you remove the unlikely here?
> return __dynamic_emit_prefix(desc, buf);
> return buf;
> }
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 15/59] dyndbg: hoist classmap-filter-by-modname up to ddebug_add_module
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (13 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 14/59] dyndbg: split _emit_lookup() out of dynamic_emit_prefix() Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:14 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 16/59] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code Jim Cromie
` (43 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The body of ddebug_attach_module_classes() is dominated by a
code-block that finds the contiguous subrange of classmaps matching on
modname, and saves it into the ddebug_table's info record.
Implement this block in a macro to accommodate different component
vectors in the "box" (as named in the for_subvec macro).
And hoist its invocation out of ddebug_attach_module_classes() up into
ddebug_add_module(). This moves the filtering step up closer to
dynamic_debug_init(), which effectively does the same for builtin
pr_debug descriptors; segmenting them into subranges by modname.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
lib/dynamic_debug.c | 57 ++++++++++++++++++++++++++++-----------------
1 file changed, 35 insertions(+), 22 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f7ec2365ab40..192783ff7b98 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1242,30 +1242,34 @@ static const struct proc_ops proc_fops = {
static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
{
- struct ddebug_class_map *cm;
- int i, nc = 0;
-
- /*
- * Find this module's classmaps in a subrange/wholerange of
- * the builtin/modular classmap vector/section. Save the start
- * and length of the subrange at its edges.
- */
- for_subvec(i, cm, di, maps) {
- if (!strcmp(cm->mod_name, dt->mod_name)) {
- if (!nc) {
- v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
- i, cm->mod_name, cm->base, cm->length, cm->map_type);
- dt->info.maps.start = cm;
- }
- nc++;
- }
- }
- if (nc) {
- dt->info.maps.len = nc;
- vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
- }
+ vpr_info("module:%s attached %d classes\n", dt->mod_name, dt->info.maps.len);
}
+/*
+ * scan the named array: @_vec, ref'd from inside @_box, for the
+ * start,len of the sub-array of elements matching on ->mod_name;
+ * remember them in _dst. Macro depends upon the fields being in both
+ * _box and _dst.
+ * @_i: caller provided counter var, init'd by macro
+ * @_sp: cursor into @_vec.
+ * @_box: ptr to a struct with @_vec, num__##@_vec, mod_name fields.
+ * @_vec: name of ref into array[T] of builtin/modular __section data.
+ * @_dst: ptr to struct with @_vec and num__##@_vec fields, both updated.
+ */
+#define dd_mark_vector_subrange(_i, _dst, _sp, _box, _vec) ({ \
+ int nc = 0; \
+ for_subvec(_i, _sp, _box, _vec) { \
+ if (!strcmp((_sp)->mod_name, (_dst)->mod_name)) { \
+ if (!nc++) \
+ (_dst)->info._vec.start = (_sp); \
+ } else { \
+ if (nc) \
+ break; /* end of consecutive matches */ \
+ } \
+ } \
+ (_dst)->info._vec.len = nc; \
+})
+
/*
* Allocate a new ddebug_table for the given module
* and add it to the global list.
@@ -1273,6 +1277,8 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
{
struct ddebug_table *dt;
+ struct ddebug_class_map *cm;
+ int i;
if (!di->descs.len)
return 0;
@@ -1294,6 +1300,13 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
dt->info = *di;
INIT_LIST_HEAD(&dt->link);
+ /*
+ * for builtin modules, ddebug_init() insures that the di
+ * cursor marks just the module's descriptors, but it doesn't
+ * do so for the builtin class _maps & _users. find the
+ * start,len of the vectors by mod_name, save to dt.
+ */
+ dd_mark_vector_subrange(i, dt, cm, di, maps);
if (di->maps.len)
ddebug_attach_module_classes(dt, di);
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 15/59] dyndbg: hoist classmap-filter-by-modname up to ddebug_add_module
2025-03-20 18:51 ` [PATCH v2 15/59] dyndbg: hoist classmap-filter-by-modname up to ddebug_add_module Jim Cromie
@ 2025-03-24 15:14 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:14 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> The body of ddebug_attach_module_classes() is dominated by a
> code-block that finds the contiguous subrange of classmaps matching on
> modname, and saves it into the ddebug_table's info record.
>
> Implement this block in a macro to accommodate different component
> vectors in the "box" (as named in the for_subvec macro).
>
> And hoist its invocation out of ddebug_attach_module_classes() up into
> ddebug_add_module(). This moves the filtering step up closer to
> dynamic_debug_init(), which effectively does the same for builtin
> pr_debug descriptors; segmenting them into subranges by modname.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
>
> ---
> lib/dynamic_debug.c | 57 ++++++++++++++++++++++++++++-----------------
> 1 file changed, 35 insertions(+), 22 deletions(-)
>
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index f7ec2365ab40..192783ff7b98 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -1242,30 +1242,34 @@ static const struct proc_ops proc_fops = {
>
> static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
> {
> - struct ddebug_class_map *cm;
> - int i, nc = 0;
> -
> - /*
> - * Find this module's classmaps in a subrange/wholerange of
> - * the builtin/modular classmap vector/section. Save the start
> - * and length of the subrange at its edges.
> - */
> - for_subvec(i, cm, di, maps) {
> - if (!strcmp(cm->mod_name, dt->mod_name)) {
> - if (!nc) {
> - v2pr_info("start subrange, class[%d]: module:%s base:%d len:%d ty:%d\n",
> - i, cm->mod_name, cm->base, cm->length, cm->map_type);
> - dt->info.maps.start = cm;
> - }
> - nc++;
> - }
> - }
> - if (nc) {
> - dt->info.maps.len = nc;
> - vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
> - }
> + vpr_info("module:%s attached %d classes\n", dt->mod_name, dt->info.maps.len);
> }
>
> +/*
> + * scan the named array: @_vec, ref'd from inside @_box, for the
> + * start,len of the sub-array of elements matching on ->mod_name;
> + * remember them in _dst. Macro depends upon the fields being in both
> + * _box and _dst.
> + * @_i: caller provided counter var, init'd by macro
> + * @_sp: cursor into @_vec.
> + * @_box: ptr to a struct with @_vec, num__##@_vec, mod_name fields.
> + * @_vec: name of ref into array[T] of builtin/modular __section data.
> + * @_dst: ptr to struct with @_vec and num__##@_vec fields, both updated.
I think you forgot to update this documentation with the new vector
structure (num__##@_vec does not exists anymore)
> + */
> +#define dd_mark_vector_subrange(_i, _dst, _sp, _box, _vec) ({ \
> + int nc = 0; \
> + for_subvec(_i, _sp, _box, _vec) { \
> + if (!strcmp((_sp)->mod_name, (_dst)->mod_name)) { \
> + if (!nc++) \
> + (_dst)->info._vec.start = (_sp); \
> + } else { \
> + if (nc) \
> + break; /* end of consecutive matches */ \
> + } \
> + } \
> + (_dst)->info._vec.len = nc; \
> +})
> +
> /*
> * Allocate a new ddebug_table for the given module
> * and add it to the global list.
> @@ -1273,6 +1277,8 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
> static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> {
> struct ddebug_table *dt;
> + struct ddebug_class_map *cm;
> + int i;
>
> if (!di->descs.len)
> return 0;
> @@ -1294,6 +1300,13 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> dt->info = *di;
>
> INIT_LIST_HEAD(&dt->link);
> + /*
> + * for builtin modules, ddebug_init() insures that the di
> + * cursor marks just the module's descriptors, but it doesn't
> + * do so for the builtin class _maps & _users. find the
Nitpick, the _users builtin class is only introduced in patch 19/56,
maybe update the documentation there.
> + * start,len of the vectors by mod_name, save to dt.
> + */
> + dd_mark_vector_subrange(i, dt, cm, di, maps);
>
> if (di->maps.len)
> ddebug_attach_module_classes(dt, di);
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 16/59] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (14 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 15/59] dyndbg: hoist classmap-filter-by-modname up to ddebug_add_module Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:15 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 17/59] dyndbg-API: replace DECLARE_DYNDBG_CLASSMAP Jim Cromie
` (42 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Remove the DD_CLASS_TYPE_*_NAMES classmap types and code.
These 2 classmap types accept class names at the PARAM interface, for
example:
echo +DRM_UT_CORE,-DRM_UT_KMS > /sys/module/drm/parameters/debug_names
The code works, but its only used by test-dynamic-debug, and wasn't
asked for by anyone else, so reduce test-surface, and simplify things.
also rename enum class_map_type to enum ddebug_class_map_type.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
include/linux/dynamic_debug.h | 23 ++------
lib/dynamic_debug.c | 102 +++-------------------------------
lib/test_dynamic_debug.c | 26 ---------
3 files changed, 14 insertions(+), 137 deletions(-)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 82eabaa6e827..9fb38d79216e 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -60,27 +60,16 @@ struct _ddebug {
#endif
} __attribute__((aligned(8)));
-enum class_map_type {
+enum ddebug_class_map_type {
DD_CLASS_TYPE_DISJOINT_BITS,
/**
- * DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, one per bit.
- * expecting hex input. Built for drm.debug, basis for other types.
+ * DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, mapped to bits[0..N].
+ * Expects hex input. Built for drm.debug, basis for other types.
*/
DD_CLASS_TYPE_LEVEL_NUM,
/**
- * DD_CLASS_TYPE_LEVEL_NUM: input is numeric level, 0-N.
- * N turns on just bits N-1 .. 0, so N=0 turns all bits off.
- */
- DD_CLASS_TYPE_DISJOINT_NAMES,
- /**
- * DD_CLASS_TYPE_DISJOINT_NAMES: input is a CSV of [+-]CLASS_NAMES,
- * classes are independent, like _DISJOINT_BITS.
- */
- DD_CLASS_TYPE_LEVEL_NAMES,
- /**
- * DD_CLASS_TYPE_LEVEL_NAMES: input is a CSV of [+-]CLASS_NAMES,
- * intended for names like: INFO,DEBUG,TRACE, with a module prefix
- * avoid EMERG,ALERT,CRIT,ERR,WARNING: they're not debug
+ * DD_CLASS_TYPE_LEVEL_NUM: input is numeric level, 0..N.
+ * Input N turns on bits 0..N-1
*/
};
@@ -90,7 +79,7 @@ struct ddebug_class_map {
const char **class_names;
const int length;
const int base; /* index of 1st .class_id, allows split/shared space */
- enum class_map_type map_type;
+ enum ddebug_class_map_type map_type;
};
/**
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 192783ff7b98..5df9cc732290 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -655,76 +655,6 @@ static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
#define CLASSMAP_BITMASK(width) ((1UL << (width)) - 1)
-/* accept comma-separated-list of [+-] classnames */
-static int param_set_dyndbg_classnames(const char *instr, const struct kernel_param *kp)
-{
- const struct ddebug_class_param *dcp = kp->arg;
- const struct ddebug_class_map *map = dcp->map;
- unsigned long curr_bits, old_bits;
- char *cl_str, *p, *tmp;
- int cls_id, totct = 0;
- bool wanted;
-
- cl_str = tmp = kstrdup_and_replace(instr, '\n', '\0', GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
-
- /* start with previously set state-bits, then modify */
- curr_bits = old_bits = *dcp->bits;
- vpr_info("\"%s\" > %s:0x%lx\n", cl_str, KP_NAME(kp), curr_bits);
-
- for (; cl_str; cl_str = p) {
- p = strchr(cl_str, ',');
- if (p)
- *p++ = '\0';
-
- if (*cl_str == '-') {
- wanted = false;
- cl_str++;
- } else {
- wanted = true;
- if (*cl_str == '+')
- cl_str++;
- }
- cls_id = match_string(map->class_names, map->length, cl_str);
- if (cls_id < 0) {
- pr_err("%s unknown to %s\n", cl_str, KP_NAME(kp));
- continue;
- }
-
- /* have one or more valid class_ids of one *_NAMES type */
- switch (map->map_type) {
- case DD_CLASS_TYPE_DISJOINT_NAMES:
- /* the +/- pertains to a single bit */
- if (test_bit(cls_id, &curr_bits) == wanted) {
- v3pr_info("no change on %s\n", cl_str);
- continue;
- }
- curr_bits ^= BIT(cls_id);
- 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]);
- break;
- case DD_CLASS_TYPE_LEVEL_NAMES:
- /* cls_id = N in 0..max. wanted +/- determines N or N-1 */
- 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, 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);
- break;
- default:
- pr_err("illegal map-type value %d\n", map->map_type);
- }
- }
- kfree(tmp);
- vpr_info("total matches: %d\n", totct);
- return 0;
-}
-
static int param_set_dyndbg_module_classes(const char *instr,
const struct kernel_param *kp,
const char *modnm)
@@ -733,29 +663,17 @@ static int param_set_dyndbg_module_classes(const char *instr,
const struct ddebug_class_map *map = dcp->map;
unsigned long inrep, new_bits, old_bits;
int rc, totct = 0;
-
- switch (map->map_type) {
-
- case DD_CLASS_TYPE_DISJOINT_NAMES:
- case DD_CLASS_TYPE_LEVEL_NAMES:
- /* handle [+-]classnames list separately, we are done here */
- return param_set_dyndbg_classnames(instr, kp);
-
- case DD_CLASS_TYPE_DISJOINT_BITS:
- case DD_CLASS_TYPE_LEVEL_NUM:
- /* numeric input, accept and fall-thru */
- rc = kstrtoul(instr, 0, &inrep);
- if (rc) {
- pr_err("expecting numeric input: %s > %s\n", instr, KP_NAME(kp));
- return -EINVAL;
- }
- break;
- default:
- pr_err("%s: bad map type: %d\n", KP_NAME(kp), map->map_type);
+ char *nl;
+
+ rc = kstrtoul(instr, 0, &inrep);
+ if (rc) {
+ nl = strchr(instr, '\n');
+ if (nl)
+ *nl = '\0';
+ pr_err("expecting numeric input, not: %s > %s\n", instr, KP_NAME(kp));
return -EINVAL;
}
- /* only _BITS,_NUM (numeric) map-types get here */
switch (map->map_type) {
case DD_CLASS_TYPE_DISJOINT_BITS:
/* expect bits. mask and warn if too many */
@@ -821,12 +739,8 @@ int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
const struct ddebug_class_map *map = dcp->map;
switch (map->map_type) {
-
- case DD_CLASS_TYPE_DISJOINT_NAMES:
case DD_CLASS_TYPE_DISJOINT_BITS:
return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", *dcp->bits);
-
- case DD_CLASS_TYPE_LEVEL_NAMES:
case DD_CLASS_TYPE_LEVEL_NUM:
return scnprintf(buffer, PAGE_SIZE, "%ld\n", *dcp->lvl);
default:
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 396144cf351b..74d183ebf3e0 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -74,13 +74,6 @@ DECLARE_DYNDBG_CLASSMAP(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS, 0,
DD_SYS_WRAP(disjoint_bits, p);
DD_SYS_WRAP(disjoint_bits, T);
-/* symbolic input, independent bits */
-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);
-DD_SYS_WRAP(disjoint_names, T);
-
/* numeric verbosity, V2 > V1 related */
enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
@@ -88,13 +81,6 @@ DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
DD_SYS_WRAP(level_num, p);
DD_SYS_WRAP(level_num, T);
-/* symbolic verbosity */
-enum cat_level_names { L0 = 22, L1, L2, L3, L4, L5, L6, L7 };
-DECLARE_DYNDBG_CLASSMAP(map_level_names, DD_CLASS_TYPE_LEVEL_NAMES, 22,
- "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7");
-DD_SYS_WRAP(level_names, p);
-DD_SYS_WRAP(level_names, T);
-
/* stand-in for all pr_debug etc */
#define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
@@ -102,10 +88,6 @@ static void do_cats(void)
{
pr_debug("doing categories\n");
- prdbg(LOW);
- prdbg(MID);
- prdbg(HI);
-
prdbg(D2_CORE);
prdbg(D2_DRIVER);
prdbg(D2_KMS);
@@ -129,14 +111,6 @@ static void do_levels(void)
prdbg(V5);
prdbg(V6);
prdbg(V7);
-
- prdbg(L1);
- prdbg(L2);
- prdbg(L3);
- prdbg(L4);
- prdbg(L5);
- prdbg(L6);
- prdbg(L7);
}
static void do_prints(void)
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 16/59] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code
2025-03-20 18:51 ` [PATCH v2 16/59] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code Jim Cromie
@ 2025-03-24 15:15 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:15 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> Remove the DD_CLASS_TYPE_*_NAMES classmap types and code.
>
> These 2 classmap types accept class names at the PARAM interface, for
> example:
>
> echo +DRM_UT_CORE,-DRM_UT_KMS > /sys/module/drm/parameters/debug_names
>
> The code works, but its only used by test-dynamic-debug, and wasn't
> asked for by anyone else, so reduce test-surface, and simplify things.
>
> also rename enum class_map_type to enum ddebug_class_map_type.
Nitpick: s/also/Also/
There were no documentation about those features?
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> include/linux/dynamic_debug.h | 23 ++------
> lib/dynamic_debug.c | 102 +++-------------------------------
> lib/test_dynamic_debug.c | 26 ---------
> 3 files changed, 14 insertions(+), 137 deletions(-)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index 82eabaa6e827..9fb38d79216e 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -60,27 +60,16 @@ struct _ddebug {
> #endif
> } __attribute__((aligned(8)));
>
> -enum class_map_type {
> +enum ddebug_class_map_type {
> DD_CLASS_TYPE_DISJOINT_BITS,
> /**
> - * DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, one per bit.
> - * expecting hex input. Built for drm.debug, basis for other types.
> + * DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, mapped to bits[0..N].
> + * Expects hex input. Built for drm.debug, basis for other types.
> */
> DD_CLASS_TYPE_LEVEL_NUM,
> /**
> - * DD_CLASS_TYPE_LEVEL_NUM: input is numeric level, 0-N.
> - * N turns on just bits N-1 .. 0, so N=0 turns all bits off.
> - */
> - DD_CLASS_TYPE_DISJOINT_NAMES,
> - /**
> - * DD_CLASS_TYPE_DISJOINT_NAMES: input is a CSV of [+-]CLASS_NAMES,
> - * classes are independent, like _DISJOINT_BITS.
> - */
> - DD_CLASS_TYPE_LEVEL_NAMES,
> - /**
> - * DD_CLASS_TYPE_LEVEL_NAMES: input is a CSV of [+-]CLASS_NAMES,
> - * intended for names like: INFO,DEBUG,TRACE, with a module prefix
> - * avoid EMERG,ALERT,CRIT,ERR,WARNING: they're not debug
> + * DD_CLASS_TYPE_LEVEL_NUM: input is numeric level, 0..N.
> + * Input N turns on bits 0..N-1
> */
> };
>
> @@ -90,7 +79,7 @@ struct ddebug_class_map {
> const char **class_names;
> const int length;
> const int base; /* index of 1st .class_id, allows split/shared space */
> - enum class_map_type map_type;
> + enum ddebug_class_map_type map_type;
> };
>
> /**
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index 192783ff7b98..5df9cc732290 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -655,76 +655,6 @@ static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
>
> #define CLASSMAP_BITMASK(width) ((1UL << (width)) - 1)
>
> -/* accept comma-separated-list of [+-] classnames */
> -static int param_set_dyndbg_classnames(const char *instr, const struct kernel_param *kp)
> -{
> - const struct ddebug_class_param *dcp = kp->arg;
> - const struct ddebug_class_map *map = dcp->map;
> - unsigned long curr_bits, old_bits;
> - char *cl_str, *p, *tmp;
> - int cls_id, totct = 0;
> - bool wanted;
> -
> - cl_str = tmp = kstrdup_and_replace(instr, '\n', '\0', GFP_KERNEL);
> - if (!tmp)
> - return -ENOMEM;
> -
> - /* start with previously set state-bits, then modify */
> - curr_bits = old_bits = *dcp->bits;
> - vpr_info("\"%s\" > %s:0x%lx\n", cl_str, KP_NAME(kp), curr_bits);
> -
> - for (; cl_str; cl_str = p) {
> - p = strchr(cl_str, ',');
> - if (p)
> - *p++ = '\0';
> -
> - if (*cl_str == '-') {
> - wanted = false;
> - cl_str++;
> - } else {
> - wanted = true;
> - if (*cl_str == '+')
> - cl_str++;
> - }
> - cls_id = match_string(map->class_names, map->length, cl_str);
> - if (cls_id < 0) {
> - pr_err("%s unknown to %s\n", cl_str, KP_NAME(kp));
> - continue;
> - }
> -
> - /* have one or more valid class_ids of one *_NAMES type */
> - switch (map->map_type) {
> - case DD_CLASS_TYPE_DISJOINT_NAMES:
> - /* the +/- pertains to a single bit */
> - if (test_bit(cls_id, &curr_bits) == wanted) {
> - v3pr_info("no change on %s\n", cl_str);
> - continue;
> - }
> - curr_bits ^= BIT(cls_id);
> - 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]);
> - break;
> - case DD_CLASS_TYPE_LEVEL_NAMES:
> - /* cls_id = N in 0..max. wanted +/- determines N or N-1 */
> - 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, 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);
> - break;
> - default:
> - pr_err("illegal map-type value %d\n", map->map_type);
> - }
> - }
> - kfree(tmp);
> - vpr_info("total matches: %d\n", totct);
> - return 0;
> -}
> -
> static int param_set_dyndbg_module_classes(const char *instr,
> const struct kernel_param *kp,
> const char *modnm)
> @@ -733,29 +663,17 @@ static int param_set_dyndbg_module_classes(const char *instr,
> const struct ddebug_class_map *map = dcp->map;
> unsigned long inrep, new_bits, old_bits;
> int rc, totct = 0;
> -
> - switch (map->map_type) {
> -
> - case DD_CLASS_TYPE_DISJOINT_NAMES:
> - case DD_CLASS_TYPE_LEVEL_NAMES:
> - /* handle [+-]classnames list separately, we are done here */
> - return param_set_dyndbg_classnames(instr, kp);
> -
> - case DD_CLASS_TYPE_DISJOINT_BITS:
> - case DD_CLASS_TYPE_LEVEL_NUM:
> - /* numeric input, accept and fall-thru */
> - rc = kstrtoul(instr, 0, &inrep);
> - if (rc) {
> - pr_err("expecting numeric input: %s > %s\n", instr, KP_NAME(kp));
> - return -EINVAL;
> - }
> - break;
> - default:
> - pr_err("%s: bad map type: %d\n", KP_NAME(kp), map->map_type);
> + char *nl;
> +
> + rc = kstrtoul(instr, 0, &inrep);
> + if (rc) {
> + nl = strchr(instr, '\n');
> + if (nl)
> + *nl = '\0';
> + pr_err("expecting numeric input, not: %s > %s\n", instr, KP_NAME(kp));
> return -EINVAL;
> }
>
> - /* only _BITS,_NUM (numeric) map-types get here */
> switch (map->map_type) {
> case DD_CLASS_TYPE_DISJOINT_BITS:
> /* expect bits. mask and warn if too many */
> @@ -821,12 +739,8 @@ int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
> const struct ddebug_class_map *map = dcp->map;
>
> switch (map->map_type) {
> -
> - case DD_CLASS_TYPE_DISJOINT_NAMES:
> case DD_CLASS_TYPE_DISJOINT_BITS:
> return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", *dcp->bits);
> -
> - case DD_CLASS_TYPE_LEVEL_NAMES:
> case DD_CLASS_TYPE_LEVEL_NUM:
> return scnprintf(buffer, PAGE_SIZE, "%ld\n", *dcp->lvl);
> default:
> diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
> index 396144cf351b..74d183ebf3e0 100644
> --- a/lib/test_dynamic_debug.c
> +++ b/lib/test_dynamic_debug.c
> @@ -74,13 +74,6 @@ DECLARE_DYNDBG_CLASSMAP(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> DD_SYS_WRAP(disjoint_bits, p);
> DD_SYS_WRAP(disjoint_bits, T);
>
> -/* symbolic input, independent bits */
> -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);
> -DD_SYS_WRAP(disjoint_names, T);
> -
> /* numeric verbosity, V2 > V1 related */
> enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
> DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
> @@ -88,13 +81,6 @@ DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
> DD_SYS_WRAP(level_num, p);
> DD_SYS_WRAP(level_num, T);
>
> -/* symbolic verbosity */
> -enum cat_level_names { L0 = 22, L1, L2, L3, L4, L5, L6, L7 };
> -DECLARE_DYNDBG_CLASSMAP(map_level_names, DD_CLASS_TYPE_LEVEL_NAMES, 22,
> - "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7");
> -DD_SYS_WRAP(level_names, p);
> -DD_SYS_WRAP(level_names, T);
> -
> /* stand-in for all pr_debug etc */
> #define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
>
> @@ -102,10 +88,6 @@ static void do_cats(void)
> {
> pr_debug("doing categories\n");
>
> - prdbg(LOW);
> - prdbg(MID);
> - prdbg(HI);
> -
> prdbg(D2_CORE);
> prdbg(D2_DRIVER);
> prdbg(D2_KMS);
> @@ -129,14 +111,6 @@ static void do_levels(void)
> prdbg(V5);
> prdbg(V6);
> prdbg(V7);
> -
> - prdbg(L1);
> - prdbg(L2);
> - prdbg(L3);
> - prdbg(L4);
> - prdbg(L5);
> - prdbg(L6);
> - prdbg(L7);
> }
>
> static void do_prints(void)
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 17/59] dyndbg-API: replace DECLARE_DYNDBG_CLASSMAP
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (15 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 16/59] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:16 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 18/59] selftests-dyndbg: add tools/testing/selftests/dynamic_debug/* Jim Cromie
` (41 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie, linux-doc
DECLARE_DYNDBG_CLASSMAP() has a design error; its usage fails a basic
K&R rule: "define once, refer many times".
When DRM_USE_DYNAMIC_DEBUG=y, it is used across DRM core & drivers;
each invocation allocates/inits the classmap understood by that
module. All must match for the modules to respond together when
DRM.debug categories are enabled. This is brittle; a maintenance
foot-gun.
Further, its culpable in the CONFIG_DRM_USE_DYNAMIC_DEBUG=Y
regression; its use in both core & drivers obfuscates the 2 roles, that
caused incomplete initialization when modprobing drivers:
1st drm.ko loads, and dyndbg initializes its DRM.debug callsites, then
a drm-driver loads, but too late for the DRM.debug enablement.
So retire it, replace with 2 macros:
DYNAMIC_DEBUG_CLASSMAP_DEFINE - invoked once from core - drm.ko
DYNAMIC_DEBUG_CLASSMAP_USE - from all drm drivers and helpers.
DYNAMIC_DEBUG_CLASSMAP_DEFINE: this reworks DECLARE_DYNDBG_CLASSMAP,
by dropping the static qualifier on the classmap, and exporting it
instead.
DYNAMIC_DEBUG_CLASSMAP_USE: then refers to the exported var by name:
used from drivers, helper-mods
lets us drop the repetitive "classname" declarations
fixes 2nd-defn problem
creates a ddebug_class_user record in new __dyndbg_class_users section
new section is scanned "differently"
DECLARE_DYNDBG_CLASSMAP is preserved temporarily, to decouple DRM
adaptation work and avoid compile-errs before its done. IOW, DRM gets
these fixes when they commit the adopt-new-api patches.
The DEFINE,USE distinction, and the separate classmap-use record,
allows dyndbg to initialize the driver's & helper's DRM.debug
callsites separately after each is modprobed.
Basically, the classmap init-scan is repeated for classmap-users.
To review, dyndbg's existing __dyndbg_classes[] section does:
. catalogs the module's classmaps
. tells dyndbg about them, allowing >control
. DYNAMIC_DEBUG_CLASSMAP_DEFINE creates section records.
. we rename it to: __dyndbg_class_maps[]
Then this patch adds __dyndbg_class_users[] section:
. catalogs users of classmap definitions elsewhere
. authorizes dyndbg to >control user's class'd prdbgs
. DYNAMIC_DEBUG_CLASSMAP_USE() creates section records.
Now ddebug_add_module(etal) can handle classmap-uses similar to (and
after) classmaps; when a dependent module is loaded, if it has
classmap-uses (to a classmap-def in another module), that module's
kernel params are scanned to find if it has a kparam that is wired to
dyndbg's param-ops, and whose classmap is the one being ref'd.
To support this, theres a few data/header changes:
new struct ddebug_class_user
contains: user-module-name, &classmap-defn
it records drm-driver's use of a classmap in the section, allowing lookup
struct ddebug_info gets 2 new fields for the new sections:
class_users, num_class_users.
set by dynamic_debug_init() for builtins.
or by kernel/module/main:load_info() for loadable modules.
vmlinux.lds.h: new BOUNDED_SECTION for __dyndbg_class_users
dynamic_debug.c has 2 changes in ddebug_add_module(), ddebug_change():
ddebug_add_module()
called ddebug_attach_module_classes()
now calls ddebug_apply_class_maps() & ddebug_apply_class_users()
these both call ddebug_apply_params().
ddebug_apply_params(new fn):
It scans module's/builtin kernel-params, calls ddebug_match_apply_kparam
for each to find any params/sysfs-nodes which may be wired to a classmap.
ddebug_match_apply_kparam(new fn):
1st, it tests the kernel-param.ops is dyndbg's; this guarantees that
the attached arg is a struct ddebug_class_param, which has a ref to
the param's state, and to the classmap defining the param's handling.
2nd, it requires that the classmap ref'd by the kparam is the one
we're called for; modules can use many separate classmaps (as
test_dynamic_debug does).
Then apply the "parent" kparam's setting to the dependent module,
using ddebug_apply_class_bitmap().
ddebug_change(and callees) also gets adjustments:
ddebug_find_valid_class(): This does a search over the module's
classmaps, looking for the class FOO echo'd to >control. So now it
searches over __dyndbg_class_users[] after __dyndbg_classes[].
ddebug_class_name(): return class-names for defined AND used classes.
test_dynamic_debug.c, test_dynamic_debug_submod.c:
This demonstrates the 2 types of classmaps & sysfs-params, following
the 4-part recipe:
1. define an enum for the classmap: DRM.debug has DRM_UT_{CORE,KMS,...}
multiple classes must share 0-62 classid space.
2. DYNAMIC_DEBUG_CLASSMAP_DEFINE(.. DRM_UT_{CORE,KMS,...})
3. DYNAMIC_DEBUG_CLASSMAP_PARAM* (classmap)
4. DYNAMIC_DEBUG_CLASSMAP_USE()
by _submod only, skipping 2,3
Move all the enum declarations together, to better explain how they
share the 0..62 class-id space available to a module (non-overlapping
subranges).
reorg macros 2,3 by name. This gives a tabular format, making it easy
to see the pattern of repetition, and the points of change.
And extend the test to replicate the 2-module (parent & dependent)
scenario which caused the CONFIG_DRM_USE_DYNAMIC_DEBUG=y regression
seen in drm & drivers.
The _submod.c is a 2-line file: #define _SUBMOD, #include parent.
This gives identical complements of prdbgs in parent & _submod, and
thus identical print behavior when all of: >control, >params, and
parent->_submod propagation are working correctly.
It also puts all the parent/_submod declarations together in the same
source, with the new ifdef _SUBMOD block invoking DYNAMIC_DEBUG_CLASSMAP_USE
for the 2 test-interfaces. I think this is clearer.
These 2 modules are both tristate, allowing 3 super/sub combos: Y/Y,
Y/M, M/M (not N/Y, since this is disallowed by dependence).
Y/Y testing exposed a missing __align(8) in the _METADATA macro, which
M/M didn't see because the module-loader memory placement constrains
it instead.
Fixes: aad0214f3026 ("dyndbg: add DECLARE_DYNDBG_CLASSMAP macro")
cc: linux-doc@vger.kernel.org
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
v2 a. building 2 .ko's from 1 source file is weird; add a clear
comment at the top to justify it (basically cloning)
ln 138+ in commit-msg is insufficient.
b. retire "DYNDBG_" name shortening b4 adding _CLASSMAP_* macros.
c. s/dd_class/_ddebug_class/
d. s/\bddebug\b/_$1/g in header: chgs 1 struct and UNIQUE_ID bases
v1.9 - commit-msg tweaks
DRM:CHECK warnings on macros: add parens
extern DEFINEd _var, static classnames
change ddebug_class_user.user_mod_name to .mod_name
simplify ddebug_find_valid_class
improve vpr_cm_info msg format
wrap (base) in macro body
move __DYNDBG_CLASSMAP_CHECK above kdoc for DYNDBG_CLASSMAP_DEFINE
v1.8 - split drm parts to separate commits.
preserve DECLARE_DYNDBG_CLASSMAP to decouple DRM, no flag day.
fixup block comment
v1.7 - previous submission-blocking bug:
missing __align(8) in DYNAMIC_DEBUG_DECLARE_METADATA on
ddebug_class_user caused corrupt records, but only for builtin
modules; module loader code probably pinned allocations to the right
alignment naturally, hiding the bug for typical builds.
v6- get rid of WARN_ON_ONCE
v?- fix _var expanded 2x in macro
dyndbg:
This fn formerly returned the map which contained the class (thus
validating it), and as a side-effect set the class-id in an outvar.
But the caller didn't use the map (after checking its not null), only
the valid class-id. So simplify the fn to return the class-id of the
validated classname, or -ENOENT when the queried classname is not
found.
Convey more useful info in the debug-msg: print class-names[0,last],
and [base,+len] instead of the class-type printout, which is almost
always "type:DISJOINT_BITS". And drop ddebug_classmap_typenames,
which is now unused.
[root@v6 b0-dd]# modprobe test_dynamic_debug_submod
[ 18.864962] dyndbg: loaded classmap: test_dynamic_debug [16..24] V0..V7
[ 18.865046] dyndbg: found kp:p_level_num =0x0
[ 18.865048] dyndbg: mapped to: test_dynamic_debug [16..24] V0..V7
[ 18.865164] dyndbg: p_level_num: lvl:0 bits:0x0
[ 18.865217] dyndbg: loaded classmap: test_dynamic_debug [0..10] D2_CORE..D2_DRMRES
[ 18.865297] dyndbg: found kp:p_disjoint_bits =0x0
[ 18.865298] dyndbg: mapped to: test_dynamic_debug [0..10] D2_CORE..D2_DRMRES
[ 18.865424] dyndbg: p_disjoint_bits: classbits: 0x0
[ 18.865472] dyndbg: module:test_dynamic_debug attached 2 classmaps
[ 18.865533] dyndbg: 23 debug prints in module test_dynamic_debug
[ 18.866558] dyndbg: loaded classmap: test_dynamic_debug_submod [16..24] V0..V7
[ 18.866698] dyndbg: found kp:p_level_num =0x0
[ 18.866699] dyndbg: mapped to: test_dynamic_debug_submod [16..24] V0..V7
[ 18.866865] dyndbg: p_level_num: lvl:0 bits:0x0
[ 18.866926] dyndbg: loaded classmap: test_dynamic_debug_submod [0..10] D2_CORE..D2_DRMRES
[ 18.867026] dyndbg: found kp:p_disjoint_bits =0x0
[ 18.867027] dyndbg: mapped to: test_dynamic_debug_submod [0..10] D2_CORE..D2_DRMRES
[ 18.867193] dyndbg: p_disjoint_bits: classbits: 0x0
[ 18.867255] dyndbg: module:test_dynamic_debug_submod attached 2 classmap uses
[ 18.867351] dyndbg: 23 debug prints in module test_dynamic_debug_submod
fixup-test-submod
fixup-test
---
MAINTAINERS | 2 +-
include/asm-generic/vmlinux.lds.h | 1 +
include/linux/dynamic_debug.h | 107 +++++++++++++++++---
kernel/module/main.c | 3 +
lib/Kconfig.debug | 24 ++++-
lib/Makefile | 3 +
lib/dynamic_debug.c | 157 ++++++++++++++++++++++++------
lib/test_dynamic_debug.c | 132 ++++++++++++++++++-------
lib/test_dynamic_debug_submod.c | 14 +++
9 files changed, 354 insertions(+), 89 deletions(-)
create mode 100644 lib/test_dynamic_debug_submod.c
diff --git a/MAINTAINERS b/MAINTAINERS
index c9763412a508..f98aec07a46d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8136,7 +8136,7 @@ M: Jim Cromie <jim.cromie@gmail.com>
S: Maintained
F: include/linux/dynamic_debug.h
F: lib/dynamic_debug.c
-F: lib/test_dynamic_debug.c
+F: lib/test_dynamic_debug*.c
DYNAMIC INTERRUPT MODERATION
M: Tal Gilboa <talgi@nvidia.com>
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index f834ad1fb8c4..fa382caf2ae2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -367,6 +367,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
/* implement dynamic printk debug */ \
. = ALIGN(8); \
BOUNDED_SECTION_BY(__dyndbg_class_maps, ___dyndbg_class_maps) \
+ BOUNDED_SECTION_BY(__dyndbg_class_users, ___dyndbg_class_users) \
BOUNDED_SECTION_BY(__dyndbg_descriptors, ___dyndbg_descs) \
CODETAG_SECTIONS() \
LIKELY_PROFILE() \
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 9fb38d79216e..0e3e14ca4765 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -73,9 +73,28 @@ enum ddebug_class_map_type {
*/
};
-struct ddebug_class_map {
- struct module *mod;
- const char *mod_name; /* needed for builtins */
+/*
+ * dyndbg-classmaps are devised to support DRM.debug directly:
+ * 10 enum-vals: DRM_UT_* define the categories
+ * ~23 categorized *_dbg() macros, each passing a DRM_UT_* val as 1st arg
+ * 2 macros below them: drm_dev_dbg, __drm_dbg
+ * ~5000 calls to the categorized macros, across all of drivers/gpu/drm/
+ *
+ * When CONFIG_DRM_USE_DYNAMIC_DEBUG=y, the 2 low macros are redefined
+ * to invoke _dynamic_func_call_cls(). This compiles the category
+ * into each callsite's class_id field, where dyndbg can select on it
+ * and alter a callsite's patch-state, avoiding repeated __drm_debug
+ * checks.
+ *
+ * To make the callsites manageable from the >control file, authors
+ * provide a "classmap" of names to class_ids in use by the module(s),
+ * usually by stringifying the enum-vals. Modules with multiple
+ * classmaps must arrange to share the 0..62 class_id space.
+ */
+
+struct _ddebug_class_map {
+ const struct module *mod; /* NULL for builtins */
+ const char *mod_name;
const char **class_names;
const int length;
const int base; /* index of 1st .class_id, allows split/shared space */
@@ -83,16 +102,39 @@ struct ddebug_class_map {
};
/**
- * 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
+ * DYNAMIC_DEBUG_CLASSMAP_DEFINE - define debug classes used by a module.
+ * @_var: name of the classmap, exported for other modules coordinated use.
+ * @_mapty: enum ddebug_class_map_type: 0:DISJOINT - independent, 1:LEVEL - v2>v1
+ * @_base: reserve N classids starting at _base, to split 0..62 classid space
+ * @classes: names of the N classes.
+ *
+ * This tells dyndbg what class_ids the module is using: _base..+N, by
+ * mapping names onto them. This qualifies "class NAME" >controls on
+ * the defining module, ignoring unknown names.
+ */
+#define DYNAMIC_DEBUG_CLASSMAP_DEFINE(_var, _mapty, _base, ...) \
+ static const char *_var##_classnames[] = { __VA_ARGS__ }; \
+ extern struct _ddebug_class_map _var; \
+ struct _ddebug_class_map __aligned(8) __used \
+ __section("__dyndbg_class_maps") _var = { \
+ .mod = THIS_MODULE, \
+ .mod_name = KBUILD_MODNAME, \
+ .base = (_base), \
+ .map_type = (_mapty), \
+ .length = ARRAY_SIZE(_var##_classnames), \
+ .class_names = _var##_classnames, \
+ }; \
+ EXPORT_SYMBOL(_var)
+
+/*
+ * XXX: keep this until DRM adapts to use the DEFINE/USE api, it
+ * differs from DYNAMIC_DEBUG_CLASSMAP_DEFINE by the lack of the
+ * extern/EXPORT on the struct init, and cascading thinkos.
*/
#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 = { \
+ static struct _ddebug_class_map __aligned(8) __used \
+ __section("__dyndbg_class_maps") _var = { \
.mod = THIS_MODULE, \
.mod_name = KBUILD_MODNAME, \
.base = _base, \
@@ -101,31 +143,64 @@ struct ddebug_class_map {
.class_names = _var##_classnames, \
}
+struct _ddebug_class_user {
+ char *mod_name;
+ struct _ddebug_class_map *map;
+};
+
+/**
+ * DYNAMIC_DEBUG_CLASSMAP_USE - refer to a classmap, DEFINEd elsewhere.
+ * @_var: name of the exported classmap var
+ *
+ * This tells dyndbg that the module has prdbgs with classids defined
+ * in the named classmap. This qualifies "class NAME" >controls on
+ * the user module, ignoring unknown names.
+ */
+#define DYNAMIC_DEBUG_CLASSMAP_USE(_var) \
+ DYNAMIC_DEBUG_CLASSMAP_USE_(_var, __UNIQUE_ID(_ddebug_class_user))
+#define DYNAMIC_DEBUG_CLASSMAP_USE_(_var, _uname) \
+ extern struct _ddebug_class_map _var; \
+ static struct _ddebug_class_user __aligned(8) __used \
+ __section("__dyndbg_class_users") _uname = { \
+ .mod_name = KBUILD_MODNAME, \
+ .map = &(_var), \
+ }
+
/*
- * @_ddebug_info: gathers module/builtin dyndbg_* __sections together.
+ * @_ddebug_info: gathers module/builtin __dyndbg_<T> __sections
+ * together, each is a vector: a struct { <T> *addr, int len }.
+ *
* For builtins, it is used as a cursor, with the inner structs
- * marking sub-vectors of the builtin __sections in DATA.
+ * marking sub-vectors of the builtin __sections in DATA_DATA
*/
struct _ddebug_descs {
struct _ddebug *start;
int len;
} __packed;
+
struct _ddebug_class_maps {
- struct ddebug_class_map *start;
+ struct _ddebug_class_map *start;
int len;
} __packed;
+
+struct _ddebug_class_users {
+ struct _ddebug_class_user *start;
+ int len;
+} __packed;
+
struct _ddebug_info {
struct _ddebug_descs descs;
struct _ddebug_class_maps maps;
+ struct _ddebug_class_users users;
} __packed;
-struct ddebug_class_param {
+struct _ddebug_class_param {
union {
unsigned long *bits;
unsigned long *lvl;
};
char flags[8];
- const struct ddebug_class_map *map;
+ const struct _ddebug_class_map *map;
};
/*
@@ -217,7 +292,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
* (|_no_desc): former gets callsite descriptor as 1st arg (for prdbgs)
*/
#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \
- DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
+ DEFINE_DYNAMIC_DEBUG_METADATA_CLS((id), cls, fmt); \
if (DYNAMIC_DEBUG_BRANCH(id)) \
func(&id, ##__VA_ARGS__); \
} while (0)
diff --git a/kernel/module/main.c b/kernel/module/main.c
index b60f728e36ac..c203b0694f7e 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2627,6 +2627,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
mod->dyndbg_info.maps.start = section_objs(info, "__dyndbg_class_maps",
sizeof(*mod->dyndbg_info.maps.start),
&mod->dyndbg_info.maps.len);
+ mod->dyndbg_info.users.start = section_objs(info, "__dyndbg_class_users",
+ sizeof(*mod->dyndbg_info.users.start),
+ &mod->dyndbg_info.users.len);
#endif
return 0;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 35796c290ca3..91a75f724c1a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2905,12 +2905,26 @@ config TEST_STATIC_KEYS
If unsure, say N.
config TEST_DYNAMIC_DEBUG
- tristate "Test DYNAMIC_DEBUG"
- depends on DYNAMIC_DEBUG
+ tristate "Build test-dynamic-debug module"
+ depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
help
- This module registers a tracer callback to count enabled
- pr_debugs in a 'do_debugging' function, then alters their
- enablements, calls the function, and compares counts.
+ This module exercises/demonstrates dyndbg's classmap API, by
+ creating 2 classes: a DISJOINT classmap (supporting DRM.debug)
+ and a LEVELS/VERBOSE classmap (like verbose2 > verbose1).
+
+ If unsure, say N.
+
+config TEST_DYNAMIC_DEBUG_SUBMOD
+ tristate "Build test-dynamic-debug submodule"
+ default m
+ depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
+ depends on TEST_DYNAMIC_DEBUG
+ help
+ This sub-module uses a classmap defined and exported by the
+ parent module, recapitulating drm & driver's shared use of
+ drm.debug to control enabled debug-categories.
+ It is tristate, independent of parent, to allow testing all
+ proper combinations of parent=y/m submod=y/m.
If unsure, say N.
diff --git a/lib/Makefile b/lib/Makefile
index d5cfc7afbbb8..2c344138d990 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_TEST_SORT) += test_sort.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o
+obj-$(CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD) += test_dynamic_debug_submod.o
obj-$(CONFIG_TEST_PRINTF) += test_printf.o
obj-$(CONFIG_TEST_SCANF) += test_scanf.o
@@ -226,6 +227,8 @@ obj-$(CONFIG_ARCH_NEED_CMPXCHG_1_EMU) += cmpxchg-emu.o
obj-$(CONFIG_DYNAMIC_DEBUG_CORE) += dynamic_debug.o
#ensure exported functions have prototypes
CFLAGS_dynamic_debug.o := -DDYNAMIC_DEBUG_MODULE
+CFLAGS_test_dynamic_debug.o := -DDYNAMIC_DEBUG_MODULE
+CFLAGS_test_dynamic_debug_submod.o := -DDYNAMIC_DEBUG_MODULE
obj-$(CONFIG_SYMBOLIC_ERRNAME) += errname.o
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 5df9cc732290..aebafa1be06a 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -29,6 +29,7 @@
#include <linux/string_helpers.h>
#include <linux/uaccess.h>
#include <linux/dynamic_debug.h>
+
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/jump_label.h>
@@ -41,8 +42,10 @@
extern struct _ddebug __start___dyndbg_descs[];
extern struct _ddebug __stop___dyndbg_descs[];
-extern struct ddebug_class_map __start___dyndbg_class_maps[];
-extern struct ddebug_class_map __stop___dyndbg_class_maps[];
+extern struct _ddebug_class_map __start___dyndbg_class_maps[];
+extern struct _ddebug_class_map __stop___dyndbg_class_maps[];
+extern struct _ddebug_class_user __start___dyndbg_class_users[];
+extern struct _ddebug_class_user __stop___dyndbg_class_users[];
struct ddebug_table {
struct list_head link;
@@ -167,23 +170,28 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
_dt->info.users.len); \
})
-#define __outvar /* filled by callee */
-static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
- const char *class_string,
- __outvar int *class_id)
+static int ddebug_find_valid_class(struct ddebug_table const *dt, const char *class_string)
{
- struct ddebug_class_map *map;
+ struct _ddebug_class_map *map;
+ struct _ddebug_class_user *cli;
int i, idx;
for_subvec(i, map, &dt->info, maps) {
idx = match_string(map->class_names, map->length, class_string);
if (idx >= 0) {
- *class_id = idx + map->base;
- return map;
+ vpr_dt_info(dt, "good-class: %s.%s ", map->mod_name, class_string);
+ return idx + map->base;
}
}
- *class_id = -ENOENT;
- return NULL;
+ for_subvec(i, cli, &dt->info, users) {
+ idx = match_string(cli->map->class_names, cli->map->length, class_string);
+ if (idx >= 0) {
+ vpr_dt_info(dt, "class-ref: %s -> %s.%s ",
+ cli->mod_name, cli->map->mod_name, class_string);
+ return idx + cli->map->base;
+ }
+ }
+ return -ENOENT;
}
/*
@@ -192,16 +200,14 @@ 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 int ddebug_change(const struct ddebug_query *query,
- struct flag_settings *modifiers)
+static int ddebug_change(const struct ddebug_query *query, struct flag_settings *modifiers)
{
int i;
struct ddebug_table *dt;
unsigned int newflags;
unsigned int nfound = 0;
struct flagsbuf fbuf, nbuf;
- struct ddebug_class_map *map = NULL;
- int __outvar valid_class;
+ int valid_class;
/* search for matching ddebugs */
mutex_lock(&ddebug_lock);
@@ -213,8 +219,8 @@ static int ddebug_change(const struct ddebug_query *query,
continue;
if (query->class_string) {
- map = ddebug_find_valid_class(dt, query->class_string, &valid_class);
- if (!map)
+ valid_class = ddebug_find_valid_class(dt, query->class_string);
+ if (valid_class < 0)
continue;
} else {
/* constrain query, do not touch class'd callsites */
@@ -578,7 +584,7 @@ static int ddebug_exec_query(char *query_string, const char *modname)
/* handle multiple queries in query string, continue on error, return
last error or number of matching callsites. Module name is either
- in param (for boot arg) or perhaps in query string.
+ in the modname arg (for boot args) or perhaps in query string.
*/
static int ddebug_exec_queries(char *query, const char *modname)
{
@@ -615,14 +621,14 @@ static int ddebug_exec_queries(char *query, const char *modname)
}
/* apply a new class-param setting */
-static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
+static int ddebug_apply_class_bitmap(const struct _ddebug_class_param *dcp,
const unsigned long *new_bits,
const unsigned long old_bits,
const char *query_modname)
{
#define QUERY_SIZE 128
char query[QUERY_SIZE];
- const struct ddebug_class_map *map = dcp->map;
+ const struct _ddebug_class_map *map = dcp->map;
int matches = 0;
int bi, ct;
@@ -659,8 +665,8 @@ static int param_set_dyndbg_module_classes(const char *instr,
const struct kernel_param *kp,
const char *modnm)
{
- const struct ddebug_class_param *dcp = kp->arg;
- const struct ddebug_class_map *map = dcp->map;
+ const struct _ddebug_class_param *dcp = kp->arg;
+ const struct _ddebug_class_map *map = dcp->map;
unsigned long inrep, new_bits, old_bits;
int rc, totct = 0;
char *nl;
@@ -709,7 +715,7 @@ static int param_set_dyndbg_module_classes(const char *instr,
/**
* 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
+ * @kp: kp->arg has state: bits/lvl, classmap, map_type
*
* enable/disable all class'd pr_debugs in the classmap. For LEVEL
* map-types, enforce * relative levels by bitpos.
@@ -735,8 +741,8 @@ EXPORT_SYMBOL(param_set_dyndbg_classes);
*/
int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
{
- const struct ddebug_class_param *dcp = kp->arg;
- const struct ddebug_class_map *map = dcp->map;
+ const struct _ddebug_class_param *dcp = kp->arg;
+ const struct _ddebug_class_map *map = dcp->map;
switch (map->map_type) {
case DD_CLASS_TYPE_DISJOINT_BITS:
@@ -746,6 +752,7 @@ int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
default:
return -1;
}
+ return 0;
}
EXPORT_SYMBOL(param_get_dyndbg_classes);
@@ -1067,13 +1074,18 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
static const char *ddebug_class_name(struct ddebug_table *dt, struct _ddebug *dp)
{
- struct ddebug_class_map *map;
+ struct _ddebug_class_map *map;
+ struct _ddebug_class_user *cli;
int i;
for_subvec(i, map, &dt->info, maps)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
+ for_subvec(i, cli, &dt->info, users)
+ if (class_in_range(dp->class_id, cli->map))
+ return cli->map->class_names[dp->class_id - cli->map->base];
+
return NULL;
}
@@ -1154,9 +1166,85 @@ static const struct proc_ops proc_fops = {
.proc_write = ddebug_proc_write
};
-static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
+#define vpr_cm_info(cm_p, msg_fmt, ...) ({ \
+ struct _ddebug_class_map const *_cm = cm_p; \
+ v2pr_info(msg_fmt " %s [%d..%d] %s..%s\n", ##__VA_ARGS__, \
+ _cm->mod_name, _cm->base, _cm->base + _cm->length, \
+ _cm->class_names[0], _cm->class_names[_cm->length - 1]); \
+ })
+
+static void ddebug_sync_classbits(const struct kernel_param *kp, const char *modname)
+{
+ const struct _ddebug_class_param *dcp = kp->arg;
+
+ /* clamp initial bitvec, mask off hi-bits */
+ if (*dcp->bits & ~CLASSMAP_BITMASK(dcp->map->length)) {
+ *dcp->bits &= CLASSMAP_BITMASK(dcp->map->length);
+ v2pr_info("preset classbits: %lx\n", *dcp->bits);
+ }
+ /* force class'd prdbgs (in USEr module) to match (DEFINEr module) class-param */
+ ddebug_apply_class_bitmap(dcp, dcp->bits, ~0, modname);
+ ddebug_apply_class_bitmap(dcp, dcp->bits, 0, modname);
+}
+
+static void ddebug_match_apply_kparam(const struct kernel_param *kp,
+ const struct _ddebug_class_map *map,
+ const char *modnm)
{
- vpr_info("module:%s attached %d classes\n", dt->mod_name, dt->info.maps.len);
+ struct _ddebug_class_param *dcp;
+
+ if (kp->ops != ¶m_ops_dyndbg_classes)
+ return;
+
+ dcp = (struct _ddebug_class_param *)kp->arg;
+
+ if (map == dcp->map) {
+ v2pr_info(" kp:%s.%s =0x%lx", modnm, kp->name, *dcp->bits);
+ vpr_cm_info(map, " %s mapped to: ", modnm);
+ ddebug_sync_classbits(kp, modnm);
+ }
+}
+
+static void ddebug_apply_params(const struct _ddebug_class_map *cm, const char *modnm)
+{
+ const struct kernel_param *kp;
+#if IS_ENABLED(CONFIG_MODULES)
+ int i;
+
+ if (cm->mod) {
+ vpr_cm_info(cm, "loaded classmap: %s", modnm);
+ /* ifdef protects the cm->mod->kp deref */
+ for (i = 0, kp = cm->mod->kp; i < cm->mod->num_kp; i++, kp++)
+ ddebug_match_apply_kparam(kp, cm, modnm);
+ }
+#endif
+ if (!cm->mod) {
+ vpr_cm_info(cm, "builtin classmap: %s", modnm);
+ for (kp = __start___param; kp < __stop___param; kp++)
+ ddebug_match_apply_kparam(kp, cm, modnm);
+ }
+}
+
+static void ddebug_apply_class_maps(struct ddebug_table *dt)
+{
+ struct _ddebug_class_map *cm;
+ int i;
+
+ for_subvec(i, cm, &dt->info, maps)
+ ddebug_apply_params(cm, cm->mod_name);
+
+ vpr_dt_info(dt, "attached %d classmaps to module: %s ", i, cm->mod_name);
+}
+
+static void ddebug_apply_class_users(struct ddebug_table *dt)
+{
+ struct _ddebug_class_user *cli;
+ int i;
+
+ for_subvec(i, cli, &dt->info, users)
+ ddebug_apply_params(cli->map, cli->mod_name);
+
+ vpr_dt_info(dt, "attached %d class-users to module: %s ", i, cli->mod_name);
}
/*
@@ -1191,7 +1279,8 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
{
struct ddebug_table *dt;
- struct ddebug_class_map *cm;
+ struct _ddebug_class_map *cm;
+ struct _ddebug_class_user *cli;
int i;
if (!di->descs.len)
@@ -1221,14 +1310,18 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
* start,len of the vectors by mod_name, save to dt.
*/
dd_mark_vector_subrange(i, dt, cm, di, maps);
+ dd_mark_vector_subrange(i, dt, cli, di, users);
- if (di->maps.len)
- ddebug_attach_module_classes(dt, di);
+ if (dt->info.maps.len)
+ ddebug_apply_class_maps(dt);
mutex_lock(&ddebug_lock);
list_add_tail(&dt->link, &ddebug_tables);
mutex_unlock(&ddebug_lock);
+ if (dt->info.users.len)
+ ddebug_apply_class_users(dt);
+
vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
return 0;
}
@@ -1378,8 +1471,10 @@ static int __init dynamic_debug_init(void)
struct _ddebug_info di = {
.descs.start = __start___dyndbg_descs,
.maps.start = __start___dyndbg_class_maps,
+ .users.start = __start___dyndbg_class_users,
.descs.len = __stop___dyndbg_descs - __start___dyndbg_descs,
.maps.len = __stop___dyndbg_class_maps - __start___dyndbg_class_maps,
+ .users.len = __stop___dyndbg_class_users - __start___dyndbg_class_users,
};
#ifdef CONFIG_MODULES
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 74d183ebf3e0..1070107f74f1 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -6,11 +6,30 @@
* Jim Cromie <jim.cromie@gmail.com>
*/
-#define pr_fmt(fmt) "test_dd: " fmt
+/*
+ * This file is built 2x, also making test_dynamic_debug_submod.ko,
+ * whose 2-line src file #includes this file. This gives us a _submod
+ * clone with identical pr_debugs, without further maintenance.
+ *
+ * If things are working properly, they should operate identically
+ * when printed or adjusted by >control. This eases visual perusal of
+ * the logs, and simplifies testing, by easing the proper accounting
+ * of expectations.
+ *
+ * It also puts both halves of the subsystem _DEFINE & _USE use case
+ * together, and integrates the common ENUM providing both class_ids
+ * and class-names to both _DEFINErs and _USERs. I think this makes
+ * the usage clearer.
+ */
+#if defined(TEST_DYNAMIC_DEBUG_SUBMOD)
+ #define pr_fmt(fmt) "test_dd_submod: " fmt
+#else
+ #define pr_fmt(fmt) "test_dd: " fmt
+#endif
#include <linux/module.h>
-/* run tests by reading or writing sysfs node: do_prints */
+/* re-gen output by reading or writing sysfs node: do_prints */
static void do_prints(void); /* device under test */
static int param_set_do_prints(const char *instr, const struct kernel_param *kp)
@@ -29,24 +48,39 @@ static const struct kernel_param_ops param_ops_do_prints = {
};
module_param_cb(do_prints, ¶m_ops_do_prints, NULL, 0600);
-/*
- * Using the CLASSMAP api:
- * - classmaps must have corresponding enum
- * - enum symbols must match/correlate with class-name strings in the map.
- * - base must equal enum's 1st value
- * - multiple maps must set their base to share the 0-30 class_id space !!
- * (build-bug-on tips welcome)
- * Additionally, here:
- * - tie together sysname, mapname, bitsname, flagsname
- */
-#define DD_SYS_WRAP(_model, _flags) \
- static unsigned long bits_##_model; \
- static struct ddebug_class_param _flags##_model = { \
+#define CLASSMAP_BITMASK(width, base) (((1UL << (width)) - 1) << (base))
+
+/* sysfs param wrapper, proto-API */
+#define DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, _init) \
+ static unsigned long bits_##_model = _init; \
+ static struct _ddebug_class_param _flags##_##_model = { \
.bits = &bits_##_model, \
.flags = #_flags, \
.map = &map_##_model, \
}; \
- module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, &_flags##_model, 0600)
+ module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, \
+ &_flags##_##_model, 0600)
+#ifdef DEBUG
+#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
+ DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, ~0)
+#else
+#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
+ DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, 0)
+#endif
+
+/*
+ * Demonstrate/test DISJOINT & LEVEL typed classmaps with a sys-param.
+ *
+ * To comport with DRM debug-category (an int), classmaps map names to
+ * ids (also an int). So a classmap starts with an enum; DRM has enum
+ * debug_category: with DRM_UT_<CORE,DRIVER,KMS,etc>. We use the enum
+ * values as class-ids, and stringified enum-symbols as classnames.
+ *
+ * Modules with multiple CLASSMAPS must have enums with distinct
+ * value-ranges, as arranged below with explicit enum_sym = X inits.
+ * To clarify this sharing, declare the 2 enums now, for the 2
+ * different classmap types
+ */
/* numeric input, independent bits */
enum cat_disjoint_bits {
@@ -60,26 +94,51 @@ enum cat_disjoint_bits {
D2_LEASE,
D2_DP,
D2_DRMRES };
-DECLARE_DYNDBG_CLASSMAP(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "D2_CORE",
- "D2_DRIVER",
- "D2_KMS",
- "D2_PRIME",
- "D2_ATOMIC",
- "D2_VBL",
- "D2_STATE",
- "D2_LEASE",
- "D2_DP",
- "D2_DRMRES");
-DD_SYS_WRAP(disjoint_bits, p);
-DD_SYS_WRAP(disjoint_bits, T);
-
-/* numeric verbosity, V2 > V1 related */
-enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
-DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
- "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
-DD_SYS_WRAP(level_num, p);
-DD_SYS_WRAP(level_num, T);
+
+/* numeric verbosity, V2 > V1 related. V0 is > D2_DRM_RES */
+enum cat_level_num { V0 = 16, V1, V2, V3, V4, V5, V6, V7 };
+
+/* recapitulate DRM's multi-classmap setup */
+#if !defined(TEST_DYNAMIC_DEBUG_SUBMOD)
+/*
+ * In single user, or parent / coordinator (drm.ko) modules, define
+ * classmaps on the client enums above, and then declares the PARAMS
+ * ref'g the classmaps. Each is exported.
+ */
+DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
+ D2_CORE,
+ "D2_CORE",
+ "D2_DRIVER",
+ "D2_KMS",
+ "D2_PRIME",
+ "D2_ATOMIC",
+ "D2_VBL",
+ "D2_STATE",
+ "D2_LEASE",
+ "D2_DP",
+ "D2_DRMRES");
+
+DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
+ V0, "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
+
+/*
+ * now add the sysfs-params
+ */
+
+DYNAMIC_DEBUG_CLASSMAP_PARAM(disjoint_bits, p);
+DYNAMIC_DEBUG_CLASSMAP_PARAM(level_num, p);
+
+#else /* TEST_DYNAMIC_DEBUG_SUBMOD */
+
+/*
+ * in submod/drm-drivers, use the classmaps defined in top/parent
+ * module above.
+ */
+
+DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
+DYNAMIC_DEBUG_CLASSMAP_USE(map_level_num);
+
+#endif
/* stand-in for all pr_debug etc */
#define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
@@ -115,6 +174,7 @@ static void do_levels(void)
static void do_prints(void)
{
+ pr_debug("do_prints:\n");
do_cats();
do_levels();
}
diff --git a/lib/test_dynamic_debug_submod.c b/lib/test_dynamic_debug_submod.c
new file mode 100644
index 000000000000..672aabf40160
--- /dev/null
+++ b/lib/test_dynamic_debug_submod.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kernel module for testing dynamic_debug
+ *
+ * Authors:
+ * Jim Cromie <jim.cromie@gmail.com>
+ */
+
+/*
+ * clone the parent, inherit all the properties, for consistency and
+ * simpler accounting in test expectations.
+ */
+#define TEST_DYNAMIC_DEBUG_SUBMOD
+#include "test_dynamic_debug.c"
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 17/59] dyndbg-API: replace DECLARE_DYNDBG_CLASSMAP
2025-03-20 18:51 ` [PATCH v2 17/59] dyndbg-API: replace DECLARE_DYNDBG_CLASSMAP Jim Cromie
@ 2025-03-24 15:16 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:16 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala, linux-doc
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> DECLARE_DYNDBG_CLASSMAP() has a design error; its usage fails a basic
> K&R rule: "define once, refer many times".
>
> When DRM_USE_DYNAMIC_DEBUG=y, it is used across DRM core & drivers;
> each invocation allocates/inits the classmap understood by that
> module. All must match for the modules to respond together when
> DRM.debug categories are enabled. This is brittle; a maintenance
> foot-gun.
>
> Further, its culpable in the CONFIG_DRM_USE_DYNAMIC_DEBUG=Y
> regression; its use in both core & drivers obfuscates the 2 roles, that
> caused incomplete initialization when modprobing drivers:
>
> 1st drm.ko loads, and dyndbg initializes its DRM.debug callsites, then
> a drm-driver loads, but too late for the DRM.debug enablement.
>
> So retire it, replace with 2 macros:
> DYNAMIC_DEBUG_CLASSMAP_DEFINE - invoked once from core - drm.ko
> DYNAMIC_DEBUG_CLASSMAP_USE - from all drm drivers and helpers.
>
> DYNAMIC_DEBUG_CLASSMAP_DEFINE: this reworks DECLARE_DYNDBG_CLASSMAP,
> by dropping the static qualifier on the classmap, and exporting it
> instead.
>
> DYNAMIC_DEBUG_CLASSMAP_USE: then refers to the exported var by name:
> used from drivers, helper-mods
> lets us drop the repetitive "classname" declarations
> fixes 2nd-defn problem
> creates a ddebug_class_user record in new __dyndbg_class_users section
> new section is scanned "differently"
>
> DECLARE_DYNDBG_CLASSMAP is preserved temporarily, to decouple DRM
> adaptation work and avoid compile-errs before its done. IOW, DRM gets
> these fixes when they commit the adopt-new-api patches.
>
> The DEFINE,USE distinction, and the separate classmap-use record,
> allows dyndbg to initialize the driver's & helper's DRM.debug
> callsites separately after each is modprobed.
>
> Basically, the classmap init-scan is repeated for classmap-users.
>
> To review, dyndbg's existing __dyndbg_classes[] section does:
>
> . catalogs the module's classmaps
> . tells dyndbg about them, allowing >control
> . DYNAMIC_DEBUG_CLASSMAP_DEFINE creates section records.
> . we rename it to: __dyndbg_class_maps[]
>
> Then this patch adds __dyndbg_class_users[] section:
>
> . catalogs users of classmap definitions elsewhere
> . authorizes dyndbg to >control user's class'd prdbgs
> . DYNAMIC_DEBUG_CLASSMAP_USE() creates section records.
>
> Now ddebug_add_module(etal) can handle classmap-uses similar to (and
> after) classmaps; when a dependent module is loaded, if it has
> classmap-uses (to a classmap-def in another module), that module's
> kernel params are scanned to find if it has a kparam that is wired to
> dyndbg's param-ops, and whose classmap is the one being ref'd.
>
> To support this, theres a few data/header changes:
>
> new struct ddebug_class_user
> contains: user-module-name, &classmap-defn
> it records drm-driver's use of a classmap in the section, allowing lookup
>
> struct ddebug_info gets 2 new fields for the new sections:
> class_users, num_class_users.
> set by dynamic_debug_init() for builtins.
> or by kernel/module/main:load_info() for loadable modules.
>
> vmlinux.lds.h: new BOUNDED_SECTION for __dyndbg_class_users
>
> dynamic_debug.c has 2 changes in ddebug_add_module(), ddebug_change():
>
> ddebug_add_module()
> called ddebug_attach_module_classes()
> now calls ddebug_apply_class_maps() & ddebug_apply_class_users()
> these both call ddebug_apply_params().
>
> ddebug_apply_params(new fn):
>
> It scans module's/builtin kernel-params, calls ddebug_match_apply_kparam
> for each to find any params/sysfs-nodes which may be wired to a classmap.
>
> ddebug_match_apply_kparam(new fn):
>
> 1st, it tests the kernel-param.ops is dyndbg's; this guarantees that
> the attached arg is a struct ddebug_class_param, which has a ref to
> the param's state, and to the classmap defining the param's handling.
>
> 2nd, it requires that the classmap ref'd by the kparam is the one
> we're called for; modules can use many separate classmaps (as
> test_dynamic_debug does).
>
> Then apply the "parent" kparam's setting to the dependent module,
> using ddebug_apply_class_bitmap().
>
> ddebug_change(and callees) also gets adjustments:
>
> ddebug_find_valid_class(): This does a search over the module's
> classmaps, looking for the class FOO echo'd to >control. So now it
> searches over __dyndbg_class_users[] after __dyndbg_classes[].
>
> ddebug_class_name(): return class-names for defined AND used classes.
>
> test_dynamic_debug.c, test_dynamic_debug_submod.c:
>
> This demonstrates the 2 types of classmaps & sysfs-params, following
> the 4-part recipe:
>
> 1. define an enum for the classmap: DRM.debug has DRM_UT_{CORE,KMS,...}
> multiple classes must share 0-62 classid space.
> 2. DYNAMIC_DEBUG_CLASSMAP_DEFINE(.. DRM_UT_{CORE,KMS,...})
> 3. DYNAMIC_DEBUG_CLASSMAP_PARAM* (classmap)
> 4. DYNAMIC_DEBUG_CLASSMAP_USE()
> by _submod only, skipping 2,3
>
> Move all the enum declarations together, to better explain how they
> share the 0..62 class-id space available to a module (non-overlapping
> subranges).
>
> reorg macros 2,3 by name. This gives a tabular format, making it easy
> to see the pattern of repetition, and the points of change.
>
> And extend the test to replicate the 2-module (parent & dependent)
> scenario which caused the CONFIG_DRM_USE_DYNAMIC_DEBUG=y regression
> seen in drm & drivers.
>
> The _submod.c is a 2-line file: #define _SUBMOD, #include parent.
>
> This gives identical complements of prdbgs in parent & _submod, and
> thus identical print behavior when all of: >control, >params, and
> parent->_submod propagation are working correctly.
>
> It also puts all the parent/_submod declarations together in the same
> source, with the new ifdef _SUBMOD block invoking DYNAMIC_DEBUG_CLASSMAP_USE
> for the 2 test-interfaces. I think this is clearer.
>
> These 2 modules are both tristate, allowing 3 super/sub combos: Y/Y,
> Y/M, M/M (not N/Y, since this is disallowed by dependence).
>
> Y/Y testing exposed a missing __align(8) in the _METADATA macro, which
> M/M didn't see because the module-loader memory placement constrains
> it instead.
>
> Fixes: aad0214f3026 ("dyndbg: add DECLARE_DYNDBG_CLASSMAP macro")
> cc: linux-doc@vger.kernel.org
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
>
> v2 a. building 2 .ko's from 1 source file is weird; add a clear
> comment at the top to justify it (basically cloning)
> ln 138+ in commit-msg is insufficient.
>
> b. retire "DYNDBG_" name shortening b4 adding _CLASSMAP_* macros.
> c. s/dd_class/_ddebug_class/
> d. s/\bddebug\b/_$1/g in header: chgs 1 struct and UNIQUE_ID bases
>
> v1.9 - commit-msg tweaks
> DRM:CHECK warnings on macros: add parens
> extern DEFINEd _var, static classnames
> change ddebug_class_user.user_mod_name to .mod_name
> simplify ddebug_find_valid_class
> improve vpr_cm_info msg format
> wrap (base) in macro body
> move __DYNDBG_CLASSMAP_CHECK above kdoc for DYNDBG_CLASSMAP_DEFINE
>
> v1.8 - split drm parts to separate commits.
> preserve DECLARE_DYNDBG_CLASSMAP to decouple DRM, no flag day.
> fixup block comment
>
> v1.7 - previous submission-blocking bug:
>
> missing __align(8) in DYNAMIC_DEBUG_DECLARE_METADATA on
> ddebug_class_user caused corrupt records, but only for builtin
> modules; module loader code probably pinned allocations to the right
> alignment naturally, hiding the bug for typical builds.
>
> v6- get rid of WARN_ON_ONCE
> v?- fix _var expanded 2x in macro
>
> dyndbg:
>
> This fn formerly returned the map which contained the class (thus
> validating it), and as a side-effect set the class-id in an outvar.
>
> But the caller didn't use the map (after checking its not null), only
> the valid class-id. So simplify the fn to return the class-id of the
> validated classname, or -ENOENT when the queried classname is not
> found.
>
> Convey more useful info in the debug-msg: print class-names[0,last],
> and [base,+len] instead of the class-type printout, which is almost
> always "type:DISJOINT_BITS". And drop ddebug_classmap_typenames,
> which is now unused.
>
> [root@v6 b0-dd]# modprobe test_dynamic_debug_submod
> [ 18.864962] dyndbg: loaded classmap: test_dynamic_debug [16..24] V0..V7
> [ 18.865046] dyndbg: found kp:p_level_num =0x0
> [ 18.865048] dyndbg: mapped to: test_dynamic_debug [16..24] V0..V7
> [ 18.865164] dyndbg: p_level_num: lvl:0 bits:0x0
> [ 18.865217] dyndbg: loaded classmap: test_dynamic_debug [0..10] D2_CORE..D2_DRMRES
> [ 18.865297] dyndbg: found kp:p_disjoint_bits =0x0
> [ 18.865298] dyndbg: mapped to: test_dynamic_debug [0..10] D2_CORE..D2_DRMRES
> [ 18.865424] dyndbg: p_disjoint_bits: classbits: 0x0
> [ 18.865472] dyndbg: module:test_dynamic_debug attached 2 classmaps
> [ 18.865533] dyndbg: 23 debug prints in module test_dynamic_debug
> [ 18.866558] dyndbg: loaded classmap: test_dynamic_debug_submod [16..24] V0..V7
> [ 18.866698] dyndbg: found kp:p_level_num =0x0
> [ 18.866699] dyndbg: mapped to: test_dynamic_debug_submod [16..24] V0..V7
> [ 18.866865] dyndbg: p_level_num: lvl:0 bits:0x0
> [ 18.866926] dyndbg: loaded classmap: test_dynamic_debug_submod [0..10] D2_CORE..D2_DRMRES
> [ 18.867026] dyndbg: found kp:p_disjoint_bits =0x0
> [ 18.867027] dyndbg: mapped to: test_dynamic_debug_submod [0..10] D2_CORE..D2_DRMRES
> [ 18.867193] dyndbg: p_disjoint_bits: classbits: 0x0
> [ 18.867255] dyndbg: module:test_dynamic_debug_submod attached 2 classmap uses
> [ 18.867351] dyndbg: 23 debug prints in module test_dynamic_debug_submod
>
> fixup-test-submod
>
> fixup-test
> ---
> MAINTAINERS | 2 +-
> include/asm-generic/vmlinux.lds.h | 1 +
> include/linux/dynamic_debug.h | 107 +++++++++++++++++---
> kernel/module/main.c | 3 +
> lib/Kconfig.debug | 24 ++++-
> lib/Makefile | 3 +
> lib/dynamic_debug.c | 157 ++++++++++++++++++++++++------
> lib/test_dynamic_debug.c | 132 ++++++++++++++++++-------
> lib/test_dynamic_debug_submod.c | 14 +++
> 9 files changed, 354 insertions(+), 89 deletions(-)
> create mode 100644 lib/test_dynamic_debug_submod.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c9763412a508..f98aec07a46d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8136,7 +8136,7 @@ M: Jim Cromie <jim.cromie@gmail.com>
> S: Maintained
> F: include/linux/dynamic_debug.h
> F: lib/dynamic_debug.c
> -F: lib/test_dynamic_debug.c
> +F: lib/test_dynamic_debug*.c
>
> DYNAMIC INTERRUPT MODERATION
> M: Tal Gilboa <talgi@nvidia.com>
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index f834ad1fb8c4..fa382caf2ae2 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -367,6 +367,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
> /* implement dynamic printk debug */ \
> . = ALIGN(8); \
> BOUNDED_SECTION_BY(__dyndbg_class_maps, ___dyndbg_class_maps) \
> + BOUNDED_SECTION_BY(__dyndbg_class_users, ___dyndbg_class_users) \
> BOUNDED_SECTION_BY(__dyndbg_descriptors, ___dyndbg_descs) \
> CODETAG_SECTIONS() \
> LIKELY_PROFILE() \
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index 9fb38d79216e..0e3e14ca4765 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -73,9 +73,28 @@ enum ddebug_class_map_type {
> */
> };
>
> -struct ddebug_class_map {
> - struct module *mod;
> - const char *mod_name; /* needed for builtins */
> +/*
> + * dyndbg-classmaps are devised to support DRM.debug directly:
> + * 10 enum-vals: DRM_UT_* define the categories
> + * ~23 categorized *_dbg() macros, each passing a DRM_UT_* val as 1st arg
> + * 2 macros below them: drm_dev_dbg, __drm_dbg
> + * ~5000 calls to the categorized macros, across all of drivers/gpu/drm/
> + *
> + * When CONFIG_DRM_USE_DYNAMIC_DEBUG=y, the 2 low macros are redefined
> + * to invoke _dynamic_func_call_cls(). This compiles the category
> + * into each callsite's class_id field, where dyndbg can select on it
> + * and alter a callsite's patch-state, avoiding repeated __drm_debug
> + * checks.
> + *
> + * To make the callsites manageable from the >control file, authors
> + * provide a "classmap" of names to class_ids in use by the module(s),
> + * usually by stringifying the enum-vals. Modules with multiple
> + * classmaps must arrange to share the 0..62 class_id space.
> + */
> +
> +struct _ddebug_class_map {
> + const struct module *mod; /* NULL for builtins */
> + const char *mod_name;
> const char **class_names;
> const int length;
> const int base; /* index of 1st .class_id, allows split/shared space */
> @@ -83,16 +102,39 @@ struct ddebug_class_map {
> };
>
> /**
> - * 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
> + * DYNAMIC_DEBUG_CLASSMAP_DEFINE - define debug classes used by a module.
> + * @_var: name of the classmap, exported for other modules coordinated use.
> + * @_mapty: enum ddebug_class_map_type: 0:DISJOINT - independent, 1:LEVEL - v2>v1
> + * @_base: reserve N classids starting at _base, to split 0..62 classid space
> + * @classes: names of the N classes.
> + *
> + * This tells dyndbg what class_ids the module is using: _base..+N, by
> + * mapping names onto them. This qualifies "class NAME" >controls on
> + * the defining module, ignoring unknown names.
> + */
> +#define DYNAMIC_DEBUG_CLASSMAP_DEFINE(_var, _mapty, _base, ...) \
> + static const char *_var##_classnames[] = { __VA_ARGS__ }; \
> + extern struct _ddebug_class_map _var; \
> + struct _ddebug_class_map __aligned(8) __used \
> + __section("__dyndbg_class_maps") _var = { \
> + .mod = THIS_MODULE, \
> + .mod_name = KBUILD_MODNAME, \
> + .base = (_base), \
> + .map_type = (_mapty), \
> + .length = ARRAY_SIZE(_var##_classnames), \
> + .class_names = _var##_classnames, \
> + }; \
> + EXPORT_SYMBOL(_var)
> +
> +/*
> + * XXX: keep this until DRM adapts to use the DEFINE/USE api, it
> + * differs from DYNAMIC_DEBUG_CLASSMAP_DEFINE by the lack of the
> + * extern/EXPORT on the struct init, and cascading thinkos.
> */
> #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 = { \
> + static struct _ddebug_class_map __aligned(8) __used \
> + __section("__dyndbg_class_maps") _var = { \
> .mod = THIS_MODULE, \
> .mod_name = KBUILD_MODNAME, \
> .base = _base, \
> @@ -101,31 +143,64 @@ struct ddebug_class_map {
> .class_names = _var##_classnames, \
> }
>
> +struct _ddebug_class_user {
> + char *mod_name;
> + struct _ddebug_class_map *map;
> +};
> +
> +/**
> + * DYNAMIC_DEBUG_CLASSMAP_USE - refer to a classmap, DEFINEd elsewhere.
> + * @_var: name of the exported classmap var
> + *
> + * This tells dyndbg that the module has prdbgs with classids defined
> + * in the named classmap. This qualifies "class NAME" >controls on
> + * the user module, ignoring unknown names.
> + */
> +#define DYNAMIC_DEBUG_CLASSMAP_USE(_var) \
> + DYNAMIC_DEBUG_CLASSMAP_USE_(_var, __UNIQUE_ID(_ddebug_class_user))
> +#define DYNAMIC_DEBUG_CLASSMAP_USE_(_var, _uname) \
> + extern struct _ddebug_class_map _var; \
> + static struct _ddebug_class_user __aligned(8) __used \
> + __section("__dyndbg_class_users") _uname = { \
> + .mod_name = KBUILD_MODNAME, \
> + .map = &(_var), \
> + }
> +
> /*
> - * @_ddebug_info: gathers module/builtin dyndbg_* __sections together.
> + * @_ddebug_info: gathers module/builtin __dyndbg_<T> __sections
> + * together, each is a vector: a struct { <T> *addr, int len }.
> + *
> * For builtins, it is used as a cursor, with the inner structs
> - * marking sub-vectors of the builtin __sections in DATA.
> + * marking sub-vectors of the builtin __sections in DATA_DATA
> */
> struct _ddebug_descs {
> struct _ddebug *start;
> int len;
> } __packed;
> +
> struct _ddebug_class_maps {
> - struct ddebug_class_map *start;
> + struct _ddebug_class_map *start;
> int len;
> } __packed;
> +
> +struct _ddebug_class_users {
> + struct _ddebug_class_user *start;
> + int len;
> +} __packed;
> +
> struct _ddebug_info {
> struct _ddebug_descs descs;
> struct _ddebug_class_maps maps;
> + struct _ddebug_class_users users;
> } __packed;
>
> -struct ddebug_class_param {
> +struct _ddebug_class_param {
> union {
> unsigned long *bits;
> unsigned long *lvl;
> };
> char flags[8];
> - const struct ddebug_class_map *map;
> + const struct _ddebug_class_map *map;
> };
>
> /*
> @@ -217,7 +292,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
> * (|_no_desc): former gets callsite descriptor as 1st arg (for prdbgs)
> */
> #define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \
> - DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
> + DEFINE_DYNAMIC_DEBUG_METADATA_CLS((id), cls, fmt); \
> if (DYNAMIC_DEBUG_BRANCH(id)) \
> func(&id, ##__VA_ARGS__); \
> } while (0)
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index b60f728e36ac..c203b0694f7e 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -2627,6 +2627,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
> mod->dyndbg_info.maps.start = section_objs(info, "__dyndbg_class_maps",
> sizeof(*mod->dyndbg_info.maps.start),
> &mod->dyndbg_info.maps.len);
> + mod->dyndbg_info.users.start = section_objs(info, "__dyndbg_class_users",
> + sizeof(*mod->dyndbg_info.users.start),
> + &mod->dyndbg_info.users.len);
> #endif
>
> return 0;
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 35796c290ca3..91a75f724c1a 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -2905,12 +2905,26 @@ config TEST_STATIC_KEYS
> If unsure, say N.
>
> config TEST_DYNAMIC_DEBUG
> - tristate "Test DYNAMIC_DEBUG"
> - depends on DYNAMIC_DEBUG
> + tristate "Build test-dynamic-debug module"
> + depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
> help
> - This module registers a tracer callback to count enabled
> - pr_debugs in a 'do_debugging' function, then alters their
> - enablements, calls the function, and compares counts.
> + This module exercises/demonstrates dyndbg's classmap API, by
> + creating 2 classes: a DISJOINT classmap (supporting DRM.debug)
> + and a LEVELS/VERBOSE classmap (like verbose2 > verbose1).
> +
> + If unsure, say N.
> +
> +config TEST_DYNAMIC_DEBUG_SUBMOD
> + tristate "Build test-dynamic-debug submodule"
> + default m
> + depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
> + depends on TEST_DYNAMIC_DEBUG
> + help
> + This sub-module uses a classmap defined and exported by the
> + parent module, recapitulating drm & driver's shared use of
> + drm.debug to control enabled debug-categories.
> + It is tristate, independent of parent, to allow testing all
> + proper combinations of parent=y/m submod=y/m.
>
> If unsure, say N.
>
> diff --git a/lib/Makefile b/lib/Makefile
> index d5cfc7afbbb8..2c344138d990 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -84,6 +84,7 @@ obj-$(CONFIG_TEST_SORT) += test_sort.o
> obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
> obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
> obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o
> +obj-$(CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD) += test_dynamic_debug_submod.o
> obj-$(CONFIG_TEST_PRINTF) += test_printf.o
> obj-$(CONFIG_TEST_SCANF) += test_scanf.o
>
> @@ -226,6 +227,8 @@ obj-$(CONFIG_ARCH_NEED_CMPXCHG_1_EMU) += cmpxchg-emu.o
> obj-$(CONFIG_DYNAMIC_DEBUG_CORE) += dynamic_debug.o
> #ensure exported functions have prototypes
> CFLAGS_dynamic_debug.o := -DDYNAMIC_DEBUG_MODULE
> +CFLAGS_test_dynamic_debug.o := -DDYNAMIC_DEBUG_MODULE
> +CFLAGS_test_dynamic_debug_submod.o := -DDYNAMIC_DEBUG_MODULE
>
> obj-$(CONFIG_SYMBOLIC_ERRNAME) += errname.o
>
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index 5df9cc732290..aebafa1be06a 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -29,6 +29,7 @@
> #include <linux/string_helpers.h>
> #include <linux/uaccess.h>
> #include <linux/dynamic_debug.h>
> +
> #include <linux/debugfs.h>
> #include <linux/slab.h>
> #include <linux/jump_label.h>
> @@ -41,8 +42,10 @@
>
> extern struct _ddebug __start___dyndbg_descs[];
> extern struct _ddebug __stop___dyndbg_descs[];
> -extern struct ddebug_class_map __start___dyndbg_class_maps[];
> -extern struct ddebug_class_map __stop___dyndbg_class_maps[];
> +extern struct _ddebug_class_map __start___dyndbg_class_maps[];
> +extern struct _ddebug_class_map __stop___dyndbg_class_maps[];
> +extern struct _ddebug_class_user __start___dyndbg_class_users[];
> +extern struct _ddebug_class_user __stop___dyndbg_class_users[];
>
> struct ddebug_table {
> struct list_head link;
> @@ -167,23 +170,28 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> _dt->info.users.len); \
> })
>
> -#define __outvar /* filled by callee */
> -static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table const *dt,
> - const char *class_string,
> - __outvar int *class_id)
> +static int ddebug_find_valid_class(struct ddebug_table const *dt, const char *class_string)
> {
> - struct ddebug_class_map *map;
> + struct _ddebug_class_map *map;
> + struct _ddebug_class_user *cli;
> int i, idx;
>
> for_subvec(i, map, &dt->info, maps) {
> idx = match_string(map->class_names, map->length, class_string);
> if (idx >= 0) {
> - *class_id = idx + map->base;
> - return map;
> + vpr_dt_info(dt, "good-class: %s.%s ", map->mod_name, class_string);
> + return idx + map->base;
> }
> }
> - *class_id = -ENOENT;
> - return NULL;
> + for_subvec(i, cli, &dt->info, users) {
> + idx = match_string(cli->map->class_names, cli->map->length, class_string);
> + if (idx >= 0) {
> + vpr_dt_info(dt, "class-ref: %s -> %s.%s ",
> + cli->mod_name, cli->map->mod_name, class_string);
> + return idx + cli->map->base;
> + }
> + }
> + return -ENOENT;
> }
>
> /*
> @@ -192,16 +200,14 @@ 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 int ddebug_change(const struct ddebug_query *query,
> - struct flag_settings *modifiers)
> +static int ddebug_change(const struct ddebug_query *query, struct flag_settings *modifiers)
> {
> int i;
> struct ddebug_table *dt;
> unsigned int newflags;
> unsigned int nfound = 0;
> struct flagsbuf fbuf, nbuf;
> - struct ddebug_class_map *map = NULL;
> - int __outvar valid_class;
> + int valid_class;
>
> /* search for matching ddebugs */
> mutex_lock(&ddebug_lock);
> @@ -213,8 +219,8 @@ static int ddebug_change(const struct ddebug_query *query,
> continue;
>
> if (query->class_string) {
> - map = ddebug_find_valid_class(dt, query->class_string, &valid_class);
> - if (!map)
> + valid_class = ddebug_find_valid_class(dt, query->class_string);
> + if (valid_class < 0)
> continue;
> } else {
> /* constrain query, do not touch class'd callsites */
> @@ -578,7 +584,7 @@ static int ddebug_exec_query(char *query_string, const char *modname)
>
> /* handle multiple queries in query string, continue on error, return
> last error or number of matching callsites. Module name is either
> - in param (for boot arg) or perhaps in query string.
> + in the modname arg (for boot args) or perhaps in query string.
> */
> static int ddebug_exec_queries(char *query, const char *modname)
> {
> @@ -615,14 +621,14 @@ static int ddebug_exec_queries(char *query, const char *modname)
> }
>
> /* apply a new class-param setting */
> -static int ddebug_apply_class_bitmap(const struct ddebug_class_param *dcp,
> +static int ddebug_apply_class_bitmap(const struct _ddebug_class_param *dcp,
> const unsigned long *new_bits,
> const unsigned long old_bits,
> const char *query_modname)
> {
> #define QUERY_SIZE 128
> char query[QUERY_SIZE];
> - const struct ddebug_class_map *map = dcp->map;
> + const struct _ddebug_class_map *map = dcp->map;
> int matches = 0;
> int bi, ct;
>
> @@ -659,8 +665,8 @@ static int param_set_dyndbg_module_classes(const char *instr,
> const struct kernel_param *kp,
> const char *modnm)
> {
> - const struct ddebug_class_param *dcp = kp->arg;
> - const struct ddebug_class_map *map = dcp->map;
> + const struct _ddebug_class_param *dcp = kp->arg;
> + const struct _ddebug_class_map *map = dcp->map;
> unsigned long inrep, new_bits, old_bits;
> int rc, totct = 0;
> char *nl;
> @@ -709,7 +715,7 @@ static int param_set_dyndbg_module_classes(const char *instr,
> /**
> * 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
> + * @kp: kp->arg has state: bits/lvl, classmap, map_type
> *
> * enable/disable all class'd pr_debugs in the classmap. For LEVEL
> * map-types, enforce * relative levels by bitpos.
> @@ -735,8 +741,8 @@ EXPORT_SYMBOL(param_set_dyndbg_classes);
> */
> int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
> {
> - const struct ddebug_class_param *dcp = kp->arg;
> - const struct ddebug_class_map *map = dcp->map;
> + const struct _ddebug_class_param *dcp = kp->arg;
> + const struct _ddebug_class_map *map = dcp->map;
>
> switch (map->map_type) {
> case DD_CLASS_TYPE_DISJOINT_BITS:
> @@ -746,6 +752,7 @@ int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp)
> default:
> return -1;
> }
> + return 0;
> }
> EXPORT_SYMBOL(param_get_dyndbg_classes);
>
> @@ -1067,13 +1074,18 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
>
> static const char *ddebug_class_name(struct ddebug_table *dt, struct _ddebug *dp)
> {
> - struct ddebug_class_map *map;
> + struct _ddebug_class_map *map;
> + struct _ddebug_class_user *cli;
> int i;
>
> for_subvec(i, map, &dt->info, maps)
> if (class_in_range(dp->class_id, map))
> return map->class_names[dp->class_id - map->base];
>
> + for_subvec(i, cli, &dt->info, users)
> + if (class_in_range(dp->class_id, cli->map))
> + return cli->map->class_names[dp->class_id - cli->map->base];
> +
> return NULL;
> }
>
> @@ -1154,9 +1166,85 @@ static const struct proc_ops proc_fops = {
> .proc_write = ddebug_proc_write
> };
>
> -static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug_info *di)
> +#define vpr_cm_info(cm_p, msg_fmt, ...) ({ \
> + struct _ddebug_class_map const *_cm = cm_p; \
> + v2pr_info(msg_fmt " %s [%d..%d] %s..%s\n", ##__VA_ARGS__, \
> + _cm->mod_name, _cm->base, _cm->base + _cm->length, \
> + _cm->class_names[0], _cm->class_names[_cm->length - 1]); \
> + })
> +
> +static void ddebug_sync_classbits(const struct kernel_param *kp, const char *modname)
> +{
> + const struct _ddebug_class_param *dcp = kp->arg;
> +
> + /* clamp initial bitvec, mask off hi-bits */
> + if (*dcp->bits & ~CLASSMAP_BITMASK(dcp->map->length)) {
> + *dcp->bits &= CLASSMAP_BITMASK(dcp->map->length);
> + v2pr_info("preset classbits: %lx\n", *dcp->bits);
> + }
> + /* force class'd prdbgs (in USEr module) to match (DEFINEr module) class-param */
> + ddebug_apply_class_bitmap(dcp, dcp->bits, ~0, modname);
> + ddebug_apply_class_bitmap(dcp, dcp->bits, 0, modname);
> +}
> +
> +static void ddebug_match_apply_kparam(const struct kernel_param *kp,
> + const struct _ddebug_class_map *map,
> + const char *modnm)
> {
> - vpr_info("module:%s attached %d classes\n", dt->mod_name, dt->info.maps.len);
> + struct _ddebug_class_param *dcp;
> +
> + if (kp->ops != ¶m_ops_dyndbg_classes)
> + return;
> +
> + dcp = (struct _ddebug_class_param *)kp->arg;
> +
> + if (map == dcp->map) {
> + v2pr_info(" kp:%s.%s =0x%lx", modnm, kp->name, *dcp->bits);
> + vpr_cm_info(map, " %s mapped to: ", modnm);
> + ddebug_sync_classbits(kp, modnm);
> + }
> +}
> +
> +static void ddebug_apply_params(const struct _ddebug_class_map *cm, const char *modnm)
> +{
> + const struct kernel_param *kp;
> +#if IS_ENABLED(CONFIG_MODULES)
> + int i;
> +
> + if (cm->mod) {
> + vpr_cm_info(cm, "loaded classmap: %s", modnm);
> + /* ifdef protects the cm->mod->kp deref */
> + for (i = 0, kp = cm->mod->kp; i < cm->mod->num_kp; i++, kp++)
> + ddebug_match_apply_kparam(kp, cm, modnm);
> + }
> +#endif
> + if (!cm->mod) {
> + vpr_cm_info(cm, "builtin classmap: %s", modnm);
> + for (kp = __start___param; kp < __stop___param; kp++)
> + ddebug_match_apply_kparam(kp, cm, modnm);
> + }
> +}
> +
> +static void ddebug_apply_class_maps(struct ddebug_table *dt)
> +{
> + struct _ddebug_class_map *cm;
> + int i;
> +
> + for_subvec(i, cm, &dt->info, maps)
> + ddebug_apply_params(cm, cm->mod_name);
> +
> + vpr_dt_info(dt, "attached %d classmaps to module: %s ", i, cm->mod_name);
> +}
> +
> +static void ddebug_apply_class_users(struct ddebug_table *dt)
> +{
> + struct _ddebug_class_user *cli;
> + int i;
> +
> + for_subvec(i, cli, &dt->info, users)
> + ddebug_apply_params(cli->map, cli->mod_name);
> +
> + vpr_dt_info(dt, "attached %d class-users to module: %s ", i, cli->mod_name);
> }
>
> /*
> @@ -1191,7 +1279,8 @@ static void ddebug_attach_module_classes(struct ddebug_table *dt, struct _ddebug
> static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> {
> struct ddebug_table *dt;
> - struct ddebug_class_map *cm;
> + struct _ddebug_class_map *cm;
> + struct _ddebug_class_user *cli;
> int i;
>
> if (!di->descs.len)
> @@ -1221,14 +1310,18 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> * start,len of the vectors by mod_name, save to dt.
> */
> dd_mark_vector_subrange(i, dt, cm, di, maps);
> + dd_mark_vector_subrange(i, dt, cli, di, users);
>
> - if (di->maps.len)
> - ddebug_attach_module_classes(dt, di);
> + if (dt->info.maps.len)
> + ddebug_apply_class_maps(dt);
>
> mutex_lock(&ddebug_lock);
> list_add_tail(&dt->link, &ddebug_tables);
> mutex_unlock(&ddebug_lock);
>
> + if (dt->info.users.len)
> + ddebug_apply_class_users(dt);
> +
> vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
> return 0;
> }
> @@ -1378,8 +1471,10 @@ static int __init dynamic_debug_init(void)
> struct _ddebug_info di = {
> .descs.start = __start___dyndbg_descs,
> .maps.start = __start___dyndbg_class_maps,
> + .users.start = __start___dyndbg_class_users,
> .descs.len = __stop___dyndbg_descs - __start___dyndbg_descs,
> .maps.len = __stop___dyndbg_class_maps - __start___dyndbg_class_maps,
> + .users.len = __stop___dyndbg_class_users - __start___dyndbg_class_users,
> };
>
> #ifdef CONFIG_MODULES
> diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
> index 74d183ebf3e0..1070107f74f1 100644
> --- a/lib/test_dynamic_debug.c
> +++ b/lib/test_dynamic_debug.c
> @@ -6,11 +6,30 @@
> * Jim Cromie <jim.cromie@gmail.com>
> */
>
> -#define pr_fmt(fmt) "test_dd: " fmt
> +/*
> + * This file is built 2x, also making test_dynamic_debug_submod.ko,
> + * whose 2-line src file #includes this file. This gives us a _submod
> + * clone with identical pr_debugs, without further maintenance.
> + *
> + * If things are working properly, they should operate identically
> + * when printed or adjusted by >control. This eases visual perusal of
> + * the logs, and simplifies testing, by easing the proper accounting
> + * of expectations.
> + *
> + * It also puts both halves of the subsystem _DEFINE & _USE use case
> + * together, and integrates the common ENUM providing both class_ids
> + * and class-names to both _DEFINErs and _USERs. I think this makes
> + * the usage clearer.
> + */
> +#if defined(TEST_DYNAMIC_DEBUG_SUBMOD)
> + #define pr_fmt(fmt) "test_dd_submod: " fmt
> +#else
> + #define pr_fmt(fmt) "test_dd: " fmt
> +#endif
>
> #include <linux/module.h>
>
> -/* run tests by reading or writing sysfs node: do_prints */
> +/* re-gen output by reading or writing sysfs node: do_prints */
>
> static void do_prints(void); /* device under test */
> static int param_set_do_prints(const char *instr, const struct kernel_param *kp)
> @@ -29,24 +48,39 @@ static const struct kernel_param_ops param_ops_do_prints = {
> };
> module_param_cb(do_prints, ¶m_ops_do_prints, NULL, 0600);
>
> -/*
> - * Using the CLASSMAP api:
> - * - classmaps must have corresponding enum
> - * - enum symbols must match/correlate with class-name strings in the map.
> - * - base must equal enum's 1st value
> - * - multiple maps must set their base to share the 0-30 class_id space !!
> - * (build-bug-on tips welcome)
> - * Additionally, here:
> - * - tie together sysname, mapname, bitsname, flagsname
> - */
> -#define DD_SYS_WRAP(_model, _flags) \
> - static unsigned long bits_##_model; \
> - static struct ddebug_class_param _flags##_model = { \
> +#define CLASSMAP_BITMASK(width, base) (((1UL << (width)) - 1) << (base))
> +
> +/* sysfs param wrapper, proto-API */
> +#define DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, _init) \
> + static unsigned long bits_##_model = _init; \
> + static struct _ddebug_class_param _flags##_##_model = { \
> .bits = &bits_##_model, \
> .flags = #_flags, \
> .map = &map_##_model, \
> }; \
> - module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, &_flags##_model, 0600)
> + module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, \
> + &_flags##_##_model, 0600)
> +#ifdef DEBUG
> +#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
> + DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, ~0)
> +#else
> +#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
> + DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, 0)
> +#endif
> +
> +/*
> + * Demonstrate/test DISJOINT & LEVEL typed classmaps with a sys-param.
> + *
> + * To comport with DRM debug-category (an int), classmaps map names to
> + * ids (also an int). So a classmap starts with an enum; DRM has enum
> + * debug_category: with DRM_UT_<CORE,DRIVER,KMS,etc>. We use the enum
> + * values as class-ids, and stringified enum-symbols as classnames.
> + *
> + * Modules with multiple CLASSMAPS must have enums with distinct
> + * value-ranges, as arranged below with explicit enum_sym = X inits.
> + * To clarify this sharing, declare the 2 enums now, for the 2
> + * different classmap types
> + */
>
> /* numeric input, independent bits */
> enum cat_disjoint_bits {
> @@ -60,26 +94,51 @@ enum cat_disjoint_bits {
> D2_LEASE,
> D2_DP,
> D2_DRMRES };
> -DECLARE_DYNDBG_CLASSMAP(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> - "D2_CORE",
> - "D2_DRIVER",
> - "D2_KMS",
> - "D2_PRIME",
> - "D2_ATOMIC",
> - "D2_VBL",
> - "D2_STATE",
> - "D2_LEASE",
> - "D2_DP",
> - "D2_DRMRES");
> -DD_SYS_WRAP(disjoint_bits, p);
> -DD_SYS_WRAP(disjoint_bits, T);
> -
> -/* numeric verbosity, V2 > V1 related */
> -enum cat_level_num { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
> -DECLARE_DYNDBG_CLASSMAP(map_level_num, DD_CLASS_TYPE_LEVEL_NUM, 14,
> - "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
> -DD_SYS_WRAP(level_num, p);
> -DD_SYS_WRAP(level_num, T);
> +
> +/* numeric verbosity, V2 > V1 related. V0 is > D2_DRM_RES */
s/D2_DRM_RES/D2_DRMRES/
> +enum cat_level_num { V0 = 16, V1, V2, V3, V4, V5, V6, V7 };
> +
> +/* recapitulate DRM's multi-classmap setup */
> +#if !defined(TEST_DYNAMIC_DEBUG_SUBMOD)
> +/*
> + * In single user, or parent / coordinator (drm.ko) modules, define
> + * classmaps on the client enums above, and then declares the PARAMS
> + * ref'g the classmaps. Each is exported.
> + */
> +DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
> + D2_CORE,
> + "D2_CORE",
> + "D2_DRIVER",
> + "D2_KMS",
> + "D2_PRIME",
> + "D2_ATOMIC",
> + "D2_VBL",
> + "D2_STATE",
> + "D2_LEASE",
> + "D2_DP",
> + "D2_DRMRES");
> +
> +DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
> + V0, "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
> +
> +/*
> + * now add the sysfs-params
> + */
> +
> +DYNAMIC_DEBUG_CLASSMAP_PARAM(disjoint_bits, p);
> +DYNAMIC_DEBUG_CLASSMAP_PARAM(level_num, p);
> +
> +#else /* TEST_DYNAMIC_DEBUG_SUBMOD */
> +
> +/*
> + * in submod/drm-drivers, use the classmaps defined in top/parent
> + * module above.
> + */
> +
> +DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
> +DYNAMIC_DEBUG_CLASSMAP_USE(map_level_num);
> +
> +#endif
>
> /* stand-in for all pr_debug etc */
> #define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
> @@ -115,6 +174,7 @@ static void do_levels(void)
>
> static void do_prints(void)
> {
> + pr_debug("do_prints:\n");
> do_cats();
> do_levels();
> }
> diff --git a/lib/test_dynamic_debug_submod.c b/lib/test_dynamic_debug_submod.c
> new file mode 100644
> index 000000000000..672aabf40160
> --- /dev/null
> +++ b/lib/test_dynamic_debug_submod.c
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Kernel module for testing dynamic_debug
> + *
> + * Authors:
> + * Jim Cromie <jim.cromie@gmail.com>
> + */
> +
> +/*
> + * clone the parent, inherit all the properties, for consistency and
> + * simpler accounting in test expectations.
> + */
> +#define TEST_DYNAMIC_DEBUG_SUBMOD
> +#include "test_dynamic_debug.c"
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 18/59] selftests-dyndbg: add tools/testing/selftests/dynamic_debug/*
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (16 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 17/59] dyndbg-API: replace DECLARE_DYNDBG_CLASSMAP Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 19/59] dyndbg: detect class_id reservation conflicts Jim Cromie
` (40 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Add a selftest script for dynamic-debug. The config requires
CONFIG_TEST_DYNAMIC_DEBUG=m and CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m,
which tacitly requires either CONFIG_DYNAMIC_DEBUG=y or
CONFIG_DYNAMIC_DEBUG_CORE=y
ATM this has just basic_tests(), which modify pr_debug() flags in the
builtin params module. This means they're available to manipulate and
observe the effects in "cat control".
This is backported from another feature branch; the support-fns (thx
Lukas) have unused features at the moment, they'll get used shortly.
The script enables simple virtme-ng testing:
[jimc@gandalf b0-ftrace]$ vrun_t
virtme-ng 1.32+115.g07b109d
doing: vng --name v6.14-rc4-60-gd5f48427de0c \
--user root -v -p 4 -a dynamic_debug.verbose=3 V=1 \
-- ../tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
virtme: waiting for virtiofsd to start
..
And add dynamic_debug to TARGETS, so `make run_tests` sees it properly
For the impatient, set TARGETS explicitly:
bash-5.2# make TARGETS=dynamic_debug run_tests
make[1]: ...
TAP version 13
1..1
[ 35.552922] dyndbg: read 3 bytes from userspace
[ 35.553099] dyndbg: query 0: "=_" mod:*
[ 35.553544] dyndbg: processed 1 queries, with 1778 matches, 0 errs
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Co-developed-by: Łukasz Bartosik <ukaszb@chromium.org>
Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
---
- check KCONFIG_CONFIG to avoid silly fails
Several tests are dependent upon config choices. Lets avoid failing
where that is noise.
The KCONFIG_CONFIG var exists to convey the config-file around. If
the var names a file, read it and extract the relevant CONFIG items,
and use them to skip the dependent tests, thus avoiding the fails that
would follow, and the disruption to whatever CI is running these
selftests.
If the envar doesn't name a config-file, ".config" is assumed.
CONFIG_DYNAMIC_DEBUG=y:
basic-tests() and comma-terminator-tests() test for the presence of
the builtin pr_debugs in module/main.c, which I deemed stable and
therefore safe to count. That said, the test fails if only
CONFIG_DYNAMIC_DEBUG_CORE=y is set. It could be rewritten to test
against test-dynamic-debug.ko, but that just trades one config
dependence for another.
CONFIG_TEST_DYNAMIC_DEBUG=m
As written, test_percent_splitting() modprobes test_dynamic_debug,
enables several classes, and count them. It could be re-written to
work for the builtin module also, but builtin test modules are not a
common or desirable build/config.
CONFIG_TEST_DYNAMIC_DEBUG=m && CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m
test_mod_submod() recaps the bug found in DRM-CI where drivers werent
enabled by drm.debug=<bits>. It modprobes both test_dynamic_debug &
test_dynamic_debug_submod, so it depends on a loadable modules config.
It could be rewritten to work in a builtin parent config; DRM=y is
common enough to be pertinent, but testing that config also wouldn't
really test anything more fully than all-loadable modules, since they
default together.
---
MAINTAINERS | 1 +
tools/testing/selftests/Makefile | 1 +
.../testing/selftests/dynamic_debug/Makefile | 9 +
tools/testing/selftests/dynamic_debug/config | 2 +
.../dynamic_debug/dyndbg_selftest.sh | 256 ++++++++++++++++++
5 files changed, 269 insertions(+)
create mode 100644 tools/testing/selftests/dynamic_debug/Makefile
create mode 100644 tools/testing/selftests/dynamic_debug/config
create mode 100755 tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
diff --git a/MAINTAINERS b/MAINTAINERS
index f98aec07a46d..46515c2f8550 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8137,6 +8137,7 @@ S: Maintained
F: include/linux/dynamic_debug.h
F: lib/dynamic_debug.c
F: lib/test_dynamic_debug*.c
+F: tools/testing/selftests/dynamic_debug/*
DYNAMIC INTERRUPT MODERATION
M: Tal Gilboa <talgi@nvidia.com>
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 8daac70c2f9d..b6a323c7f986 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -26,6 +26,7 @@ TARGETS += drivers/net/team
TARGETS += drivers/net/virtio_net
TARGETS += drivers/platform/x86/intel/ifs
TARGETS += dt
+TARGETS += dynamic_debug
TARGETS += efivarfs
TARGETS += exec
TARGETS += fchmodat2
diff --git a/tools/testing/selftests/dynamic_debug/Makefile b/tools/testing/selftests/dynamic_debug/Makefile
new file mode 100644
index 000000000000..6d06fa7f1040
--- /dev/null
+++ b/tools/testing/selftests/dynamic_debug/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# borrowed from Makefile for user memory selftests
+
+# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
+all:
+
+TEST_PROGS := dyndbg_selftest.sh
+
+include ../lib.mk
diff --git a/tools/testing/selftests/dynamic_debug/config b/tools/testing/selftests/dynamic_debug/config
new file mode 100644
index 000000000000..d080da571ac0
--- /dev/null
+++ b/tools/testing/selftests/dynamic_debug/config
@@ -0,0 +1,2 @@
+CONFIG_TEST_DYNAMIC_DEBUG=m
+CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m
diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
new file mode 100755
index 000000000000..68a9046405f2
--- /dev/null
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -0,0 +1,256 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+
+V=${V:=0} # invoke as V=1 $0 for global verbose
+RED="\033[0;31m"
+GREEN="\033[0;32m"
+YELLOW="\033[0;33m"
+BLUE="\033[0;34m"
+MAGENTA="\033[0;35m"
+CYAN="\033[0;36m"
+NC="\033[0;0m"
+error_msg=""
+
+[ -e /proc/dynamic_debug/control ] || {
+ echo -e "${RED}: this test requires CONFIG_DYNAMIC_DEBUG=y ${NC}"
+ exit 0 # nothing to test here, no good reason to fail.
+}
+
+# need info to avoid failures due to untestable configs
+
+[ -f "$KCONFIG_CONFIG" ] || KCONFIG_CONFIG=".config"
+if [ -f "$KCONFIG_CONFIG" ]; then
+ echo "# consulting KCONFIG_CONFIG: $KCONFIG_CONFIG"
+ grep -q "CONFIG_DYNAMIC_DEBUG=y" $KCONFIG_CONFIG ; LACK_DD_BUILTIN=$?
+ grep -q "CONFIG_TEST_DYNAMIC_DEBUG=m" $KCONFIG_CONFIG ; LACK_TMOD=$?
+ grep -q "CONFIG_TEST_DYNAMIC_DEBUG_SUBMOD=m" $KCONFIG_CONFIG ; LACK_TMOD_SUBMOD=$?
+ if [ $V -eq 1 ]; then
+ echo LACK_DD_BUILTIN: $LACK_DD_BUILTIN
+ echo LACK_TMOD: $LACK_TMOD
+ echo LACK_TMOD_SUBMOD: $LACK_TMOD_SUBMOD
+ fi
+else
+ LACK_DD_BUILTIN=0
+ LACK_TMOD=0
+ LACK_TMOD_SUBMOD=0
+fi
+
+function vx () {
+ echo $1 > /sys/module/dynamic_debug/parameters/verbose
+}
+
+function ddgrep () {
+ grep $1 /proc/dynamic_debug/control
+}
+
+function doprints () {
+ cat /sys/module/test_dynamic_debug/parameters/do_prints
+}
+
+function ddcmd () {
+ exp_exit_code=0
+ num_args=$#
+ if [ "${@:$#}" = "pass" ]; then
+ num_args=$#-1
+ elif [ "${@:$#}" = "fail" ]; then
+ num_args=$#-1
+ exp_exit_code=1
+ fi
+ args=${@:1:$num_args}
+ output=$((echo "$args" > /proc/dynamic_debug/control) 2>&1)
+ exit_code=$?
+ error_msg=$(echo $output | cut -d ":" -f 5 | sed -e 's/^[[:space:]]*//')
+ handle_exit_code $BASH_LINENO $FUNCNAME $exit_code $exp_exit_code
+}
+
+function handle_exit_code() {
+ local exp_exit_code=0
+ [ $# == 4 ] && exp_exit_code=$4
+ if [ $3 -ne $exp_exit_code ]; then
+ echo -e "${RED}: $BASH_SOURCE:$1 $2() expected to exit with code $exp_exit_code"
+ [ $3 == 1 ] && echo "Error: '$error_msg'"
+ exit
+ fi
+}
+
+# $1 - pattern to match, pattern in $1 is enclosed by spaces for a match ""\s$1\s"
+# $2 - number of times the pattern passed in $1 is expected to match
+# $3 - optional can be set either to "-r" or "-v"
+# "-r" means relaxed matching in this case pattern provided in $1 is passed
+# as is without enclosing it with spaces
+# "-v" prints matching lines
+# $4 - optional when $3 is set to "-r" then $4 can be used to pass "-v"
+function check_match_ct {
+ pattern="\s$1\s"
+ exp_cnt=0
+
+ [ "$3" == "-r" ] && pattern="$1"
+ let cnt=$(ddgrep "$pattern" | wc -l)
+ if [ $V -eq 1 ] || [ "$3" == "-v" ] || [ "$4" == "-v" ]; then
+ echo -ne "${BLUE}" && ddgrep $pattern && echo -ne "${NC}"
+ fi
+ [ $# -gt 1 ] && exp_cnt=$2
+ if [ $cnt -ne $exp_cnt ]; then
+ echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO check failed expected $exp_cnt on $1, got $cnt"
+ exit
+ else
+ echo ": $cnt matches on $1"
+ fi
+}
+
+# $1 - trace instance name
+# #2 - if > 0 then directory is expected to exist, if <= 0 then otherwise
+# $3 - "-v" for verbose
+function check_trace_instance_dir {
+ if [ -e /sys/kernel/tracing/instances/$1 ]; then
+ if [ "$3" == "-v" ] ; then
+ echo "ls -l /sys/kernel/tracing/instances/$1: "
+ ls -l /sys/kernel/tracing/instances/$1
+ fi
+ if [ $2 -le 0 ]; then
+ echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO error trace instance \
+ '/sys/kernel/tracing/instances/$1' does exist"
+ exit
+ fi
+ else
+ if [ $2 -gt 0 ]; then
+ echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO error trace instance \
+ '/sys/kernel/tracing/instances/$1' does not exist"
+ exit
+ fi
+ fi
+}
+
+function tmark {
+ echo $* > /sys/kernel/tracing/trace_marker
+}
+
+# $1 - trace instance name
+# $2 - line number
+# $3 - if > 0 then the instance is expected to be opened, otherwise
+# the instance is expected to be closed
+function check_trace_instance {
+ output=$(tail -n9 /proc/dynamic_debug/control | grep ": Opened trace instances" \
+ | xargs -n1 | grep $1)
+ if [ "$output" != $1 ] && [ $3 -gt 0 ]; then
+ echo -e "${RED}: $BASH_SOURCE:$2 trace instance $1 is not opened"
+ exit
+ fi
+ if [ "$output" == $1 ] && [ $3 -le 0 ]; then
+ echo -e "${RED}: $BASH_SOURCE:$2 trace instance $1 is not closed"
+ exit
+ fi
+}
+
+function is_trace_instance_opened {
+ check_trace_instance $1 $BASH_LINENO 1
+}
+
+function is_trace_instance_closed {
+ check_trace_instance $1 $BASH_LINENO 0
+}
+
+# $1 - trace instance directory to delete
+# $2 - if > 0 then directory is expected to be deleted successfully, if <= 0 then otherwise
+function del_trace_instance_dir() {
+ exp_exit_code=1
+ [ $2 -gt 0 ] && exp_exit_code=0
+ output=$((rmdir /sys/kernel/debug/tracing/instances/$1) 2>&1)
+ exit_code=$?
+ error_msg=$(echo $output | cut -d ":" -f 3 | sed -e 's/^[[:space:]]*//')
+ handle_exit_code $BASH_LINENO $FUNCNAME $exit_code $exp_exit_code
+}
+
+function error_log_ref {
+ # to show what I got
+ : echo "# error-log-ref: $1"
+ : echo cat \$2
+}
+
+function ifrmmod {
+ lsmod | grep $1 2>&1>/dev/null && rmmod $1
+}
+
+# $1 - text to search for
+function search_trace() {
+ search_trace_name 0 1 $1
+}
+
+# $1 - trace instance name, 0 for global event trace
+# $2 - line number counting from the bottom
+# $3 - text to search for
+function search_trace_name() {
+ if [ "$1" = "0" ]; then
+ buf=$(cat /sys/kernel/debug/tracing/trace)
+ line=$(tail -$2 /sys/kernel/debug/tracing/trace | head -1 | sed -e 's/^[[:space:]]*//')
+ else
+ buf=$(cat /sys/kernel/debug/tracing/instances/$1/trace)
+ line=$(tail -$2 /sys/kernel/debug/tracing/instances/$1/trace | head -1 | \
+ sed -e 's/^[[:space:]]*//')
+ fi
+ if [ $2 = 0 ]; then
+ # whole-buf check
+ output=$(echo $buf | grep "$3")
+ else
+ output=$(echo $line | grep "$3")
+ fi
+ if [ "$output" = "" ]; then
+ echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO search for '$3' failed \
+ in line '$line' or '$buf'"
+ exit
+ fi
+ if [ $V = 1 ]; then
+ echo -e "${MAGENTA}: search_trace_name in $1 found: \n$output \nin:${BLUE} $buf ${NC}"
+ fi
+}
+
+# $1 - error message to check
+function check_err_msg() {
+ if [ "$error_msg" != "$1" ]; then
+ echo -e "${RED}: $BASH_SOURCE:$BASH_LINENO error message '$error_msg' \
+ does not match with '$1'"
+ exit
+ fi
+}
+
+function basic_tests {
+ echo -e "${GREEN}# BASIC_TESTS ${NC}"
+ if [ $LACK_DD_BUILTIN -eq 1 ]; then
+ echo "SKIP"
+ return
+ fi
+ ddcmd =_ # zero everything
+ check_match_ct =p 0
+
+ # module params are builtin to handle boot args
+ check_match_ct '\[params\]' 4 -r
+ ddcmd module params +mpf
+ check_match_ct =pmf 4
+
+ # multi-cmd input, newline separated, with embedded comments
+ cat <<"EOF" > /proc/dynamic_debug/control
+ module params =_ # clear params
+ module params +mf # set flags
+ module params func parse_args +sl # other flags
+EOF
+ check_match_ct =mf 3
+ check_match_ct =mfsl 1
+ ddcmd =_
+}
+
+tests_list=(
+ basic_tests
+)
+
+# Run tests
+
+ifrmmod test_dynamic_debug_submod
+ifrmmod test_dynamic_debug
+
+for test in "${tests_list[@]}"
+do
+ $test
+ echo ""
+done
+echo -en "${GREEN}# Done on: "
+date
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 19/59] dyndbg: detect class_id reservation conflicts
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (17 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 18/59] selftests-dyndbg: add tools/testing/selftests/dynamic_debug/* Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:51 ` [PATCH v2 20/59] dyndbg: check DYNDBG_CLASSMAP_DEFINE args at compile-time Jim Cromie
` (39 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
If a module _DEFINEs + _USEs 2 or more classmaps, it must devise them
to share the per-module 0..62 class-id space; ie their respective
base,+length reservations cannot overlap.
To detect conflicts at modprobe, add ddebug_class_range_overlap(),
call it from ddebug_add_module(), and WARN and return -EINVAL when
they're detected.
test_dynamic_debug.c:
If built with -DFORCE_CLASSID_CONFLICT, the test-modules get 2 bad
DYNDBG_CLASS_DEFINE declarations, into parent and the _submod. These
conflict with one of the good ones in the parent (D2_CORE..etc),
causing the modprobe(s) to warn
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
---
lib/dynamic_debug.c | 33 +++++++++++++++++++++++++++++++--
lib/test_dynamic_debug.c | 8 ++++++++
2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index aebafa1be06a..e84b6677e94d 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1225,7 +1225,7 @@ static void ddebug_apply_params(const struct _ddebug_class_map *cm, const char *
}
}
-static void ddebug_apply_class_maps(struct ddebug_table *dt)
+static void ddebug_apply_class_maps(const struct ddebug_table *dt)
{
struct _ddebug_class_map *cm;
int i;
@@ -1236,7 +1236,7 @@ static void ddebug_apply_class_maps(struct ddebug_table *dt)
vpr_dt_info(dt, "attached %d classmaps to module: %s ", i, cm->mod_name);
}
-static void ddebug_apply_class_users(struct ddebug_table *dt)
+static void ddebug_apply_class_users(const struct ddebug_table *dt)
{
struct _ddebug_class_user *cli;
int i;
@@ -1272,6 +1272,22 @@ static void ddebug_apply_class_users(struct ddebug_table *dt)
(_dst)->info._vec.len = nc; \
})
+static int __maybe_unused
+ddebug_class_range_overlap(struct _ddebug_class_map *cm,
+ u64 *reserved_ids)
+{
+ u64 range = (((1ULL << cm->length) - 1) << cm->base);
+
+ if (range & *reserved_ids) {
+ pr_err("[%d..%d] on %s conflicts with %llx\n", cm->base,
+ cm->base + cm->length - 1, cm->class_names[0],
+ *reserved_ids);
+ return -EINVAL;
+ }
+ *reserved_ids |= range;
+ return 0;
+}
+
/*
* Allocate a new ddebug_table for the given module
* and add it to the global list.
@@ -1281,6 +1297,7 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
struct ddebug_table *dt;
struct _ddebug_class_map *cm;
struct _ddebug_class_user *cli;
+ u64 reserved_ids = 0;
int i;
if (!di->descs.len)
@@ -1312,6 +1329,13 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
dd_mark_vector_subrange(i, dt, cm, di, maps);
dd_mark_vector_subrange(i, dt, cli, di, users);
+ for_subvec(i, cm, &dt->info, maps)
+ if (ddebug_class_range_overlap(cm, &reserved_ids))
+ goto cleanup;
+ for_subvec(i, cli, &dt->info, users)
+ if (ddebug_class_range_overlap(cli->map, &reserved_ids))
+ goto cleanup;
+
if (dt->info.maps.len)
ddebug_apply_class_maps(dt);
@@ -1324,6 +1348,11 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
return 0;
+cleanup:
+ WARN_ONCE("dyndbg multi-classmap conflict in %s\n", modname);
+ kfree(dt);
+ return -EINVAL;
+
}
/* helper for ddebug_dyndbg_(boot|module)_param_cb */
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 1070107f74f1..e42916b08fd4 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -128,6 +128,14 @@ DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
DYNAMIC_DEBUG_CLASSMAP_PARAM(disjoint_bits, p);
DYNAMIC_DEBUG_CLASSMAP_PARAM(level_num, p);
+#ifdef FORCE_CLASSID_CONFLICT
+/*
+ * Enable with -Dflag on compile to test overlapping class-id range
+ * detection. This should warn on modprobes.
+ */
+DYNDBG_CLASSMAP_DEFINE(classid_range_conflict, 0, D2_CORE + 1, "D3_CORE");
+#endif
+
#else /* TEST_DYNAMIC_DEBUG_SUBMOD */
/*
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 20/59] dyndbg: check DYNDBG_CLASSMAP_DEFINE args at compile-time
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (18 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 19/59] dyndbg: detect class_id reservation conflicts Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-24 15:16 ` Louis Chauvet
2025-03-20 18:51 ` [PATCH v2 21/59] dyndbg-test: change do_prints testpoint to accept a loopct Jim Cromie
` (38 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Add __DYNDBG_CLASSMAP_CHECK to implement these arg-checks at compile:
0 <= _base < 63
class_names is not empty
class_names[0] is a string
(class_names.length + _base) < 63
These compile-time checks will prevent several misuses; 4 such
examples are added to test_dynamic_debug_submod.ko, and will fail
compilation if -DDD_MACRO_ARGCHECK is added to cflags. This wouldn't
be useful CONFIG_ item, since it breaks the build.
NB:
checkpatch complains incorrectly about do-while-0 here; its a strictly
file-scope macro, and do-whiles break there.
It should soften ERR to WARN and qualify advice wrt file-vs-fn scope,
& new-scope-declaratives exception (forex: _METADATA_)
The known exceptions by name/pattern works well (_METADATA_ is covered
by "struct"), this patch just wants static_assert added. On my list,
with above.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
- split static-asserts to __DYNDBG_CLASSMAP_CHECK
- move __DYNDBG_CLASSMAP_CHECK above kdoc for DYNDBG_CLASSMAP_DEFINE
silences kernel-doc warnings
---
include/linux/dynamic_debug.h | 9 +++++++++
lib/test_dynamic_debug.c | 11 +++++++++++
2 files changed, 20 insertions(+)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 0e3e14ca4765..da2d677947ee 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -101,6 +101,14 @@ struct _ddebug_class_map {
enum ddebug_class_map_type map_type;
};
+#define __DYNDBG_CLASSMAP_CHECK(_clnames, _base) \
+ static_assert(((_base) >= 0 && (_base) < _DPRINTK_CLASS_DFLT), \
+ "_base must be in 0..62"); \
+ static_assert(ARRAY_SIZE(_clnames) > 0, \
+ "classnames array size must be > 0"); \
+ static_assert((ARRAY_SIZE(_clnames) + (_base)) < _DPRINTK_CLASS_DFLT, \
+ "_base + classnames.length exceeds range")
+
/**
* DYNAMIC_DEBUG_CLASSMAP_DEFINE - define debug classes used by a module.
* @_var: name of the classmap, exported for other modules coordinated use.
@@ -114,6 +122,7 @@ struct _ddebug_class_map {
*/
#define DYNAMIC_DEBUG_CLASSMAP_DEFINE(_var, _mapty, _base, ...) \
static const char *_var##_classnames[] = { __VA_ARGS__ }; \
+ __DYNDBG_CLASSMAP_CHECK(_var##_classnames, (_base)); \
extern struct _ddebug_class_map _var; \
struct _ddebug_class_map __aligned(8) __used \
__section("__dyndbg_class_maps") _var = { \
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index e42916b08fd4..9f9e3fddd7e6 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -146,8 +146,19 @@ DYNDBG_CLASSMAP_DEFINE(classid_range_conflict, 0, D2_CORE + 1, "D3_CORE");
DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
DYNAMIC_DEBUG_CLASSMAP_USE(map_level_num);
+#if defined(DD_MACRO_ARGCHECK)
+/*
+ * Exersize compile-time arg-checks in DYNDBG_CLASSMAP_DEFINE.
+ * These will break compilation.
+ */
+DYNDBG_CLASSMAP_DEFINE(fail_base_neg, 0, -1, "NEGATIVE_BASE_ARG");
+DYNDBG_CLASSMAP_DEFINE(fail_base_big, 0, 100, "TOOBIG_BASE_ARG");
+DYNDBG_CLASSMAP_DEFINE(fail_str_type, 0, 0, 1 /* not a string */);
+DYNDBG_CLASSMAP_DEFINE(fail_emptyclass, 0, 0 /* ,empty */);
#endif
+#endif /* TEST_DYNAMIC_DEBUG_SUBMOD */
+
/* stand-in for all pr_debug etc */
#define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 20/59] dyndbg: check DYNDBG_CLASSMAP_DEFINE args at compile-time
2025-03-20 18:51 ` [PATCH v2 20/59] dyndbg: check DYNDBG_CLASSMAP_DEFINE args at compile-time Jim Cromie
@ 2025-03-24 15:16 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:16 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:51, Jim Cromie a écrit :
> Add __DYNDBG_CLASSMAP_CHECK to implement these arg-checks at compile:
> 0 <= _base < 63
> class_names is not empty
> class_names[0] is a string
> (class_names.length + _base) < 63
>
> These compile-time checks will prevent several misuses; 4 such
> examples are added to test_dynamic_debug_submod.ko, and will fail
> compilation if -DDD_MACRO_ARGCHECK is added to cflags. This wouldn't
> be useful CONFIG_ item, since it breaks the build.
>
> NB:
>
> checkpatch complains incorrectly about do-while-0 here; its a strictly
> file-scope macro, and do-whiles break there.
>
> It should soften ERR to WARN and qualify advice wrt file-vs-fn scope,
> & new-scope-declaratives exception (forex: _METADATA_)
>
> The known exceptions by name/pattern works well (_METADATA_ is covered
> by "struct"), this patch just wants static_assert added. On my list,
> with above.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Nice addition to avoid issues!
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> - split static-asserts to __DYNDBG_CLASSMAP_CHECK
> - move __DYNDBG_CLASSMAP_CHECK above kdoc for DYNDBG_CLASSMAP_DEFINE
> silences kernel-doc warnings
> ---
> include/linux/dynamic_debug.h | 9 +++++++++
> lib/test_dynamic_debug.c | 11 +++++++++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index 0e3e14ca4765..da2d677947ee 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -101,6 +101,14 @@ struct _ddebug_class_map {
> enum ddebug_class_map_type map_type;
> };
>
> +#define __DYNDBG_CLASSMAP_CHECK(_clnames, _base) \
> + static_assert(((_base) >= 0 && (_base) < _DPRINTK_CLASS_DFLT), \
> + "_base must be in 0..62"); \
> + static_assert(ARRAY_SIZE(_clnames) > 0, \
> + "classnames array size must be > 0"); \
> + static_assert((ARRAY_SIZE(_clnames) + (_base)) < _DPRINTK_CLASS_DFLT, \
> + "_base + classnames.length exceeds range")
> +
> /**
> * DYNAMIC_DEBUG_CLASSMAP_DEFINE - define debug classes used by a module.
> * @_var: name of the classmap, exported for other modules coordinated use.
> @@ -114,6 +122,7 @@ struct _ddebug_class_map {
> */
> #define DYNAMIC_DEBUG_CLASSMAP_DEFINE(_var, _mapty, _base, ...) \
> static const char *_var##_classnames[] = { __VA_ARGS__ }; \
> + __DYNDBG_CLASSMAP_CHECK(_var##_classnames, (_base)); \
> extern struct _ddebug_class_map _var; \
> struct _ddebug_class_map __aligned(8) __used \
> __section("__dyndbg_class_maps") _var = { \
> diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
> index e42916b08fd4..9f9e3fddd7e6 100644
> --- a/lib/test_dynamic_debug.c
> +++ b/lib/test_dynamic_debug.c
> @@ -146,8 +146,19 @@ DYNDBG_CLASSMAP_DEFINE(classid_range_conflict, 0, D2_CORE + 1, "D3_CORE");
> DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
> DYNAMIC_DEBUG_CLASSMAP_USE(map_level_num);
>
> +#if defined(DD_MACRO_ARGCHECK)
> +/*
> + * Exersize compile-time arg-checks in DYNDBG_CLASSMAP_DEFINE.
> + * These will break compilation.
> + */
> +DYNDBG_CLASSMAP_DEFINE(fail_base_neg, 0, -1, "NEGATIVE_BASE_ARG");
> +DYNDBG_CLASSMAP_DEFINE(fail_base_big, 0, 100, "TOOBIG_BASE_ARG");
> +DYNDBG_CLASSMAP_DEFINE(fail_str_type, 0, 0, 1 /* not a string */);
> +DYNDBG_CLASSMAP_DEFINE(fail_emptyclass, 0, 0 /* ,empty */);
> #endif
>
> +#endif /* TEST_DYNAMIC_DEBUG_SUBMOD */
> +
> /* stand-in for all pr_debug etc */
> #define prdbg(SYM) __pr_debug_cls(SYM, #SYM " msg\n")
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 21/59] dyndbg-test: change do_prints testpoint to accept a loopct
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (19 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 20/59] dyndbg: check DYNDBG_CLASSMAP_DEFINE args at compile-time Jim Cromie
@ 2025-03-20 18:51 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 22/59] dyndbg-API: promote DYNAMIC_DEBUG_CLASSMAP_PARAM to API Jim Cromie
` (37 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:51 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
echo 1000 > /sys/module/test_dynamic_debug/parameters/do_prints
This allows its use as a scriptable load generator, to generate
dynamic-prefix-emits for flag combinations vs undecorated messages.
This will make it easy to assess the cost of the prefixing.
Reading the ./do_prints node also prints messages (once) to the-log.
NB: the count is clamped to 10000, chosen to be notice able, but not
annoying, and not enough to accidentally flood the logs.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
lib/test_dynamic_debug.c | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 9f9e3fddd7e6..4a3d2612ef60 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -29,18 +29,30 @@
#include <linux/module.h>
-/* re-gen output by reading or writing sysfs node: do_prints */
-
-static void do_prints(void); /* device under test */
+/* re-trigger debug output by reading or writing sysfs node: do_prints */
+#define PRINT_CLAMP 10000
+static void do_prints(unsigned int); /* device under test */
static int param_set_do_prints(const char *instr, const struct kernel_param *kp)
{
- do_prints();
+ int rc;
+ unsigned int ct;
+
+ rc = kstrtouint(instr, 0, &ct);
+ if (rc) {
+ pr_err("expecting numeric input, using 1 instead\n");
+ ct = 1;
+ }
+ if (ct > PRINT_CLAMP) {
+ ct = PRINT_CLAMP;
+ pr_info("clamping print-count to %d\n", ct);
+ }
+ do_prints(ct);
return 0;
}
static int param_get_do_prints(char *buffer, const struct kernel_param *kp)
{
- do_prints();
- return scnprintf(buffer, PAGE_SIZE, "did do_prints\n");
+ do_prints(1);
+ return scnprintf(buffer, PAGE_SIZE, "did 1 do_prints\n");
}
static const struct kernel_param_ops param_ops_do_prints = {
.set = param_set_do_prints,
@@ -191,17 +203,20 @@ static void do_levels(void)
prdbg(V7);
}
-static void do_prints(void)
+static void do_prints(unsigned int ct)
{
- pr_debug("do_prints:\n");
- do_cats();
- do_levels();
+ /* maybe clamp this */
+ pr_debug("do-prints %d times:\n", ct);
+ for (; ct; ct--) {
+ do_cats();
+ do_levels();
+ }
}
static int __init test_dynamic_debug_init(void)
{
pr_debug("init start\n");
- do_prints();
+ do_prints(1);
pr_debug("init done\n");
return 0;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 22/59] dyndbg-API: promote DYNAMIC_DEBUG_CLASSMAP_PARAM to API
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (20 preceding siblings ...)
2025-03-20 18:51 ` [PATCH v2 21/59] dyndbg-test: change do_prints testpoint to accept a loopct Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:18 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 23/59] dyndbg: move .mod_name from/to structs ddebug_table/_ddebug_info Jim Cromie
` (36 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie, linux-doc
move the DYNAMIC_DEBUG_CLASSMAP_PARAM macro from test-dynamic-debug.c into
the header, and refine it, by distinguishing the 2 use cases:
1.DYNAMIC_DEBUG_CLASSMAP_PARAM_REF
for DRM, to pass in extern __drm_debug by name.
dyndbg keeps bits in it, so drm can still use it as before
2.DYNAMIC_DEBUG_CLASSMAP_PARAM
new user (test_dynamic_debug) doesn't need to share state,
decls a static long unsigned int to store the bitvec.
__DYNAMIC_DEBUG_CLASSMAP_PARAM
bottom layer - allocate,init a ddebug-class-param, module-param-cb.
Modify ddebug_sync_classbits() argtype deref inside the fn, to give
access to all kp members.
Also clean up and improve comments in test-code, and add
MODULE_DESCRIPTIONs.
cc: linux-doc@vger.kernel.org
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
-v9
- fixup drm-print.h add PARAM_REF forwarding macros
with DYNAMIC_DEBUG_CLASSMAP_PARAM_REF in the API, add DRM_ variant
---
include/linux/dynamic_debug.h | 38 +++++++++++++++++++++
lib/dynamic_debug.c | 60 ++++++++++++++++++++++-----------
lib/test_dynamic_debug.c | 47 ++++++++++----------------
lib/test_dynamic_debug_submod.c | 9 ++++-
4 files changed, 104 insertions(+), 50 deletions(-)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index da2d677947ee..03a83a83b621 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -212,6 +212,44 @@ struct _ddebug_class_param {
const struct _ddebug_class_map *map;
};
+/**
+ * DYNAMIC_DEBUG_CLASSMAP_PARAM - control a ddebug-classmap from a sys-param
+ * @_name: sysfs node name
+ * @_var: name of the classmap var defining the controlled classes/bits
+ * @_flags: flags to be toggled, typically just 'p'
+ *
+ * Creates a sysfs-param to control the classes defined by the
+ * exported classmap, with bits 0..N-1 mapped to the classes named.
+ * This version keeps class-state in a private long int.
+ */
+#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _var, _flags) \
+ static unsigned long _name##_bvec; \
+ __DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _name##_bvec, _var, _flags)
+
+/**
+ * DYNAMIC_DEBUG_CLASSMAP_PARAM_REF - wrap a classmap with a controlling sys-param
+ * @_name: sysfs node name
+ * @_bits: name of the module's unsigned long bit-vector, ex: __drm_debug
+ * @_var: name of the (exported) classmap var defining the classes/bits
+ * @_flags: flags to be toggled, typically just 'p'
+ *
+ * Creates a sysfs-param to control the classes defined by the
+ * exported clasmap, with bits 0..N-1 mapped to the classes named.
+ * This version keeps class-state in user @_bits. This lets drm check
+ * __drm_debug elsewhere too.
+ */
+#define DYNAMIC_DEBUG_CLASSMAP_PARAM_REF(_name, _bits, _var, _flags) \
+ __DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _bits, _var, _flags)
+
+#define __DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _bits, _var, _flags) \
+ static struct _ddebug_class_param _name##_##_flags = { \
+ .bits = &(_bits), \
+ .flags = #_flags, \
+ .map = &(_var), \
+ }; \
+ module_param_cb(_name, ¶m_ops_dyndbg_classes, \
+ &_name##_##_flags, 0600)
+
/*
* pr_debug() and friends are globally enabled or modules have selectively
* enabled them.
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e84b6677e94d..3c9fb8324ad6 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -661,6 +661,30 @@ static int ddebug_apply_class_bitmap(const struct _ddebug_class_param *dcp,
#define CLASSMAP_BITMASK(width) ((1UL << (width)) - 1)
+static void ddebug_class_param_clamp_input(unsigned long *inrep, const struct kernel_param *kp)
+{
+ const struct _ddebug_class_param *dcp = kp->arg;
+ const struct _ddebug_class_map *map = dcp->map;
+
+ switch (map->map_type) {
+ case DD_CLASS_TYPE_DISJOINT_BITS:
+ /* expect bits. mask and warn if too many */
+ if (*inrep & ~CLASSMAP_BITMASK(map->length)) {
+ pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, masking\n",
+ KP_NAME(kp), *inrep, CLASSMAP_BITMASK(map->length));
+ *inrep &= CLASSMAP_BITMASK(map->length);
+ }
+ break;
+ case DD_CLASS_TYPE_LEVEL_NUM:
+ /* input is bitpos, of highest verbosity to be enabled */
+ if (*inrep > map->length) {
+ pr_warn("%s: level:%ld exceeds max:%d, clamping\n",
+ KP_NAME(kp), *inrep, map->length);
+ *inrep = map->length;
+ }
+ break;
+ }
+}
static int param_set_dyndbg_module_classes(const char *instr,
const struct kernel_param *kp,
const char *modnm)
@@ -679,26 +703,15 @@ static int param_set_dyndbg_module_classes(const char *instr,
pr_err("expecting numeric input, not: %s > %s\n", instr, KP_NAME(kp));
return -EINVAL;
}
+ ddebug_class_param_clamp_input(&inrep, kp);
switch (map->map_type) {
case DD_CLASS_TYPE_DISJOINT_BITS:
- /* expect bits. mask and warn if too many */
- if (inrep & ~CLASSMAP_BITMASK(map->length)) {
- pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, masking\n",
- KP_NAME(kp), inrep, CLASSMAP_BITMASK(map->length));
- inrep &= CLASSMAP_BITMASK(map->length);
- }
v2pr_info("bits:0x%lx > %s.%s\n", inrep, modnm ?: "*", KP_NAME(kp));
totct += ddebug_apply_class_bitmap(dcp, &inrep, *dcp->bits, modnm);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
- /* input is bitpos, of highest verbosity to be enabled */
- if (inrep > map->length) {
- pr_warn("%s: level:%ld exceeds max:%d, clamping\n",
- KP_NAME(kp), inrep, map->length);
- inrep = map->length;
- }
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));
@@ -1176,15 +1189,24 @@ static const struct proc_ops proc_fops = {
static void ddebug_sync_classbits(const struct kernel_param *kp, const char *modname)
{
const struct _ddebug_class_param *dcp = kp->arg;
+ unsigned long new_bits;
- /* clamp initial bitvec, mask off hi-bits */
- if (*dcp->bits & ~CLASSMAP_BITMASK(dcp->map->length)) {
- *dcp->bits &= CLASSMAP_BITMASK(dcp->map->length);
- v2pr_info("preset classbits: %lx\n", *dcp->bits);
+ ddebug_class_param_clamp_input(dcp->bits, kp);
+
+ switch (dcp->map->map_type) {
+ case DD_CLASS_TYPE_DISJOINT_BITS:
+ v2pr_info(" %s: classbits: 0x%lx\n", KP_NAME(kp), *dcp->bits);
+ ddebug_apply_class_bitmap(dcp, dcp->bits, 0UL, modname);
+ break;
+ case DD_CLASS_TYPE_LEVEL_NUM:
+ new_bits = CLASSMAP_BITMASK(*dcp->lvl);
+ v2pr_info(" %s: lvl:%ld bits:0x%lx\n", KP_NAME(kp), *dcp->lvl, new_bits);
+ ddebug_apply_class_bitmap(dcp, &new_bits, 0UL, modname);
+ break;
+ default:
+ pr_err("bad map type %d\n", dcp->map->map_type);
+ return;
}
- /* force class'd prdbgs (in USEr module) to match (DEFINEr module) class-param */
- ddebug_apply_class_bitmap(dcp, dcp->bits, ~0, modname);
- ddebug_apply_class_bitmap(dcp, dcp->bits, 0, modname);
}
static void ddebug_match_apply_kparam(const struct kernel_param *kp,
diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index 4a3d2612ef60..78cf5420770a 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Kernel module for testing dynamic_debug
+ * Kernel module to test/demonstrate dynamic_debug features,
+ * particularly classmaps and their support for subsystems like DRM.
*
* Authors:
* Jim Cromie <jim.cromie@gmail.com>
@@ -62,24 +63,6 @@ module_param_cb(do_prints, ¶m_ops_do_prints, NULL, 0600);
#define CLASSMAP_BITMASK(width, base) (((1UL << (width)) - 1) << (base))
-/* sysfs param wrapper, proto-API */
-#define DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, _init) \
- static unsigned long bits_##_model = _init; \
- static struct _ddebug_class_param _flags##_##_model = { \
- .bits = &bits_##_model, \
- .flags = #_flags, \
- .map = &map_##_model, \
- }; \
- module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, \
- &_flags##_##_model, 0600)
-#ifdef DEBUG
-#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
- DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, ~0)
-#else
-#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
- DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, 0)
-#endif
-
/*
* Demonstrate/test DISJOINT & LEVEL typed classmaps with a sys-param.
*
@@ -110,12 +93,15 @@ enum cat_disjoint_bits {
/* numeric verbosity, V2 > V1 related. V0 is > D2_DRM_RES */
enum cat_level_num { V0 = 16, V1, V2, V3, V4, V5, V6, V7 };
-/* recapitulate DRM's multi-classmap setup */
+/*
+ * use/demonstrate multi-module-group classmaps, as for DRM
+ */
#if !defined(TEST_DYNAMIC_DEBUG_SUBMOD)
/*
- * In single user, or parent / coordinator (drm.ko) modules, define
- * classmaps on the client enums above, and then declares the PARAMS
- * ref'g the classmaps. Each is exported.
+ * For module-groups of 1+, define classmaps with names (stringified
+ * enum-symbols) copied from above. 1-to-1 mapping is recommended.
+ * The classmap is exported, so that other modules in the group can
+ * link to it and control their prdbgs.
*/
DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
D2_CORE,
@@ -134,11 +120,13 @@ DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
V0, "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
/*
- * now add the sysfs-params
+ * for use-cases that want it, provide a sysfs-param to set the
+ * classes in the classmap. It is at this interface where the
+ * "v3>v2" property is applied to DD_CLASS_TYPE_LEVEL_NUM inputs.
*/
-DYNAMIC_DEBUG_CLASSMAP_PARAM(disjoint_bits, p);
-DYNAMIC_DEBUG_CLASSMAP_PARAM(level_num, p);
+DYNAMIC_DEBUG_CLASSMAP_PARAM(p_disjoint_bits, map_disjoint_bits, p);
+DYNAMIC_DEBUG_CLASSMAP_PARAM(p_level_num, map_level_num, p);
#ifdef FORCE_CLASSID_CONFLICT
/*
@@ -149,12 +137,10 @@ DYNDBG_CLASSMAP_DEFINE(classid_range_conflict, 0, D2_CORE + 1, "D3_CORE");
#endif
#else /* TEST_DYNAMIC_DEBUG_SUBMOD */
-
/*
- * in submod/drm-drivers, use the classmaps defined in top/parent
- * module above.
+ * the +1 members of a multi-module group refer to the classmap
+ * DEFINEd (and exported) above.
*/
-
DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
DYNAMIC_DEBUG_CLASSMAP_USE(map_level_num);
@@ -229,6 +215,7 @@ static void __exit test_dynamic_debug_exit(void)
module_init(test_dynamic_debug_init);
module_exit(test_dynamic_debug_exit);
+MODULE_DESCRIPTION("test/demonstrate dynamic-debug features");
MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
MODULE_DESCRIPTION("Kernel module for testing dynamic_debug");
MODULE_LICENSE("GPL");
diff --git a/lib/test_dynamic_debug_submod.c b/lib/test_dynamic_debug_submod.c
index 672aabf40160..3adf3925fb86 100644
--- a/lib/test_dynamic_debug_submod.c
+++ b/lib/test_dynamic_debug_submod.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Kernel module for testing dynamic_debug
+ * Kernel module to test/demonstrate dynamic_debug features,
+ * particularly classmaps and their support for subsystems, like DRM,
+ * which defines its drm_debug classmap in drm module, and uses it in
+ * helpers & drivers.
*
* Authors:
* Jim Cromie <jim.cromie@gmail.com>
@@ -12,3 +15,7 @@
*/
#define TEST_DYNAMIC_DEBUG_SUBMOD
#include "test_dynamic_debug.c"
+
+MODULE_DESCRIPTION("test/demonstrate dynamic-debug subsystem support");
+MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
+MODULE_LICENSE("GPL");
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 22/59] dyndbg-API: promote DYNAMIC_DEBUG_CLASSMAP_PARAM to API
2025-03-20 18:52 ` [PATCH v2 22/59] dyndbg-API: promote DYNAMIC_DEBUG_CLASSMAP_PARAM to API Jim Cromie
@ 2025-03-24 15:18 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:18 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala, linux-doc
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> move the DYNAMIC_DEBUG_CLASSMAP_PARAM macro from test-dynamic-debug.c into
> the header, and refine it, by distinguishing the 2 use cases:
>
> 1.DYNAMIC_DEBUG_CLASSMAP_PARAM_REF
> for DRM, to pass in extern __drm_debug by name.
> dyndbg keeps bits in it, so drm can still use it as before
>
> 2.DYNAMIC_DEBUG_CLASSMAP_PARAM
> new user (test_dynamic_debug) doesn't need to share state,
> decls a static long unsigned int to store the bitvec.
>
> __DYNAMIC_DEBUG_CLASSMAP_PARAM
> bottom layer - allocate,init a ddebug-class-param, module-param-cb.
>
> Modify ddebug_sync_classbits() argtype deref inside the fn, to give
> access to all kp members.
>
> Also clean up and improve comments in test-code, and add
> MODULE_DESCRIPTIONs.
>
> cc: linux-doc@vger.kernel.org
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
>
> -v9
> - fixup drm-print.h add PARAM_REF forwarding macros
> with DYNAMIC_DEBUG_CLASSMAP_PARAM_REF in the API, add DRM_ variant
> ---
> include/linux/dynamic_debug.h | 38 +++++++++++++++++++++
> lib/dynamic_debug.c | 60 ++++++++++++++++++++++-----------
> lib/test_dynamic_debug.c | 47 ++++++++++----------------
> lib/test_dynamic_debug_submod.c | 9 ++++-
> 4 files changed, 104 insertions(+), 50 deletions(-)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index da2d677947ee..03a83a83b621 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -212,6 +212,44 @@ struct _ddebug_class_param {
> const struct _ddebug_class_map *map;
> };
>
> +/**
> + * DYNAMIC_DEBUG_CLASSMAP_PARAM - control a ddebug-classmap from a sys-param
> + * @_name: sysfs node name
> + * @_var: name of the classmap var defining the controlled classes/bits
> + * @_flags: flags to be toggled, typically just 'p'
> + *
> + * Creates a sysfs-param to control the classes defined by the
> + * exported classmap, with bits 0..N-1 mapped to the classes named.
> + * This version keeps class-state in a private long int.
> + */
> +#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _var, _flags) \
> + static unsigned long _name##_bvec; \
> + __DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _name##_bvec, _var, _flags)
> +
> +/**
> + * DYNAMIC_DEBUG_CLASSMAP_PARAM_REF - wrap a classmap with a controlling sys-param
> + * @_name: sysfs node name
> + * @_bits: name of the module's unsigned long bit-vector, ex: __drm_debug
> + * @_var: name of the (exported) classmap var defining the classes/bits
> + * @_flags: flags to be toggled, typically just 'p'
> + *
> + * Creates a sysfs-param to control the classes defined by the
> + * exported clasmap, with bits 0..N-1 mapped to the classes named.
> + * This version keeps class-state in user @_bits. This lets drm check
> + * __drm_debug elsewhere too.
> + */
> +#define DYNAMIC_DEBUG_CLASSMAP_PARAM_REF(_name, _bits, _var, _flags) \
> + __DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _bits, _var, _flags)
> +
> +#define __DYNAMIC_DEBUG_CLASSMAP_PARAM(_name, _bits, _var, _flags) \
> + static struct _ddebug_class_param _name##_##_flags = { \
> + .bits = &(_bits), \
> + .flags = #_flags, \
> + .map = &(_var), \
> + }; \
> + module_param_cb(_name, ¶m_ops_dyndbg_classes, \
> + &_name##_##_flags, 0600)
> +
> /*
> * pr_debug() and friends are globally enabled or modules have selectively
> * enabled them.
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index e84b6677e94d..3c9fb8324ad6 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -661,6 +661,30 @@ static int ddebug_apply_class_bitmap(const struct _ddebug_class_param *dcp,
>
> #define CLASSMAP_BITMASK(width) ((1UL << (width)) - 1)
>
> +static void ddebug_class_param_clamp_input(unsigned long *inrep, const struct kernel_param *kp)
> +{
> + const struct _ddebug_class_param *dcp = kp->arg;
> + const struct _ddebug_class_map *map = dcp->map;
> +
> + switch (map->map_type) {
> + case DD_CLASS_TYPE_DISJOINT_BITS:
> + /* expect bits. mask and warn if too many */
> + if (*inrep & ~CLASSMAP_BITMASK(map->length)) {
> + pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, masking\n",
> + KP_NAME(kp), *inrep, CLASSMAP_BITMASK(map->length));
> + *inrep &= CLASSMAP_BITMASK(map->length);
> + }
> + break;
> + case DD_CLASS_TYPE_LEVEL_NUM:
> + /* input is bitpos, of highest verbosity to be enabled */
> + if (*inrep > map->length) {
> + pr_warn("%s: level:%ld exceeds max:%d, clamping\n",
> + KP_NAME(kp), *inrep, map->length);
> + *inrep = map->length;
> + }
> + break;
> + }
> +}
> static int param_set_dyndbg_module_classes(const char *instr,
> const struct kernel_param *kp,
> const char *modnm)
> @@ -679,26 +703,15 @@ static int param_set_dyndbg_module_classes(const char *instr,
> pr_err("expecting numeric input, not: %s > %s\n", instr, KP_NAME(kp));
> return -EINVAL;
> }
> + ddebug_class_param_clamp_input(&inrep, kp);
>
> switch (map->map_type) {
> case DD_CLASS_TYPE_DISJOINT_BITS:
> - /* expect bits. mask and warn if too many */
> - if (inrep & ~CLASSMAP_BITMASK(map->length)) {
> - pr_warn("%s: input: 0x%lx exceeds mask: 0x%lx, masking\n",
> - KP_NAME(kp), inrep, CLASSMAP_BITMASK(map->length));
> - inrep &= CLASSMAP_BITMASK(map->length);
> - }
> v2pr_info("bits:0x%lx > %s.%s\n", inrep, modnm ?: "*", KP_NAME(kp));
> totct += ddebug_apply_class_bitmap(dcp, &inrep, *dcp->bits, modnm);
> *dcp->bits = inrep;
> break;
> case DD_CLASS_TYPE_LEVEL_NUM:
> - /* input is bitpos, of highest verbosity to be enabled */
> - if (inrep > map->length) {
> - pr_warn("%s: level:%ld exceeds max:%d, clamping\n",
> - KP_NAME(kp), inrep, map->length);
> - inrep = map->length;
> - }
> 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));
> @@ -1176,15 +1189,24 @@ static const struct proc_ops proc_fops = {
> static void ddebug_sync_classbits(const struct kernel_param *kp, const char *modname)
> {
> const struct _ddebug_class_param *dcp = kp->arg;
> + unsigned long new_bits;
>
> - /* clamp initial bitvec, mask off hi-bits */
> - if (*dcp->bits & ~CLASSMAP_BITMASK(dcp->map->length)) {
> - *dcp->bits &= CLASSMAP_BITMASK(dcp->map->length);
> - v2pr_info("preset classbits: %lx\n", *dcp->bits);
> + ddebug_class_param_clamp_input(dcp->bits, kp);
> +
> + switch (dcp->map->map_type) {
> + case DD_CLASS_TYPE_DISJOINT_BITS:
> + v2pr_info(" %s: classbits: 0x%lx\n", KP_NAME(kp), *dcp->bits);
> + ddebug_apply_class_bitmap(dcp, dcp->bits, 0UL, modname);
> + break;
> + case DD_CLASS_TYPE_LEVEL_NUM:
> + new_bits = CLASSMAP_BITMASK(*dcp->lvl);
> + v2pr_info(" %s: lvl:%ld bits:0x%lx\n", KP_NAME(kp), *dcp->lvl, new_bits);
> + ddebug_apply_class_bitmap(dcp, &new_bits, 0UL, modname);
> + break;
> + default:
> + pr_err("bad map type %d\n", dcp->map->map_type);
> + return;
> }
> - /* force class'd prdbgs (in USEr module) to match (DEFINEr module) class-param */
> - ddebug_apply_class_bitmap(dcp, dcp->bits, ~0, modname);
> - ddebug_apply_class_bitmap(dcp, dcp->bits, 0, modname);
> }
>
> static void ddebug_match_apply_kparam(const struct kernel_param *kp,
> diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
> index 4a3d2612ef60..78cf5420770a 100644
> --- a/lib/test_dynamic_debug.c
> +++ b/lib/test_dynamic_debug.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> - * Kernel module for testing dynamic_debug
> + * Kernel module to test/demonstrate dynamic_debug features,
> + * particularly classmaps and their support for subsystems like DRM.
> *
> * Authors:
> * Jim Cromie <jim.cromie@gmail.com>
> @@ -62,24 +63,6 @@ module_param_cb(do_prints, ¶m_ops_do_prints, NULL, 0600);
>
> #define CLASSMAP_BITMASK(width, base) (((1UL << (width)) - 1) << (base))
>
> -/* sysfs param wrapper, proto-API */
> -#define DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, _init) \
> - static unsigned long bits_##_model = _init; \
> - static struct _ddebug_class_param _flags##_##_model = { \
> - .bits = &bits_##_model, \
> - .flags = #_flags, \
> - .map = &map_##_model, \
> - }; \
> - module_param_cb(_flags##_##_model, ¶m_ops_dyndbg_classes, \
> - &_flags##_##_model, 0600)
> -#ifdef DEBUG
> -#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
> - DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, ~0)
> -#else
> -#define DYNAMIC_DEBUG_CLASSMAP_PARAM(_model, _flags) \
> - DYNAMIC_DEBUG_CLASSMAP_PARAM_(_model, _flags, 0)
> -#endif
> -
> /*
> * Demonstrate/test DISJOINT & LEVEL typed classmaps with a sys-param.
> *
> @@ -110,12 +93,15 @@ enum cat_disjoint_bits {
> /* numeric verbosity, V2 > V1 related. V0 is > D2_DRM_RES */
> enum cat_level_num { V0 = 16, V1, V2, V3, V4, V5, V6, V7 };
>
> -/* recapitulate DRM's multi-classmap setup */
> +/*
> + * use/demonstrate multi-module-group classmaps, as for DRM
> + */
> #if !defined(TEST_DYNAMIC_DEBUG_SUBMOD)
> /*
> - * In single user, or parent / coordinator (drm.ko) modules, define
> - * classmaps on the client enums above, and then declares the PARAMS
> - * ref'g the classmaps. Each is exported.
> + * For module-groups of 1+, define classmaps with names (stringified
> + * enum-symbols) copied from above. 1-to-1 mapping is recommended.
> + * The classmap is exported, so that other modules in the group can
> + * link to it and control their prdbgs.
> */
> DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_disjoint_bits, DD_CLASS_TYPE_DISJOINT_BITS,
> D2_CORE,
> @@ -134,11 +120,13 @@ DYNAMIC_DEBUG_CLASSMAP_DEFINE(map_level_num, DD_CLASS_TYPE_LEVEL_NUM,
> V0, "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
>
> /*
> - * now add the sysfs-params
> + * for use-cases that want it, provide a sysfs-param to set the
> + * classes in the classmap. It is at this interface where the
> + * "v3>v2" property is applied to DD_CLASS_TYPE_LEVEL_NUM inputs.
> */
>
> -DYNAMIC_DEBUG_CLASSMAP_PARAM(disjoint_bits, p);
> -DYNAMIC_DEBUG_CLASSMAP_PARAM(level_num, p);
> +DYNAMIC_DEBUG_CLASSMAP_PARAM(p_disjoint_bits, map_disjoint_bits, p);
> +DYNAMIC_DEBUG_CLASSMAP_PARAM(p_level_num, map_level_num, p);
>
> #ifdef FORCE_CLASSID_CONFLICT
> /*
> @@ -149,12 +137,10 @@ DYNDBG_CLASSMAP_DEFINE(classid_range_conflict, 0, D2_CORE + 1, "D3_CORE");
> #endif
>
> #else /* TEST_DYNAMIC_DEBUG_SUBMOD */
> -
> /*
> - * in submod/drm-drivers, use the classmaps defined in top/parent
> - * module above.
> + * the +1 members of a multi-module group refer to the classmap
> + * DEFINEd (and exported) above.
> */
> -
> DYNAMIC_DEBUG_CLASSMAP_USE(map_disjoint_bits);
> DYNAMIC_DEBUG_CLASSMAP_USE(map_level_num);
>
> @@ -229,6 +215,7 @@ static void __exit test_dynamic_debug_exit(void)
> module_init(test_dynamic_debug_init);
> module_exit(test_dynamic_debug_exit);
>
> +MODULE_DESCRIPTION("test/demonstrate dynamic-debug features");
I think this belongs to the patch introducing test_dynamic_debug_submod.c
> MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
> MODULE_DESCRIPTION("Kernel module for testing dynamic_debug");
> MODULE_LICENSE("GPL");
> diff --git a/lib/test_dynamic_debug_submod.c b/lib/test_dynamic_debug_submod.c
> index 672aabf40160..3adf3925fb86 100644
> --- a/lib/test_dynamic_debug_submod.c
> +++ b/lib/test_dynamic_debug_submod.c
> @@ -1,6 +1,9 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> - * Kernel module for testing dynamic_debug
> + * Kernel module to test/demonstrate dynamic_debug features,
> + * particularly classmaps and their support for subsystems, like DRM,
> + * which defines its drm_debug classmap in drm module, and uses it in
> + * helpers & drivers.
> *
> * Authors:
> * Jim Cromie <jim.cromie@gmail.com>
> @@ -12,3 +15,7 @@
> */
> #define TEST_DYNAMIC_DEBUG_SUBMOD
> #include "test_dynamic_debug.c"
> +
> +MODULE_DESCRIPTION("test/demonstrate dynamic-debug subsystem support");
> +MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
> +MODULE_LICENSE("GPL");
I think this belongs to the patch introducing test_dynamic_debug_submod.c
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 23/59] dyndbg: move .mod_name from/to structs ddebug_table/_ddebug_info
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (21 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 22/59] dyndbg-API: promote DYNAMIC_DEBUG_CLASSMAP_PARAM to API Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:19 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 24/59] dyndbg: treat comma as a token separator Jim Cromie
` (35 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
struct _ddebug_info already has almost all dyndbg's info for a module,
so finish the encapsulation. This puts the datum closer to where its
needed, improving the chance that we can obsolete the _ddebug.modame
field with a desc_modname(dp) accessor fn.
In static ddebug_add_module(&_ddebug_info_cursor..), force the
cursor-model by dropping the modname arg, and setting it explicitly
into the cursor before the 3 calls to it.
struct ddebug_table only uses .mod_name when applying >control
changes, and it has a _ddebug_info member anyway, so it keeps access
to the field, just with a different offset.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
include/linux/dynamic_debug.h | 1 +
lib/dynamic_debug.c | 41 ++++++++++++++++++-----------------
2 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 03a83a83b621..8043966a0fd6 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -198,6 +198,7 @@ struct _ddebug_class_users {
} __packed;
struct _ddebug_info {
+ const char *mod_name;
struct _ddebug_descs descs;
struct _ddebug_class_maps maps;
struct _ddebug_class_users users;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 3c9fb8324ad6..cd3eec5bb81c 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -49,7 +49,6 @@ extern struct _ddebug_class_user __stop___dyndbg_class_users[];
struct ddebug_table {
struct list_head link;
- const char *mod_name;
struct _ddebug_info info;
};
@@ -166,7 +165,7 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
#define vpr_dt_info(dt_p, msg_p, ...) ({ \
struct ddebug_table const *_dt = dt_p; \
v2pr_info(msg_p " module:%s nd:%d nc:%d nu:%d\n", ##__VA_ARGS__, \
- _dt->mod_name, _dt->info.descs.len, _dt->info.maps.len, \
+ _dt->info.mod_name, _dt->info.descs.len, _dt->info.maps.len, \
_dt->info.users.len); \
})
@@ -215,7 +214,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
/* match against the module name */
if (query->module &&
- !match_wildcard(query->module, dt->mod_name))
+ !match_wildcard(query->module, dt->info.mod_name))
continue;
if (query->class_string) {
@@ -283,7 +282,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
#endif
v4pr_info("changed %s:%d [%s]%s %s => %s\n",
trim_prefix(dp->filename), dp->lineno,
- dt->mod_name, dp->function,
+ dt->info.mod_name, dp->function,
ddebug_describe_flags(dp->flags, &fbuf),
ddebug_describe_flags(newflags, &nbuf));
dp->flags = newflags;
@@ -1123,7 +1122,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
seq_printf(m, "%s:%u [%s]%s =%s \"",
trim_prefix(dp->filename), dp->lineno,
- iter->table->mod_name, dp->function,
+ iter->table->info.mod_name, dp->function,
ddebug_describe_flags(dp->flags, &flags));
seq_escape_str(m, dp->format, ESCAPE_SPACE, "\t\r\n\"");
seq_putc(m, '"');
@@ -1283,7 +1282,7 @@ static void ddebug_apply_class_users(const struct ddebug_table *dt)
#define dd_mark_vector_subrange(_i, _dst, _sp, _box, _vec) ({ \
int nc = 0; \
for_subvec(_i, _sp, _box, _vec) { \
- if (!strcmp((_sp)->mod_name, (_dst)->mod_name)) { \
+ if (!strcmp((_sp)->mod_name, (_dst)->info.mod_name)) { \
if (!nc++) \
(_dst)->info._vec.start = (_sp); \
} else { \
@@ -1314,7 +1313,7 @@ ddebug_class_range_overlap(struct _ddebug_class_map *cm,
* Allocate a new ddebug_table for the given module
* and add it to the global list.
*/
-static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
+static int ddebug_add_module(struct _ddebug_info *di)
{
struct ddebug_table *dt;
struct _ddebug_class_map *cm;
@@ -1325,20 +1324,19 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
if (!di->descs.len)
return 0;
- v3pr_info("add-module: %s %d sites\n", modname, di->descs.len);
+ v3pr_info("add-module: %s %d sites\n", di->mod_name, di->descs.len);
dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL) {
- pr_err("error adding module: %s\n", modname);
+ pr_err("error adding module: %s\n", di->mod_name);
return -ENOMEM;
}
/*
- * For built-in modules, name lives in .rodata and is
- * immortal. For loaded modules, name points at the name[]
- * member of struct module, which lives at least as long as
- * this struct ddebug_table.
+ * For built-in modules, name (as supplied in di by its
+ * callers) lives in .rodata and is immortal. For loaded
+ * modules, name points at the name[] member of struct module,
+ * which lives at least as long as this struct ddebug_table.
*/
- dt->mod_name = modname;
dt->info = *di;
INIT_LIST_HEAD(&dt->link);
@@ -1368,10 +1366,10 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
if (dt->info.users.len)
ddebug_apply_class_users(dt);
- vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
+ vpr_info("%3u debug prints in module %s\n", di->descs.len, di->mod_name);
return 0;
cleanup:
- WARN_ONCE("dyndbg multi-classmap conflict in %s\n", modname);
+ WARN_ONCE("dyndbg multi-classmap conflict in %s\n", di->mod_name);
kfree(dt);
return -EINVAL;
@@ -1436,7 +1434,7 @@ static int ddebug_remove_module(const char *mod_name)
mutex_lock(&ddebug_lock);
list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
- if (dt->mod_name == mod_name) {
+ if (dt->info.mod_name == mod_name) {
ddebug_table_free(dt);
ret = 0;
break;
@@ -1456,7 +1454,8 @@ static int ddebug_module_notify(struct notifier_block *self, unsigned long val,
switch (val) {
case MODULE_STATE_COMING:
- ret = ddebug_add_module(&mod->dyndbg_info, mod->name);
+ mod->dyndbg_info.mod_name = mod->name;
+ ret = ddebug_add_module(&mod->dyndbg_info);
if (ret)
WARN(1, "Failed to allocate memory: dyndbg may not work properly.\n");
break;
@@ -1556,7 +1555,8 @@ static int __init dynamic_debug_init(void)
mod_ct++;
di.descs.len = mod_sites;
di.descs.start = iter_mod_start;
- ret = ddebug_add_module(&di, modname);
+ di.mod_name = modname;
+ ret = ddebug_add_module(&di);
if (ret)
goto out_err;
@@ -1567,7 +1567,8 @@ static int __init dynamic_debug_init(void)
}
di.descs.len = mod_sites;
di.descs.start = iter_mod_start;
- ret = ddebug_add_module(&di, modname);
+ di.mod_name = modname;
+ ret = ddebug_add_module(&di);
if (ret)
goto out_err;
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 23/59] dyndbg: move .mod_name from/to structs ddebug_table/_ddebug_info
2025-03-20 18:52 ` [PATCH v2 23/59] dyndbg: move .mod_name from/to structs ddebug_table/_ddebug_info Jim Cromie
@ 2025-03-24 15:19 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:19 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> struct _ddebug_info already has almost all dyndbg's info for a module,
> so finish the encapsulation. This puts the datum closer to where its
> needed, improving the chance that we can obsolete the _ddebug.modame
> field with a desc_modname(dp) accessor fn.
>
> In static ddebug_add_module(&_ddebug_info_cursor..), force the
> cursor-model by dropping the modname arg, and setting it explicitly
> into the cursor before the 3 calls to it.
>
> struct ddebug_table only uses .mod_name when applying >control
> changes, and it has a _ddebug_info member anyway, so it keeps access
> to the field, just with a different offset.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> include/linux/dynamic_debug.h | 1 +
> lib/dynamic_debug.c | 41 ++++++++++++++++++-----------------
> 2 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index 03a83a83b621..8043966a0fd6 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -198,6 +198,7 @@ struct _ddebug_class_users {
> } __packed;
>
> struct _ddebug_info {
> + const char *mod_name;
> struct _ddebug_descs descs;
> struct _ddebug_class_maps maps;
> struct _ddebug_class_users users;
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index 3c9fb8324ad6..cd3eec5bb81c 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -49,7 +49,6 @@ extern struct _ddebug_class_user __stop___dyndbg_class_users[];
>
> struct ddebug_table {
> struct list_head link;
> - const char *mod_name;
> struct _ddebug_info info;
> };
>
> @@ -166,7 +165,7 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
> #define vpr_dt_info(dt_p, msg_p, ...) ({ \
> struct ddebug_table const *_dt = dt_p; \
> v2pr_info(msg_p " module:%s nd:%d nc:%d nu:%d\n", ##__VA_ARGS__, \
> - _dt->mod_name, _dt->info.descs.len, _dt->info.maps.len, \
> + _dt->info.mod_name, _dt->info.descs.len, _dt->info.maps.len, \
> _dt->info.users.len); \
> })
>
> @@ -215,7 +214,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
>
> /* match against the module name */
> if (query->module &&
> - !match_wildcard(query->module, dt->mod_name))
> + !match_wildcard(query->module, dt->info.mod_name))
> continue;
>
> if (query->class_string) {
> @@ -283,7 +282,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
> #endif
> v4pr_info("changed %s:%d [%s]%s %s => %s\n",
> trim_prefix(dp->filename), dp->lineno,
> - dt->mod_name, dp->function,
> + dt->info.mod_name, dp->function,
> ddebug_describe_flags(dp->flags, &fbuf),
> ddebug_describe_flags(newflags, &nbuf));
> dp->flags = newflags;
> @@ -1123,7 +1122,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
>
> seq_printf(m, "%s:%u [%s]%s =%s \"",
> trim_prefix(dp->filename), dp->lineno,
> - iter->table->mod_name, dp->function,
> + iter->table->info.mod_name, dp->function,
> ddebug_describe_flags(dp->flags, &flags));
> seq_escape_str(m, dp->format, ESCAPE_SPACE, "\t\r\n\"");
> seq_putc(m, '"');
> @@ -1283,7 +1282,7 @@ static void ddebug_apply_class_users(const struct ddebug_table *dt)
> #define dd_mark_vector_subrange(_i, _dst, _sp, _box, _vec) ({ \
> int nc = 0; \
> for_subvec(_i, _sp, _box, _vec) { \
> - if (!strcmp((_sp)->mod_name, (_dst)->mod_name)) { \
> + if (!strcmp((_sp)->mod_name, (_dst)->info.mod_name)) { \
> if (!nc++) \
> (_dst)->info._vec.start = (_sp); \
> } else { \
> @@ -1314,7 +1313,7 @@ ddebug_class_range_overlap(struct _ddebug_class_map *cm,
> * Allocate a new ddebug_table for the given module
> * and add it to the global list.
> */
> -static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> +static int ddebug_add_module(struct _ddebug_info *di)
> {
> struct ddebug_table *dt;
> struct _ddebug_class_map *cm;
> @@ -1325,20 +1324,19 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> if (!di->descs.len)
> return 0;
>
> - v3pr_info("add-module: %s %d sites\n", modname, di->descs.len);
> + v3pr_info("add-module: %s %d sites\n", di->mod_name, di->descs.len);
>
> dt = kzalloc(sizeof(*dt), GFP_KERNEL);
> if (dt == NULL) {
> - pr_err("error adding module: %s\n", modname);
> + pr_err("error adding module: %s\n", di->mod_name);
> return -ENOMEM;
> }
> /*
> - * For built-in modules, name lives in .rodata and is
> - * immortal. For loaded modules, name points at the name[]
> - * member of struct module, which lives at least as long as
> - * this struct ddebug_table.
> + * For built-in modules, name (as supplied in di by its
> + * callers) lives in .rodata and is immortal. For loaded
> + * modules, name points at the name[] member of struct module,
> + * which lives at least as long as this struct ddebug_table.
> */
> - dt->mod_name = modname;
> dt->info = *di;
>
> INIT_LIST_HEAD(&dt->link);
> @@ -1368,10 +1366,10 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
> if (dt->info.users.len)
> ddebug_apply_class_users(dt);
>
> - vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
> + vpr_info("%3u debug prints in module %s\n", di->descs.len, di->mod_name);
> return 0;
> cleanup:
> - WARN_ONCE("dyndbg multi-classmap conflict in %s\n", modname);
> + WARN_ONCE("dyndbg multi-classmap conflict in %s\n", di->mod_name);
> kfree(dt);
> return -EINVAL;
>
> @@ -1436,7 +1434,7 @@ static int ddebug_remove_module(const char *mod_name)
>
> mutex_lock(&ddebug_lock);
> list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
> - if (dt->mod_name == mod_name) {
> + if (dt->info.mod_name == mod_name) {
> ddebug_table_free(dt);
> ret = 0;
> break;
> @@ -1456,7 +1454,8 @@ static int ddebug_module_notify(struct notifier_block *self, unsigned long val,
>
> switch (val) {
> case MODULE_STATE_COMING:
> - ret = ddebug_add_module(&mod->dyndbg_info, mod->name);
> + mod->dyndbg_info.mod_name = mod->name;
> + ret = ddebug_add_module(&mod->dyndbg_info);
> if (ret)
> WARN(1, "Failed to allocate memory: dyndbg may not work properly.\n");
> break;
> @@ -1556,7 +1555,8 @@ static int __init dynamic_debug_init(void)
> mod_ct++;
> di.descs.len = mod_sites;
> di.descs.start = iter_mod_start;
> - ret = ddebug_add_module(&di, modname);
> + di.mod_name = modname;
> + ret = ddebug_add_module(&di);
> if (ret)
> goto out_err;
>
> @@ -1567,7 +1567,8 @@ static int __init dynamic_debug_init(void)
> }
> di.descs.len = mod_sites;
> di.descs.start = iter_mod_start;
> - ret = ddebug_add_module(&di, modname);
> + di.mod_name = modname;
> + ret = ddebug_add_module(&di);
> if (ret)
> goto out_err;
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 24/59] dyndbg: treat comma as a token separator
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (22 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 23/59] dyndbg: move .mod_name from/to structs ddebug_table/_ddebug_info Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:18 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 25/59] selftests-dyndbg: add comma_terminator_tests Jim Cromie
` (34 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Treat comma as a token terminator, just like a space. This allows a
user to avoid quoting hassles when spaces are otherwise needed:
:#> modprobe drm dyndbg=class,DRM_UT_CORE,+p\;class,DRM_UT_KMS,+p
or as a boot arg:
drm.dyndbg=class,DRM_UT_CORE,+p # todo: support multi-query here
Given the many ways a boot-line +args can be assembled and then passed
in/down/around shell based tools, this may allow side-stepping all
sorts of quoting hassles thru those layers.
existing query format:
modprobe test_dynamic_debug dyndbg="class D2_CORE +p"
new format:
modprobe test_dynamic_debug dyndbg=class,D2_CORE,+p
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Co-developed-by: Łukasz Bartosik <ukaszb@chromium.org>
Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
---
lib/dynamic_debug.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index cd3eec5bb81c..168663629ef2 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -293,6 +293,14 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
return nfound;
}
+static char *skip_spaces_and_commas(const char *str)
+{
+ str = skip_spaces(str);
+ while (*str == ',')
+ str = skip_spaces(++str);
+ return (char *)str;
+}
+
/*
* Split the buffer `buf' into space-separated words.
* Handles simple " and ' quoting, i.e. without nested,
@@ -306,8 +314,8 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
while (*buf) {
char *end;
- /* Skip leading whitespace */
- buf = skip_spaces(buf);
+ /* Skip leading whitespace and comma */
+ buf = skip_spaces_and_commas(buf);
if (!*buf)
break; /* oh, it was trailing whitespace */
if (*buf == '#')
@@ -323,7 +331,7 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
return -EINVAL; /* unclosed quote */
}
} else {
- for (end = buf; *end && !isspace(*end); end++)
+ for (end = buf; *end && !isspace(*end) && *end != ','; end++)
;
if (end == buf) {
pr_err("parse err after word:%d=%s\n", nwords,
@@ -595,7 +603,8 @@ static int ddebug_exec_queries(char *query, const char *modname)
if (split)
*split++ = '\0';
- query = skip_spaces(query);
+ query = skip_spaces_and_commas(query);
+
if (!query || !*query || *query == '#')
continue;
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 24/59] dyndbg: treat comma as a token separator
2025-03-20 18:52 ` [PATCH v2 24/59] dyndbg: treat comma as a token separator Jim Cromie
@ 2025-03-24 15:18 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:18 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Treat comma as a token terminator, just like a space. This allows a
> user to avoid quoting hassles when spaces are otherwise needed:
>
> :#> modprobe drm dyndbg=class,DRM_UT_CORE,+p\;class,DRM_UT_KMS,+p
>
> or as a boot arg:
>
> drm.dyndbg=class,DRM_UT_CORE,+p # todo: support multi-query here
>
> Given the many ways a boot-line +args can be assembled and then passed
> in/down/around shell based tools, this may allow side-stepping all
> sorts of quoting hassles thru those layers.
>
> existing query format:
>
> modprobe test_dynamic_debug dyndbg="class D2_CORE +p"
>
> new format:
>
> modprobe test_dynamic_debug dyndbg=class,D2_CORE,+p
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> Co-developed-by: Łukasz Bartosik <ukaszb@chromium.org>
> Signed-off-by: Łukasz Bartosik <ukaszb@chromium.org>
This patch seems to be unrelated to the whole series, and can be applied
on the current rc. What do you think about extracting the patches 24,
25, 26, 27? I understand 28 depends on it, but I believe 24..27 can be
merged before as they are simple.
> ---
> lib/dynamic_debug.c | 17 +++++++++++++----
> 1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index cd3eec5bb81c..168663629ef2 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -293,6 +293,14 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
> return nfound;
> }
>
> +static char *skip_spaces_and_commas(const char *str)
> +{
> + str = skip_spaces(str);
> + while (*str == ',')
> + str = skip_spaces(++str);
> + return (char *)str;
> +}
> +
This is a bit complex to read, maybe you can simply re-write skip_space
completely to avoid the explicit check against is_skip below
bool is_skip(char c) {
return isspace(c) || c == ',';
}
char *skip(char *s) {
while (is_skip(*s))
s++;
return s;
}
With or without this:
Reviewed-by: Louis Chauvet <louis.chauvet@booltin.com>
> /*
> * Split the buffer `buf' into space-separated words.
> * Handles simple " and ' quoting, i.e. without nested,
> @@ -306,8 +314,8 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
> while (*buf) {
> char *end;
>
> - /* Skip leading whitespace */
> - buf = skip_spaces(buf);
> + /* Skip leading whitespace and comma */
> + buf = skip_spaces_and_commas(buf);
> if (!*buf)
> break; /* oh, it was trailing whitespace */
> if (*buf == '#')
> @@ -323,7 +331,7 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
> return -EINVAL; /* unclosed quote */
> }
> } else {
> - for (end = buf; *end && !isspace(*end); end++)
> + for (end = buf; *end && !isspace(*end) && *end != ','; end++)
^ here use is_skip
> ;
> if (end == buf) {
> pr_err("parse err after word:%d=%s\n", nwords,
> @@ -595,7 +603,8 @@ static int ddebug_exec_queries(char *query, const char *modname)
> if (split)
> *split++ = '\0';
>
> - query = skip_spaces(query);
> + query = skip_spaces_and_commas(query);
> +
> if (!query || !*query || *query == '#')
> continue;
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 25/59] selftests-dyndbg: add comma_terminator_tests
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (23 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 24/59] dyndbg: treat comma as a token separator Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:19 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 26/59] dyndbg: split multi-query strings with % Jim Cromie
` (33 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
New fn validates parsing and effect of queries using combinations of
commas and spaces to delimit the tokens.
It manipulates pr-debugs in builtin module/params, so might have deps
I havent foreseen on odd configurations.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
- skip comma tests if no builtins
---
.../dynamic_debug/dyndbg_selftest.sh | 21 ++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index 68a9046405f2..368d10a691a0 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -216,7 +216,7 @@ function check_err_msg() {
function basic_tests {
echo -e "${GREEN}# BASIC_TESTS ${NC}"
if [ $LACK_DD_BUILTIN -eq 1 ]; then
- echo "SKIP"
+ echo "SKIP - test requires params, which is a builtin module"
return
fi
ddcmd =_ # zero everything
@@ -238,8 +238,27 @@ EOF
ddcmd =_
}
+function comma_terminator_tests {
+ echo -e "${GREEN}# COMMA_TERMINATOR_TESTS ${NC}"
+ if [ $LACK_DD_BUILTIN -eq 1 ]; then
+ echo "SKIP - test requires params, which is a builtin module"
+ return
+ fi
+ # try combos of spaces & commas
+ check_match_ct '\[params\]' 4 -r
+ ddcmd module,params,=_ # commas as spaces
+ ddcmd module,params,+mpf # turn on module's pr-debugs
+ check_match_ct =pmf 4
+ ddcmd ,module ,, , params, -p
+ check_match_ct =mf 4
+ ddcmd " , module ,,, , params, -m" #
+ check_match_ct =f 4
+ ddcmd =_
+}
+
tests_list=(
basic_tests
+ comma_terminator_tests
)
# Run tests
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 25/59] selftests-dyndbg: add comma_terminator_tests
2025-03-20 18:52 ` [PATCH v2 25/59] selftests-dyndbg: add comma_terminator_tests Jim Cromie
@ 2025-03-24 15:19 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:19 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> New fn validates parsing and effect of queries using combinations of
> commas and spaces to delimit the tokens.
>
> It manipulates pr-debugs in builtin module/params, so might have deps
> I havent foreseen on odd configurations.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> - skip comma tests if no builtins
> ---
> .../dynamic_debug/dyndbg_selftest.sh | 21 ++++++++++++++++++-
> 1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> index 68a9046405f2..368d10a691a0 100755
> --- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> +++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> @@ -216,7 +216,7 @@ function check_err_msg() {
> function basic_tests {
> echo -e "${GREEN}# BASIC_TESTS ${NC}"
> if [ $LACK_DD_BUILTIN -eq 1 ]; then
> - echo "SKIP"
> + echo "SKIP - test requires params, which is a builtin module"
> return
> fi
> ddcmd =_ # zero everything
> @@ -238,8 +238,27 @@ EOF
> ddcmd =_
> }
>
> +function comma_terminator_tests {
> + echo -e "${GREEN}# COMMA_TERMINATOR_TESTS ${NC}"
> + if [ $LACK_DD_BUILTIN -eq 1 ]; then
> + echo "SKIP - test requires params, which is a builtin module"
> + return
> + fi
> + # try combos of spaces & commas
> + check_match_ct '\[params\]' 4 -r
> + ddcmd module,params,=_ # commas as spaces
> + ddcmd module,params,+mpf # turn on module's pr-debugs
> + check_match_ct =pmf 4
> + ddcmd ,module ,, , params, -p
> + check_match_ct =mf 4
> + ddcmd " , module ,,, , params, -m" #
> + check_match_ct =f 4
> + ddcmd =_
> +}
> +
> tests_list=(
> basic_tests
> + comma_terminator_tests
> )
>
> # Run tests
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 26/59] dyndbg: split multi-query strings with %
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (24 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 25/59] selftests-dyndbg: add comma_terminator_tests Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:19 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 27/59] selftests-dyndbg: test_percent_splitting Jim Cromie
` (32 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Since commit
85f7f6c0edb8 ("dynamic_debug: process multiple debug-queries on a line")
Multi-query commands have been allowed:
modprobe drm dyndbg="class DRM_UT_CORE +p; class DRM_UT_KMS +p"
modprobe drm dyndbg=<<EOX
class DRM_UT_CORE +p
class DRM_UT_KMS +p
EOX
More recently, the need for quoting was avoided by treating a comma
like a space/token-terminator:
modprobe drm dyndbg=class,DRM_UT_CORE,+p\;class,DRM_UT_KMS,+p
That works, but it needs the escaped semicolon, which is a shell
special-char (one of the bash control operators), so it is brittle
when passed in/down/around scripts. In particular, it fails when
passed to vng (virtme-ng).
So this patch adds '%' to the existing ';' and '\n' multi-command
separators, which is more shell-friendly, so you can more fully avoid
quoting and escaping hassles.
NOTE: it does break format matching on '%' patterns:
bash-5.2# ddcmd 'format "find-me: %foo" +p'
[ 203.900581] dyndbg: read 26 bytes from userspace
[ 203.900883] dyndbg: query 0: "format "find-me: " mod:*
[ 203.901118] dyndbg: unclosed quote: find-me:
[ 203.901355] dyndbg: tokenize failed
[ 203.901529] dyndbg: query 1: "foo" +p" mod:*
[ 203.901957] dyndbg: split into words: "foo"" "+p"
[ 203.902243] dyndbg: op='+' flags=0x1 maskp=0xffffffff
[ 203.902458] dyndbg: expecting pairs of match-spec <value>
[ 203.902703] dyndbg: query parse failed
[ 203.902871] dyndbg: processed 2 queries, with 0 matches, 2 errs
bash: echo: write error: Invalid argument
The '%' splits the input into 2 queries, and both fail. Given the
limited utility of matching against the working parts of a format
string "foo: %d bar %s", nothing is actually lost here.
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 168663629ef2..c44502787c2b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -599,7 +599,7 @@ static int ddebug_exec_queries(char *query, const char *modname)
int i, errs = 0, exitcode = 0, rc, nfound = 0;
for (i = 0; query; query = split) {
- split = strpbrk(query, ";\n");
+ split = strpbrk(query, "%;\n");
if (split)
*split++ = '\0';
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 26/59] dyndbg: split multi-query strings with %
2025-03-20 18:52 ` [PATCH v2 26/59] dyndbg: split multi-query strings with % Jim Cromie
@ 2025-03-24 15:19 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:19 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Since commit
> 85f7f6c0edb8 ("dynamic_debug: process multiple debug-queries on a line")
>
> Multi-query commands have been allowed:
>
> modprobe drm dyndbg="class DRM_UT_CORE +p; class DRM_UT_KMS +p"
> modprobe drm dyndbg=<<EOX
> class DRM_UT_CORE +p
> class DRM_UT_KMS +p
> EOX
>
> More recently, the need for quoting was avoided by treating a comma
> like a space/token-terminator:
>
> modprobe drm dyndbg=class,DRM_UT_CORE,+p\;class,DRM_UT_KMS,+p
>
> That works, but it needs the escaped semicolon, which is a shell
> special-char (one of the bash control operators), so it is brittle
> when passed in/down/around scripts. In particular, it fails when
> passed to vng (virtme-ng).
>
> So this patch adds '%' to the existing ';' and '\n' multi-command
> separators, which is more shell-friendly, so you can more fully avoid
> quoting and escaping hassles.
>
> NOTE: it does break format matching on '%' patterns:
>
> bash-5.2# ddcmd 'format "find-me: %foo" +p'
> [ 203.900581] dyndbg: read 26 bytes from userspace
> [ 203.900883] dyndbg: query 0: "format "find-me: " mod:*
> [ 203.901118] dyndbg: unclosed quote: find-me:
> [ 203.901355] dyndbg: tokenize failed
> [ 203.901529] dyndbg: query 1: "foo" +p" mod:*
> [ 203.901957] dyndbg: split into words: "foo"" "+p"
> [ 203.902243] dyndbg: op='+' flags=0x1 maskp=0xffffffff
> [ 203.902458] dyndbg: expecting pairs of match-spec <value>
> [ 203.902703] dyndbg: query parse failed
> [ 203.902871] dyndbg: processed 2 queries, with 0 matches, 2 errs
> bash: echo: write error: Invalid argument
>
> The '%' splits the input into 2 queries, and both fail. Given the
> limited utility of matching against the working parts of a format
> string "foo: %d bar %s", nothing is actually lost here.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.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 168663629ef2..c44502787c2b 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -599,7 +599,7 @@ static int ddebug_exec_queries(char *query, const char *modname)
> int i, errs = 0, exitcode = 0, rc, nfound = 0;
>
> for (i = 0; query; query = split) {
> - split = strpbrk(query, ";\n");
> + split = strpbrk(query, "%;\n");
> if (split)
> *split++ = '\0';
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 27/59] selftests-dyndbg: test_percent_splitting
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (25 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 26/59] dyndbg: split multi-query strings with % Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:19 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 28/59] selftests-dyndbg: add test_mod_submod Jim Cromie
` (31 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
This does basic testing of classmaps using '%' separated
multi-queries. It modprobes test_dynamic_debug with several classes
enabled, and counts to verify that the expected sites show the
enablement in the control file.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
.../dynamic_debug/dyndbg_selftest.sh | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index 368d10a691a0..c97c9391d0f4 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -256,9 +256,29 @@ function comma_terminator_tests {
ddcmd =_
}
+function test_percent_splitting {
+ echo -e "${GREEN}# TEST_PERCENT_SPLITTING - multi-command splitting on % ${NC}"
+ ifrmmod test_dynamic_debug_submod
+ ifrmmod test_dynamic_debug
+ ddcmd =_
+ modprobe test_dynamic_debug dyndbg=class,D2_CORE,+pf%class,D2_KMS,+pt%class,D2_ATOMIC,+pm
+ check_match_ct =pf 1
+ check_match_ct =pt 1
+ check_match_ct =pm 1
+ check_match_ct test_dynamic_debug 23 -r
+ # add flags to those callsites
+ ddcmd class,D2_CORE,+mf%class,D2_KMS,+lt%class,D2_ATOMIC,+ml
+ check_match_ct =pmf 1
+ check_match_ct =plt 1
+ check_match_ct =pml 1
+ check_match_ct test_dynamic_debug 23 -r
+ ifrmmod test_dynamic_debug
+}
+
tests_list=(
basic_tests
comma_terminator_tests
+ test_percent_splitting
)
# Run tests
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 27/59] selftests-dyndbg: test_percent_splitting
2025-03-20 18:52 ` [PATCH v2 27/59] selftests-dyndbg: test_percent_splitting Jim Cromie
@ 2025-03-24 15:19 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:19 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> This does basic testing of classmaps using '%' separated
> multi-queries. It modprobes test_dynamic_debug with several classes
> enabled, and counts to verify that the expected sites show the
> enablement in the control file.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> .../dynamic_debug/dyndbg_selftest.sh | 20 +++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> index 368d10a691a0..c97c9391d0f4 100755
> --- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> +++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> @@ -256,9 +256,29 @@ function comma_terminator_tests {
> ddcmd =_
> }
>
> +function test_percent_splitting {
> + echo -e "${GREEN}# TEST_PERCENT_SPLITTING - multi-command splitting on % ${NC}"
> + ifrmmod test_dynamic_debug_submod
> + ifrmmod test_dynamic_debug
> + ddcmd =_
> + modprobe test_dynamic_debug dyndbg=class,D2_CORE,+pf%class,D2_KMS,+pt%class,D2_ATOMIC,+pm
> + check_match_ct =pf 1
> + check_match_ct =pt 1
> + check_match_ct =pm 1
> + check_match_ct test_dynamic_debug 23 -r
> + # add flags to those callsites
> + ddcmd class,D2_CORE,+mf%class,D2_KMS,+lt%class,D2_ATOMIC,+ml
> + check_match_ct =pmf 1
> + check_match_ct =plt 1
> + check_match_ct =pml 1
> + check_match_ct test_dynamic_debug 23 -r
> + ifrmmod test_dynamic_debug
> +}
> +
> tests_list=(
> basic_tests
> comma_terminator_tests
> + test_percent_splitting
> )
>
> # Run tests
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 28/59] selftests-dyndbg: add test_mod_submod
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (26 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 27/59] selftests-dyndbg: test_percent_splitting Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:20 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 29/59] dyndbg: change __dynamic_func_call_cls* macros into expressions Jim Cromie
` (30 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
This new test-fn runs 3 module/submodule modprobe scenarios, variously
using both the generic dyndbg=<queries> modprobe arg, and the
test-module's classmap-params to manipulate the test-mod*'s pr_debugs.
In all cases, the current flag-settings are counted and tested vs
expectations.
The 3rd scenario recapitulates the DRM_USE_DYNAMIC_DEBUG=y failure.
1. 2 modprobes (super then sub), with separate dyndbg=class-settings
check module specific flag settings
2. modprobe submod, supermod is auto-loaded
set supermod class-params
check expected enablements in super & submod
3. modprobe super, with param=setting (like drm.debug=0x1ef)
modprobe submod
validate submod's class'd pr_debugs get properly enabled
The test uses multi-queries, with both commas and percents (to avoid
spaces and quoting). This is the main reason the test wasn't earlier
in the patchset, closer to the classmap patches its validating.
With some tedium, the tests could be refactored to split out early
tests which avoid multi-cmds, and test only the class-params.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
- drop -v used in test_mod_submod(). V=1 does it for whole test
- ifrmmod at test end (Lukasz)
---
.../dynamic_debug/dyndbg_selftest.sh | 69 +++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index c97c9391d0f4..cfed79b34996 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -275,10 +275,79 @@ function test_percent_splitting {
ifrmmod test_dynamic_debug
}
+function test_mod_submod {
+ echo -e "${GREEN}# TEST_MOD_SUBMOD ${NC}"
+ ifrmmod test_dynamic_debug_submod
+ ifrmmod test_dynamic_debug
+ ddcmd =_
+
+ # modprobe with class enablements
+ modprobe test_dynamic_debug \
+ dyndbg=class,D2_CORE,+pf%class,D2_KMS,+pt%class,D2_ATOMIC,+pm
+
+ check_match_ct '\[test_dynamic_debug\]' 23 -r
+ check_match_ct =pf 1
+ check_match_ct =pt 1
+ check_match_ct =pm 1
+
+ modprobe test_dynamic_debug_submod
+ check_match_ct test_dynamic_debug_submod 23 -r
+ check_match_ct '\[test_dynamic_debug\]' 23 -r
+ check_match_ct test_dynamic_debug 46 -r
+
+ # no enablements propagate here
+ check_match_ct =pf 1
+ check_match_ct =pt 1
+ check_match_ct =pm 1
+
+ # change classes again, this time submod too
+ ddcmd class,D2_CORE,+mf%class,D2_KMS,+lt%class,D2_ATOMIC,+ml "# add some prefixes"
+ check_match_ct =pmf 1
+ check_match_ct =plt 1
+ check_match_ct =pml 1
+ # submod changed too
+ check_match_ct =mf 1
+ check_match_ct =lt 1
+ check_match_ct =ml 1
+
+ # now work the classmap-params
+ # fresh start, to clear all above flags (test-fn limits)
+ ifrmmod test_dynamic_debug_submod
+ ifrmmod test_dynamic_debug
+ modprobe test_dynamic_debug_submod # get supermod too
+
+ echo 1 > /sys/module/test_dynamic_debug/parameters/p_disjoint_bits
+ echo 4 > /sys/module/test_dynamic_debug/parameters/p_level_num
+ # 2 mods * ( V1-3 + D2_CORE )
+ check_match_ct =p 8
+ echo 3 > /sys/module/test_dynamic_debug/parameters/p_disjoint_bits
+ echo 0 > /sys/module/test_dynamic_debug/parameters/p_level_num
+ # 2 mods * ( D2_CORE, D2_DRIVER )
+ check_match_ct =p 4
+ echo 0x16 > /sys/module/test_dynamic_debug/parameters/p_disjoint_bits
+ echo 0 > /sys/module/test_dynamic_debug/parameters/p_level_num
+ # 2 mods * ( D2_DRIVER, D2_KMS, D2_ATOMIC )
+ check_match_ct =p 6
+
+ # recap DRM_USE_DYNAMIC_DEBUG regression
+ ifrmmod test_dynamic_debug_submod
+ ifrmmod test_dynamic_debug
+ # set super-mod params
+ modprobe test_dynamic_debug p_disjoint_bits=0x16 p_level_num=5
+ check_match_ct =p 7
+ modprobe test_dynamic_debug_submod
+ # see them picked up by submod
+ check_match_ct =p 14
+ ifrmmod test_dynamic_debug_submod
+ ifrmmod test_dynamic_debug
+}
+
tests_list=(
basic_tests
+ # these require test_dynamic_debug*.ko
comma_terminator_tests
test_percent_splitting
+ test_mod_submod
)
# Run tests
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 28/59] selftests-dyndbg: add test_mod_submod
2025-03-20 18:52 ` [PATCH v2 28/59] selftests-dyndbg: add test_mod_submod Jim Cromie
@ 2025-03-24 15:20 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:20 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> This new test-fn runs 3 module/submodule modprobe scenarios, variously
> using both the generic dyndbg=<queries> modprobe arg, and the
> test-module's classmap-params to manipulate the test-mod*'s pr_debugs.
> In all cases, the current flag-settings are counted and tested vs
> expectations.
>
> The 3rd scenario recapitulates the DRM_USE_DYNAMIC_DEBUG=y failure.
>
> 1. 2 modprobes (super then sub), with separate dyndbg=class-settings
> check module specific flag settings
>
> 2. modprobe submod, supermod is auto-loaded
> set supermod class-params
> check expected enablements in super & submod
>
> 3. modprobe super, with param=setting (like drm.debug=0x1ef)
> modprobe submod
> validate submod's class'd pr_debugs get properly enabled
>
> The test uses multi-queries, with both commas and percents (to avoid
> spaces and quoting). This is the main reason the test wasn't earlier
> in the patchset, closer to the classmap patches its validating.
>
> With some tedium, the tests could be refactored to split out early
> tests which avoid multi-cmds, and test only the class-params.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> - drop -v used in test_mod_submod(). V=1 does it for whole test
> - ifrmmod at test end (Lukasz)
> ---
> .../dynamic_debug/dyndbg_selftest.sh | 69 +++++++++++++++++++
> 1 file changed, 69 insertions(+)
>
> diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> index c97c9391d0f4..cfed79b34996 100755
> --- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> +++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
> @@ -275,10 +275,79 @@ function test_percent_splitting {
> ifrmmod test_dynamic_debug
> }
>
> +function test_mod_submod {
> + echo -e "${GREEN}# TEST_MOD_SUBMOD ${NC}"
> + ifrmmod test_dynamic_debug_submod
> + ifrmmod test_dynamic_debug
> + ddcmd =_
> +
> + # modprobe with class enablements
> + modprobe test_dynamic_debug \
> + dyndbg=class,D2_CORE,+pf%class,D2_KMS,+pt%class,D2_ATOMIC,+pm
> +
> + check_match_ct '\[test_dynamic_debug\]' 23 -r
> + check_match_ct =pf 1
> + check_match_ct =pt 1
> + check_match_ct =pm 1
> +
> + modprobe test_dynamic_debug_submod
> + check_match_ct test_dynamic_debug_submod 23 -r
> + check_match_ct '\[test_dynamic_debug\]' 23 -r
> + check_match_ct test_dynamic_debug 46 -r
> +
> + # no enablements propagate here
> + check_match_ct =pf 1
> + check_match_ct =pt 1
> + check_match_ct =pm 1
> +
> + # change classes again, this time submod too
> + ddcmd class,D2_CORE,+mf%class,D2_KMS,+lt%class,D2_ATOMIC,+ml "# add some prefixes"
> + check_match_ct =pmf 1
> + check_match_ct =plt 1
> + check_match_ct =pml 1
> + # submod changed too
> + check_match_ct =mf 1
> + check_match_ct =lt 1
> + check_match_ct =ml 1
> +
> + # now work the classmap-params
> + # fresh start, to clear all above flags (test-fn limits)
> + ifrmmod test_dynamic_debug_submod
> + ifrmmod test_dynamic_debug
> + modprobe test_dynamic_debug_submod # get supermod too
> +
> + echo 1 > /sys/module/test_dynamic_debug/parameters/p_disjoint_bits
> + echo 4 > /sys/module/test_dynamic_debug/parameters/p_level_num
> + # 2 mods * ( V1-3 + D2_CORE )
> + check_match_ct =p 8
> + echo 3 > /sys/module/test_dynamic_debug/parameters/p_disjoint_bits
> + echo 0 > /sys/module/test_dynamic_debug/parameters/p_level_num
> + # 2 mods * ( D2_CORE, D2_DRIVER )
> + check_match_ct =p 4
> + echo 0x16 > /sys/module/test_dynamic_debug/parameters/p_disjoint_bits
> + echo 0 > /sys/module/test_dynamic_debug/parameters/p_level_num
> + # 2 mods * ( D2_DRIVER, D2_KMS, D2_ATOMIC )
> + check_match_ct =p 6
> +
> + # recap DRM_USE_DYNAMIC_DEBUG regression
> + ifrmmod test_dynamic_debug_submod
> + ifrmmod test_dynamic_debug
> + # set super-mod params
> + modprobe test_dynamic_debug p_disjoint_bits=0x16 p_level_num=5
> + check_match_ct =p 7
> + modprobe test_dynamic_debug_submod
> + # see them picked up by submod
> + check_match_ct =p 14
> + ifrmmod test_dynamic_debug_submod
> + ifrmmod test_dynamic_debug
> +}
> +
> tests_list=(
> basic_tests
> + # these require test_dynamic_debug*.ko
> comma_terminator_tests
> test_percent_splitting
> + test_mod_submod
> )
>
> # Run tests
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 29/59] dyndbg: change __dynamic_func_call_cls* macros into expressions
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (27 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 28/59] selftests-dyndbg: add test_mod_submod Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:19 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries Jim Cromie
` (29 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The Xe driver's XE_IOCTL_DBG macro calls drm_dbg() from inside an if
(expression). This breaks when CONFIG_DRM_USE_DYNAMIC_DEBUG=y because
the invoked macro has a do-while-0 wrapper.
if (cond && (drm_dbg("expr-form"),1)) {
... do some more stuff
}
Fix for this usage by changing __dynamic_func_call_cls{,_no_desc}
macros into expressions, by replacing the do-while-0s with a ({ })
wrapper. In the common usage, the trailing ';' converts the
expression into a statement.
drm_dbg("statement form");
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
---
include/linux/dynamic_debug.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 8043966a0fd6..80bcaad03400 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -339,20 +339,20 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
* (|_cls): adds in _DPRINT_CLASS_DFLT as needed
* (|_no_desc): former gets callsite descriptor as 1st arg (for prdbgs)
*/
-#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \
- DEFINE_DYNAMIC_DEBUG_METADATA_CLS((id), cls, fmt); \
+#define __dynamic_func_call_cls(id, cls, fmt, func, ...) ({ \
+ DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
if (DYNAMIC_DEBUG_BRANCH(id)) \
- func(&id, ##__VA_ARGS__); \
-} while (0)
+ func(&(id), ##__VA_ARGS__); \
+})
#define __dynamic_func_call(id, fmt, func, ...) \
__dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt, \
func, ##__VA_ARGS__)
-#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do { \
+#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) ({ \
DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
if (DYNAMIC_DEBUG_BRANCH(id)) \
func(__VA_ARGS__); \
-} while (0)
+})
#define __dynamic_func_call_no_desc(id, fmt, func, ...) \
__dynamic_func_call_cls_no_desc(id, _DPRINTK_CLASS_DFLT, \
fmt, func, ##__VA_ARGS__)
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 29/59] dyndbg: change __dynamic_func_call_cls* macros into expressions
2025-03-20 18:52 ` [PATCH v2 29/59] dyndbg: change __dynamic_func_call_cls* macros into expressions Jim Cromie
@ 2025-03-24 15:19 ` Louis Chauvet
2025-03-25 16:23 ` jim.cromie
0 siblings, 1 reply; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:19 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> The Xe driver's XE_IOCTL_DBG macro calls drm_dbg() from inside an if
> (expression). This breaks when CONFIG_DRM_USE_DYNAMIC_DEBUG=y because
> the invoked macro has a do-while-0 wrapper.
>
> if (cond && (drm_dbg("expr-form"),1)) {
> ... do some more stuff
> }
>
> Fix for this usage by changing __dynamic_func_call_cls{,_no_desc}
> macros into expressions, by replacing the do-while-0s with a ({ })
> wrapper. In the common usage, the trailing ';' converts the
> expression into a statement.
>
> drm_dbg("statement form");
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> ---
> include/linux/dynamic_debug.h | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> index 8043966a0fd6..80bcaad03400 100644
> --- a/include/linux/dynamic_debug.h
> +++ b/include/linux/dynamic_debug.h
> @@ -339,20 +339,20 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
> * (|_cls): adds in _DPRINT_CLASS_DFLT as needed
> * (|_no_desc): former gets callsite descriptor as 1st arg (for prdbgs)
> */
> -#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \
> - DEFINE_DYNAMIC_DEBUG_METADATA_CLS((id), cls, fmt); \
> +#define __dynamic_func_call_cls(id, cls, fmt, func, ...) ({ \
> + DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
Is it normal to remove the parenthesis around id? Or the other way
around, why did you add parenthesis in PATCH 17?
> if (DYNAMIC_DEBUG_BRANCH(id)) \
> - func(&id, ##__VA_ARGS__); \
> -} while (0)
> + func(&(id), ##__VA_ARGS__); \
> +})
> #define __dynamic_func_call(id, fmt, func, ...) \
> __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt, \
> func, ##__VA_ARGS__)
>
> -#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do { \
> +#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) ({ \
> DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
I expect the same constraints around id here, both with parenthesis, or
no parenthesis at all.
> if (DYNAMIC_DEBUG_BRANCH(id)) \
> func(__VA_ARGS__); \
> -} while (0)
> +})
> #define __dynamic_func_call_no_desc(id, fmt, func, ...) \
> __dynamic_func_call_cls_no_desc(id, _DPRINTK_CLASS_DFLT, \
> fmt, func, ##__VA_ARGS__)
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 29/59] dyndbg: change __dynamic_func_call_cls* macros into expressions
2025-03-24 15:19 ` Louis Chauvet
@ 2025-03-25 16:23 ` jim.cromie
0 siblings, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-25 16:23 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
On Mon, Mar 24, 2025 at 9:19 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>
>
>
> Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> > The Xe driver's XE_IOCTL_DBG macro calls drm_dbg() from inside an if
> > (expression). This breaks when CONFIG_DRM_USE_DYNAMIC_DEBUG=y because
> > the invoked macro has a do-while-0 wrapper.
> >
> > if (cond && (drm_dbg("expr-form"),1)) {
> > ... do some more stuff
> > }
> >
> > Fix for this usage by changing __dynamic_func_call_cls{,_no_desc}
> > macros into expressions, by replacing the do-while-0s with a ({ })
> > wrapper. In the common usage, the trailing ';' converts the
> > expression into a statement.
> >
> > drm_dbg("statement form");
> >
> > Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> > ---
> > ---
> > include/linux/dynamic_debug.h | 12 ++++++------
> > 1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
> > index 8043966a0fd6..80bcaad03400 100644
> > --- a/include/linux/dynamic_debug.h
> > +++ b/include/linux/dynamic_debug.h
> > @@ -339,20 +339,20 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
> > * (|_cls): adds in _DPRINT_CLASS_DFLT as needed
> > * (|_no_desc): former gets callsite descriptor as 1st arg (for prdbgs)
> > */
> > -#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do { \
> > - DEFINE_DYNAMIC_DEBUG_METADATA_CLS((id), cls, fmt); \
> > +#define __dynamic_func_call_cls(id, cls, fmt, func, ...) ({ \
> > + DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
>
> Is it normal to remove the parenthesis around id? Or the other way
> around, why did you add parenthesis in PATCH 17?
>
heisen-thinking ?
noisy inputs ?
historically, checkpatch warnings on macros have given me difficulty
so I tend toward defense.
I think this one was a red-herring.
> > if (DYNAMIC_DEBUG_BRANCH(id)) \
> > - func(&id, ##__VA_ARGS__); \
> > -} while (0)
> > + func(&(id), ##__VA_ARGS__); \
> > +})
> > #define __dynamic_func_call(id, fmt, func, ...) \
> > __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt, \
> > func, ##__VA_ARGS__)
> >
> > -#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do { \
> > +#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) ({ \
> > DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt); \
>
> I expect the same constraints around id here, both with parenthesis, or
> no parenthesis at all.
>
yes, inconsistent.
> > if (DYNAMIC_DEBUG_BRANCH(id)) \
> > func(__VA_ARGS__); \
> > -} while (0)
> > +})
> > #define __dynamic_func_call_no_desc(id, fmt, func, ...) \
> > __dynamic_func_call_cls_no_desc(id, _DPRINTK_CLASS_DFLT, \
> > fmt, func, ##__VA_ARGS__)
>
> --
> Louis Chauvet, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (28 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 29/59] dyndbg: change __dynamic_func_call_cls* macros into expressions Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:20 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 31/59] docs/dyndbg: explain new delimiters: comma, percent Jim Cromie
` (28 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Current classmap code protects class'd pr_debugs from unintended
changes by "legacy" unclassed queries:
# this doesn't disable all of DRM_UT_* categories
echo "-p" > /proc/dynamic_debug/control
# name the class to change it - protective but tedious
echo "class DRM_UT_CORE +p" > /proc/dynamic_debug/control
# or do it the subsystem way
echo 1 > /sys/module/drm/parameters/debug
This "name the class to change it" behavior gave a modicum of
protection to classmap users (ie DRM) so their debug settings aren't
trivially and unintentionally altered underneath them.
But this made the class keyword special in some sense; the other
keywords skip only on explicit mismatch, otherwize the code falls thru
to adjust the pr-debug site.
So Jason Baron didn't like this special case when I 1st proposed it;
I argued 2 points:
- "protection gives stable-debug, improving utility"
- __drm_debug is authoritative w/o dyndbg under it.
I thought I'd convinced him back then, (and the patchset got merged),
but he noted it again when he reviewed this series. So this commit
names the "special case": ddebug_client_module_protects_classes(), and
reverts it to Jason's preference.
If a class mismatch is seen, code distinguishes whether the class was
explicitly given (and always skips/continue), or the DFLT was assumed
because no class was given. Here we test
ddebug_client_module_protects_classes(), skip if so.
Later, if any user/module wants to protect its classes, we could add a
flag to ddebug_table, a means to set it from CLASSMAP_DEFINE, and
check it when applying a classless query/cmd.
CC: jbaron@akamai.com
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
lib/dynamic_debug.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index c44502787c2b..13de0dd3a4ad 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -193,6 +193,17 @@ static int ddebug_find_valid_class(struct ddebug_table const *dt, const char *cl
return -ENOENT;
}
+/*
+ * classmaps-v1 protected classes from changes by legacy commands
+ * (those selecting _DPRINTK_CLASS_DFLT by omission), v2 undoes that
+ * special treatment. State so explicitly. Later we could give
+ * modules the choice to protect their classes or to keep v2 behavior.
+ */
+static inline bool ddebug_client_module_protects_classes(const struct ddebug_table *dt)
+{
+ return false;
+}
+
/*
* Search the tables for _ddebug's which match the given `query' and
* apply the `flags' and `mask' to them. Returns number of matching
@@ -206,7 +217,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
unsigned int newflags;
unsigned int nfound = 0;
struct flagsbuf fbuf, nbuf;
- int valid_class;
+ int slctd_class;
/* search for matching ddebugs */
mutex_lock(&ddebug_lock);
@@ -218,21 +229,26 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
continue;
if (query->class_string) {
- valid_class = ddebug_find_valid_class(dt, query->class_string);
- if (valid_class < 0)
+ slctd_class = ddebug_find_valid_class(dt, query->class_string);
+ if (slctd_class < 0)
+ /* skip/reject classes unknown by module */
continue;
} else {
- /* constrain query, do not touch class'd callsites */
- valid_class = _DPRINTK_CLASS_DFLT;
+ slctd_class = _DPRINTK_CLASS_DFLT;
}
for (i = 0; i < dt->info.descs.len; i++) {
struct _ddebug *dp = &dt->info.descs.start[i];
- /* match site against query-class */
- if (dp->class_id != valid_class)
- continue;
-
+ if (dp->class_id != slctd_class) {
+ if (query->class_string)
+ /* site.class != given class */
+ continue;
+ /* legacy query, class'd site */
+ else if (ddebug_client_module_protects_classes(dt))
+ continue;
+ /* allow change on class'd pr_debug */
+ }
/* match against the source filename */
if (query->filename &&
!match_wildcard(query->filename, dp->filename) &&
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries
2025-03-20 18:52 ` [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries Jim Cromie
@ 2025-03-24 15:20 ` Louis Chauvet
2025-03-25 18:29 ` jim.cromie
2025-03-25 20:02 ` jim.cromie
0 siblings, 2 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:20 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Current classmap code protects class'd pr_debugs from unintended
> changes by "legacy" unclassed queries:
>
> # this doesn't disable all of DRM_UT_* categories
> echo "-p" > /proc/dynamic_debug/control
>
> # name the class to change it - protective but tedious
> echo "class DRM_UT_CORE +p" > /proc/dynamic_debug/control
>
> # or do it the subsystem way
> echo 1 > /sys/module/drm/parameters/debug
>
> This "name the class to change it" behavior gave a modicum of
> protection to classmap users (ie DRM) so their debug settings aren't
> trivially and unintentionally altered underneath them.
>
> But this made the class keyword special in some sense; the other
> keywords skip only on explicit mismatch, otherwize the code falls thru
s/otherwize/otherwise/
> to adjust the pr-debug site.
>
> So Jason Baron didn't like this special case when I 1st proposed it;
> I argued 2 points:
> - "protection gives stable-debug, improving utility"
> - __drm_debug is authoritative w/o dyndbg under it.
>
> I thought I'd convinced him back then, (and the patchset got merged),
> but he noted it again when he reviewed this series. So this commit
> names the "special case": ddebug_client_module_protects_classes(), and
> reverts it to Jason's preference.
>
> If a class mismatch is seen, code distinguishes whether the class was
> explicitly given (and always skips/continue), or the DFLT was assumed
> because no class was given. Here we test
> ddebug_client_module_protects_classes(), skip if so.
>
> Later, if any user/module wants to protect its classes, we could add a
> flag to ddebug_table, a means to set it from CLASSMAP_DEFINE, and
> check it when applying a classless query/cmd.
I don't really understand the goal of the protection, do you have the
discussion between you and Jason so I can have some context and some
answer to my questions?
With the example you gave above, I think this could lead to a very odd
behavior: if I enable dyndbg, I expect any pr_dbg to be managed by
dyndbg settings.
If a user writes stuff on dyndbg control, he clearly knows what he is
doing, and he wants to control what logs he wants.
And if you allow multiple "protected" users, the normal way to disable
all dyndbg logs will be:
ddcmd -p
ddcmd class DRM_UT_CORE -p
ddcmd class DRM_... -p # all drm classes
ddcmd class SPI_... -p # all spi classes
ddcmd class WHATEVER_... -p # all other subsystem
# And only now you can enable only what you want
ddcmd module my_mod +p
This is clearly annoying to write.
If DRM (or whatever subsystem) wants to add a debug parameter and use it
to control their logs without being impacted by dyndbg, I believe it
should not use dyndbg classes to do it.
> CC: jbaron@akamai.com
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> lib/dynamic_debug.c | 34 +++++++++++++++++++++++++---------
> 1 file changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> index c44502787c2b..13de0dd3a4ad 100644
> --- a/lib/dynamic_debug.c
> +++ b/lib/dynamic_debug.c
> @@ -193,6 +193,17 @@ static int ddebug_find_valid_class(struct ddebug_table const *dt, const char *cl
> return -ENOENT;
> }
>
> +/*
> + * classmaps-v1 protected classes from changes by legacy commands
> + * (those selecting _DPRINTK_CLASS_DFLT by omission), v2 undoes that
> + * special treatment. State so explicitly. Later we could give
> + * modules the choice to protect their classes or to keep v2 behavior.
> + */
> +static inline bool ddebug_client_module_protects_classes(const struct ddebug_table *dt)
> +{
> + return false;
> +}
> +
> /*
> * Search the tables for _ddebug's which match the given `query' and
> * apply the `flags' and `mask' to them. Returns number of matching
> @@ -206,7 +217,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
> unsigned int newflags;
> unsigned int nfound = 0;
> struct flagsbuf fbuf, nbuf;
> - int valid_class;
> + int slctd_class;
Nitpick: can you use full words? slctd is difficult to read.
>
> /* search for matching ddebugs */
> mutex_lock(&ddebug_lock);
> @@ -218,21 +229,26 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
> continue;
>
> if (query->class_string) {
> - valid_class = ddebug_find_valid_class(dt, query->class_string);
> - if (valid_class < 0)
> + slctd_class = ddebug_find_valid_class(dt, query->class_string);
> + if (slctd_class < 0)
> + /* skip/reject classes unknown by module */
> continue;
> } else {
> - /* constrain query, do not touch class'd callsites */
> - valid_class = _DPRINTK_CLASS_DFLT;
> + slctd_class = _DPRINTK_CLASS_DFLT;
> }
>
> for (i = 0; i < dt->info.descs.len; i++) {
> struct _ddebug *dp = &dt->info.descs.start[i];
>
> - /* match site against query-class */
> - if (dp->class_id != valid_class)
> - continue;
> -
> + if (dp->class_id != slctd_class) {
> + if (query->class_string)
> + /* site.class != given class */
> + continue;
> + /* legacy query, class'd site */
> + else if (ddebug_client_module_protects_classes(dt))
> + continue;
> + /* allow change on class'd pr_debug */
> + }
> /* match against the source filename */
> if (query->filename &&
> !match_wildcard(query->filename, dp->filename) &&
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries
2025-03-24 15:20 ` Louis Chauvet
@ 2025-03-25 18:29 ` jim.cromie
2025-03-25 23:05 ` jim.cromie
2025-03-25 20:02 ` jim.cromie
1 sibling, 1 reply; 103+ messages in thread
From: jim.cromie @ 2025-03-25 18:29 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
On Mon, Mar 24, 2025 at 9:20 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>
>
>
> Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> > Current classmap code protects class'd pr_debugs from unintended
> > changes by "legacy" unclassed queries:
> >
> > # this doesn't disable all of DRM_UT_* categories
> > echo "-p" > /proc/dynamic_debug/control
> >
> > # name the class to change it - protective but tedious
> > echo "class DRM_UT_CORE +p" > /proc/dynamic_debug/control
> >
> > # or do it the subsystem way
> > echo 1 > /sys/module/drm/parameters/debug
> >
> > This "name the class to change it" behavior gave a modicum of
> > protection to classmap users (ie DRM) so their debug settings aren't
> > trivially and unintentionally altered underneath them.
> >
> > But this made the class keyword special in some sense; the other
> > keywords skip only on explicit mismatch, otherwize the code falls thru
>
> s/otherwize/otherwise/
ack
>
> > to adjust the pr-debug site.
> >
> > So Jason Baron didn't like this special case when I 1st proposed it;
> > I argued 2 points:
> > - "protection gives stable-debug, improving utility"
> > - __drm_debug is authoritative w/o dyndbg under it.
> >
> > I thought I'd convinced him back then, (and the patchset got merged),
> > but he noted it again when he reviewed this series. So this commit
> > names the "special case": ddebug_client_module_protects_classes(), and
> > reverts it to Jason's preference.
> >
> > If a class mismatch is seen, code distinguishes whether the class was
> > explicitly given (and always skips/continue), or the DFLT was assumed
> > because no class was given. Here we test
> > ddebug_client_module_protects_classes(), skip if so.
> >
> > Later, if any user/module wants to protect its classes, we could add a
> > flag to ddebug_table, a means to set it from CLASSMAP_DEFINE, and
> > check it when applying a classless query/cmd.
>
> I don't really understand the goal of the protection, do you have the
> discussion between you and Jason so I can have some context and some
> answer to my questions?
>
The on-list discussion is here.
https://lore.kernel.org/lkml/2d3846cb-ff9a-3484-61a8-973799727d8f@akamai.com/
https://lore.kernel.org/lkml/0d9f644f-3d60-02c3-7ce0-01296757e181@akamai.com/#t
At the time I thought it was unfinished business, and expected some
more discussion,
but that didnt happen, and later GregKH committed the set.
Last summer I emailed him privately, and he made a 5-6 points Ive
addressed in this rev,
(reduction of repetitive code, enforcing classmap constraints,
protecting against misuse)
but it also became clear he still didnt like the "specialness" of the keyword,
given by the _DFLT constraint applied to legacy callsites and queries.
Since thats a bit of a philosophical debate, I looked for a technical solution,
to have it either way with fairly trivial additions, and to yield
until user experience
dictates otherwise
To be clear, I still think protecting the "classed" is proper.
Without dyndbg, /sys/module/drm/parameters/debug is authoritative, full stop.
I'm surprised any customer would give away that certainty,
it looks like a (small caliber) footgun to me.
But its not worth disagreeing on.
Hence this patch reverts that "protection"
> With the example you gave above, I think this could lead to a very odd
> behavior: if I enable dyndbg, I expect any pr_dbg to be managed by
> dyndbg settings.
if by "any" you mean ALL the ones that currently exist,
before we add a whole new "CLASS" of user,
(with ~5k uses, all comfortable with their exclusive control)
I can agree.
echo class FOO +p > control
gives full control. You just have to say so for the new classes of users.
>
> If a user writes stuff on dyndbg control, he clearly knows what he is
> doing, and he wants to control what logs he wants.
>
> And if you allow multiple "protected" users, the normal way to disable
> all dyndbg logs will be:
>
> ddcmd -p
> ddcmd class DRM_UT_CORE -p
> ddcmd class DRM_... -p # all drm classes
> ddcmd class SPI_... -p # all spi classes
> ddcmd class WHATEVER_... -p # all other subsystem
>
> # And only now you can enable only what you want
> ddcmd module my_mod +p
>
> This is clearly annoying to write.
It is clearly annoying.
It doesnt need to be handy.
thats what /sys/module/drm/parameters/debug is for.
with modest "protection" of explicit naming,
the sysfs knob can reasonably be expected
to reflect whats going on underneath.
Without it, bets are misplaced.
>
> If DRM (or whatever subsystem) wants to add a debug parameter and use it
> to control their logs without being impacted by dyndbg, I believe it
> should not use dyndbg classes to do it.
hmm - dyndbg's 1st value is its NOOP cost when off.
If thats not worth something, you wouldnt bother using it.
In any case, its pretty clear that my viewpoint isnt prevailing here,
and as I said, I dont care enough to disagree.
the reversion here can stand.
>
> > CC: jbaron@akamai.com
> > Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> > ---
> > lib/dynamic_debug.c | 34 +++++++++++++++++++++++++---------
> > 1 file changed, 25 insertions(+), 9 deletions(-)
> >
> > diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
> > index c44502787c2b..13de0dd3a4ad 100644
> > --- a/lib/dynamic_debug.c
> > +++ b/lib/dynamic_debug.c
> > @@ -193,6 +193,17 @@ static int ddebug_find_valid_class(struct ddebug_table const *dt, const char *cl
> > return -ENOENT;
> > }
> >
> > +/*
> > + * classmaps-v1 protected classes from changes by legacy commands
> > + * (those selecting _DPRINTK_CLASS_DFLT by omission), v2 undoes that
> > + * special treatment. State so explicitly. Later we could give
> > + * modules the choice to protect their classes or to keep v2 behavior.
> > + */
> > +static inline bool ddebug_client_module_protects_classes(const struct ddebug_table *dt)
> > +{
> > + return false;
> > +}
> > +
> > /*
> > * Search the tables for _ddebug's which match the given `query' and
> > * apply the `flags' and `mask' to them. Returns number of matching
> > @@ -206,7 +217,7 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
> > unsigned int newflags;
> > unsigned int nfound = 0;
> > struct flagsbuf fbuf, nbuf;
> > - int valid_class;
> > + int slctd_class;
>
> Nitpick: can you use full words? slctd is difficult to read.
>
> >
> > /* search for matching ddebugs */
> > mutex_lock(&ddebug_lock);
> > @@ -218,21 +229,26 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
> > continue;
> >
> > if (query->class_string) {
> > - valid_class = ddebug_find_valid_class(dt, query->class_string);
> > - if (valid_class < 0)
> > + slctd_class = ddebug_find_valid_class(dt, query->class_string);
> > + if (slctd_class < 0)
> > + /* skip/reject classes unknown by module */
> > continue;
> > } else {
> > - /* constrain query, do not touch class'd callsites */
> > - valid_class = _DPRINTK_CLASS_DFLT;
> > + slctd_class = _DPRINTK_CLASS_DFLT;
> > }
> >
> > for (i = 0; i < dt->info.descs.len; i++) {
> > struct _ddebug *dp = &dt->info.descs.start[i];
> >
> > - /* match site against query-class */
> > - if (dp->class_id != valid_class)
> > - continue;
> > -
> > + if (dp->class_id != slctd_class) {
> > + if (query->class_string)
> > + /* site.class != given class */
> > + continue;
> > + /* legacy query, class'd site */
> > + else if (ddebug_client_module_protects_classes(dt))
> > + continue;
> > + /* allow change on class'd pr_debug */
> > + }
> > /* match against the source filename */
> > if (query->filename &&
> > !match_wildcard(query->filename, dp->filename) &&
>
> --
> Louis Chauvet, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries
2025-03-25 18:29 ` jim.cromie
@ 2025-03-25 23:05 ` jim.cromie
0 siblings, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-25 23:05 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
On Tue, Mar 25, 2025 at 12:29 PM <jim.cromie@gmail.com> wrote:
>
> On Mon, Mar 24, 2025 at 9:20 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
> >
> >
> >
> > Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> > > Current classmap code protects class'd pr_debugs from unintended
> > > changes by "legacy" unclassed queries:
> > >
> > > # this doesn't disable all of DRM_UT_* categories
> > > echo "-p" > /proc/dynamic_debug/control
> > >
> > > # name the class to change it - protective but tedious
> > > echo "class DRM_UT_CORE +p" > /proc/dynamic_debug/control
> > >
> > > # or do it the subsystem way
> > > echo 1 > /sys/module/drm/parameters/debug
> > >
> > > This "name the class to change it" behavior gave a modicum of
> > > protection to classmap users (ie DRM) so their debug settings aren't
> > > trivially and unintentionally altered underneath them.
> > >
> > > But this made the class keyword special in some sense; the other
> > > keywords skip only on explicit mismatch, otherwize the code falls thru
> >
> > s/otherwize/otherwise/
>
> ack
>
> >
> > > to adjust the pr-debug site.
> > >
> > > So Jason Baron didn't like this special case when I 1st proposed it;
> > > I argued 2 points:
> > > - "protection gives stable-debug, improving utility"
> > > - __drm_debug is authoritative w/o dyndbg under it.
> > >
> > > I thought I'd convinced him back then, (and the patchset got merged),
> > > but he noted it again when he reviewed this series. So this commit
> > > names the "special case": ddebug_client_module_protects_classes(), and
> > > reverts it to Jason's preference.
> > >
> > > If a class mismatch is seen, code distinguishes whether the class was
> > > explicitly given (and always skips/continue), or the DFLT was assumed
> > > because no class was given. Here we test
> > > ddebug_client_module_protects_classes(), skip if so.
> > >
> > > Later, if any user/module wants to protect its classes, we could add a
> > > flag to ddebug_table, a means to set it from CLASSMAP_DEFINE, and
> > > check it when applying a classless query/cmd.
> >
> > I don't really understand the goal of the protection, do you have the
> > discussion between you and Jason so I can have some context and some
> > answer to my questions?
> >
>
> The on-list discussion is here.
>
> https://lore.kernel.org/lkml/2d3846cb-ff9a-3484-61a8-973799727d8f@akamai.com/
> https://lore.kernel.org/lkml/0d9f644f-3d60-02c3-7ce0-01296757e181@akamai.com/#t
>
> At the time I thought it was unfinished business, and expected some
> more discussion,
> but that didnt happen, and later GregKH committed the set.
>
> Last summer I emailed him privately, and he made a 5-6 points Ive
> addressed in this rev,
> (reduction of repetitive code, enforcing classmap constraints,
> protecting against misuse)
> but it also became clear he still didnt like the "specialness" of the keyword,
> given by the _DFLT constraint applied to legacy callsites and queries.
>
> Since thats a bit of a philosophical debate, I looked for a technical solution,
> to have it either way with fairly trivial additions, and to yield
> until user experience
> dictates otherwise
>
> To be clear, I still think protecting the "classed" is proper.
> Without dyndbg, /sys/module/drm/parameters/debug is authoritative, full stop.
> I'm surprised any customer would give away that certainty,
> it looks like a (small caliber) footgun to me.
> But its not worth disagreeing on.
> Hence this patch reverts that "protection"
>
> > With the example you gave above, I think this could lead to a very odd
> > behavior: if I enable dyndbg, I expect any pr_dbg to be managed by
> > dyndbg settings.
>
> if by "any" you mean ALL the ones that currently exist,
> before we add a whole new "CLASS" of user,
> (with ~5k uses, all comfortable with their exclusive control)
> I can agree.
>
> echo class FOO +p > control
> gives full control. You just have to say so for the new classes of users.
>
> >
> > If a user writes stuff on dyndbg control, he clearly knows what he is
> > doing, and he wants to control what logs he wants.
> >
> > And if you allow multiple "protected" users, the normal way to disable
> > all dyndbg logs will be:
> >
> > ddcmd -p
> > ddcmd class DRM_UT_CORE -p
> > ddcmd class DRM_... -p # all drm classes
> > ddcmd class SPI_... -p # all spi classes
> > ddcmd class WHATEVER_... -p # all other subsystem
> >
> > # And only now you can enable only what you want
> > ddcmd module my_mod +p
> >
> > This is clearly annoying to write.
>
> It is clearly annoying.
> It doesnt need to be handy.
> thats what /sys/module/drm/parameters/debug is for.
> with modest "protection" of explicit naming,
> the sysfs knob can reasonably be expected
> to reflect whats going on underneath.
> Without it, bets are misplaced.
>
Heres an improvement:
a use of CLASSMAP_PARAM means user wants a sysfs knob.
We can reasonably conclude they prefer that mode of control
(its what DRM users would expect, since a long time ago).
In that case, protect the PARAM settings
(from unqualified settings, use of class FOO still works)
otherwise no protection.
simple to explain, no extra knobs.
> >
> > If DRM (or whatever subsystem) wants to add a debug parameter and use it
> > to control their logs without being impacted by dyndbg, I believe it
> > should not use dyndbg classes to do it.
>
> hmm - dyndbg's 1st value is its NOOP cost when off.
> If thats not worth something, you wouldnt bother using it.
>
>
> In any case, its pretty clear that my viewpoint isnt prevailing here,
> and as I said, I dont care enough to disagree.
> the reversion here can stand.
>
>
apologies, since Im sounding kinda argumentative.
Jim
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries
2025-03-24 15:20 ` Louis Chauvet
2025-03-25 18:29 ` jim.cromie
@ 2025-03-25 20:02 ` jim.cromie
1 sibling, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-25 20:02 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
> > - int valid_class;
> > + int slctd_class;
>
> Nitpick: can you use full words? slctd is difficult to read.
>
yes. done. thx.
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 31/59] docs/dyndbg: explain new delimiters: comma, percent
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (29 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 30/59] dyndbg: drop "protection" of class'd pr_debugs from legacy queries Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:22 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 32/59] docs/dyndbg: explain flags parse 1st Jim Cromie
` (27 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie, linux-doc
Add mention of comma and percent delimiters into the respective
paragraphs describing their equivalents: space and newline.
cc: linux-doc@vger.kernel.org
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
.../admin-guide/dynamic-debug-howto.rst | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index 4ac18c0a1d95..8e2083605bd7 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -78,16 +78,19 @@ Command Language Reference
==========================
At the basic lexical level, a command is a sequence of words separated
-by spaces or tabs. So these are all equivalent::
+by spaces, tabs, or commas. So these are all equivalent::
:#> ddcmd file svcsock.c line 1603 +p
:#> ddcmd "file svcsock.c line 1603 +p"
:#> ddcmd ' file svcsock.c line 1603 +p '
+ :#> ddcmd file,svcsock.c,line,1603,+p
-Command submissions are bounded by a write() system call.
-Multiple commands can be written together, separated by ``;`` or ``\n``::
+Command submissions are bounded by a write() system call. Multiple
+commands can be written together, separated by ``%``, ``;`` or ``\n``::
- :#> ddcmd "func pnpacpi_get_resources +p; func pnp_assign_mem +p"
+ :#> ddcmd func foo +p % func bar +p
+ :#> ddcmd func foo +p \; func bar +p
+ :#> ddcmd "func foo +p ; func bar +p"
:#> ddcmd <<"EOC"
func pnpacpi_get_resources +p
func pnp_assign_mem +p
@@ -109,7 +112,6 @@ 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:::
@@ -133,7 +135,6 @@ keywords are:::
``line-range`` cannot contain space, e.g.
"1-30" is valid range but "1 - 30" is not.
-
The meanings of each keyword are:
func
@@ -158,9 +159,11 @@ module
The given string is compared against the module name
of each callsite. The module name is the string as
seen in ``lsmod``, i.e. without the directory or the ``.ko``
- suffix and with ``-`` changed to ``_``. Examples::
+ suffix and with ``-`` changed to ``_``.
+
+ Examples::
- module sunrpc
+ module,sunrpc # with ',' as token separator
module nfsd
module drm* # both drm, drm_kms_helper
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 31/59] docs/dyndbg: explain new delimiters: comma, percent
2025-03-20 18:52 ` [PATCH v2 31/59] docs/dyndbg: explain new delimiters: comma, percent Jim Cromie
@ 2025-03-24 15:22 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:22 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala, linux-doc
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Add mention of comma and percent delimiters into the respective
> paragraphs describing their equivalents: space and newline.
>
> cc: linux-doc@vger.kernel.org
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
I think this should go with the previous patches introducing the
feature. (I don't know if doc should be in a separate patch, but I think
you can at least split this patch and put them just after the feature
itself)
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> .../admin-guide/dynamic-debug-howto.rst | 19 +++++++++++--------
> 1 file changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
> index 4ac18c0a1d95..8e2083605bd7 100644
> --- a/Documentation/admin-guide/dynamic-debug-howto.rst
> +++ b/Documentation/admin-guide/dynamic-debug-howto.rst
> @@ -78,16 +78,19 @@ Command Language Reference
> ==========================
>
> At the basic lexical level, a command is a sequence of words separated
> -by spaces or tabs. So these are all equivalent::
> +by spaces, tabs, or commas. So these are all equivalent::
>
> :#> ddcmd file svcsock.c line 1603 +p
> :#> ddcmd "file svcsock.c line 1603 +p"
> :#> ddcmd ' file svcsock.c line 1603 +p '
> + :#> ddcmd file,svcsock.c,line,1603,+p
>
> -Command submissions are bounded by a write() system call.
> -Multiple commands can be written together, separated by ``;`` or ``\n``::
> +Command submissions are bounded by a write() system call. Multiple
> +commands can be written together, separated by ``%``, ``;`` or ``\n``::
>
> - :#> ddcmd "func pnpacpi_get_resources +p; func pnp_assign_mem +p"
> + :#> ddcmd func foo +p % func bar +p
> + :#> ddcmd func foo +p \; func bar +p
> + :#> ddcmd "func foo +p ; func bar +p"
> :#> ddcmd <<"EOC"
> func pnpacpi_get_resources +p
> func pnp_assign_mem +p
> @@ -109,7 +112,6 @@ 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:::
> @@ -133,7 +135,6 @@ keywords are:::
> ``line-range`` cannot contain space, e.g.
> "1-30" is valid range but "1 - 30" is not.
>
> -
> The meanings of each keyword are:
>
> func
> @@ -158,9 +159,11 @@ module
> The given string is compared against the module name
> of each callsite. The module name is the string as
> seen in ``lsmod``, i.e. without the directory or the ``.ko``
> - suffix and with ``-`` changed to ``_``. Examples::
> + suffix and with ``-`` changed to ``_``.
> +
> + Examples::
>
> - module sunrpc
> + module,sunrpc # with ',' as token separator
> module nfsd
> module drm* # both drm, drm_kms_helper
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 32/59] docs/dyndbg: explain flags parse 1st
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (30 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 31/59] docs/dyndbg: explain new delimiters: comma, percent Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 33/59] docs/dyndbg: add classmap info to howto (TBD) Jim Cromie
` (26 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie, linux-doc
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
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
Documentation/admin-guide/dynamic-debug-howto.rst | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index 8e2083605bd7..d2928884c92b 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -112,6 +112,16 @@ 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 "*".
+Note: because the match-spec can be empty, the flags are checked 1st,
+then the pairs of keyword values. 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
+
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:::
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 32/59] docs/dyndbg: explain flags parse 1st
2025-03-20 18:52 ` [PATCH v2 32/59] docs/dyndbg: explain flags parse 1st Jim Cromie
@ 2025-03-24 15:23 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala, linux-doc
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> 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
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
I think this could be merged outside this series.
> ---
> Documentation/admin-guide/dynamic-debug-howto.rst | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
> index 8e2083605bd7..d2928884c92b 100644
> --- a/Documentation/admin-guide/dynamic-debug-howto.rst
> +++ b/Documentation/admin-guide/dynamic-debug-howto.rst
> @@ -112,6 +112,16 @@ 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 "*".
>
> +Note: because the match-spec can be empty, the flags are checked 1st,
> +then the pairs of keyword values. 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
> +
> 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:::
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 33/59] docs/dyndbg: add classmap info to howto (TBD)
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (31 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 32/59] docs/dyndbg: explain flags parse 1st Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body Jim Cromie
` (25 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie, linux-doc
Describe the 3 API macros providing dynamic_debug's classmaps
DYNDBG_CLASSMAP_DEFINE - create & export a classmap
DYNDBG_CLASSMAP_USE - refer to exported map
DYNDBG_CLASSMAP_PARAM - bind control param to the classmap
DYNDBG_CLASSMAP_PARAM_REF + use module's storage - __drm_debug
TBD: some of this might be over-specification, or just over-talked.
NB: The _DEFINE & _USE model makes the user dependent on the definer,
just like EXPORT_SYMBOL(__drm_debug) already does.
cc: linux-doc@vger.kernel.org
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
v5 adjustments per Randy Dunlap
v7 checkpatch fixes
v8 more
v9 rewords
---
.../admin-guide/dynamic-debug-howto.rst | 80 ++++++++++++++++++-
1 file changed, 79 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index d2928884c92b..9422dc4917d0 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -243,7 +243,6 @@ the ``p`` flag has meaning, other flags are ignored.
Note the regexp ``^[-+=][fslmpt_]+$`` matches a flags specification.
To clear all flags at once, use ``=_`` or ``-fslmpt``.
-
Debug messages during Boot Process
==================================
@@ -393,3 +392,82 @@ just a shortcut for ``print_hex_dump(KERN_DEBUG)``.
For ``print_hex_dump_debug()``/``print_hex_dump_bytes()``, format string is
its ``prefix_str`` argument, if it is constant string; or ``hexdump``
in case ``prefix_str`` is built dynamically.
+
+Dynamic Debug classmaps
+=======================
+
+The "class" keyword selects prdbgs based on author supplied,
+domain-oriented names. This complements the nested-scope keywords:
+module, file, function, line.
+
+The main difference from the others: class'd prdbgs must be named to
+be changed. This protects them from generic overwrite:
+
+ # IOW this cannot undo any DRM.debug settings
+ :#> ddcmd -p
+
+So each class must be enabled individually (no wildcards):
+
+ :#> ddcmd class DRM_UT_CORE +p
+ :#> ddcmd class DRM_UT_KMS +p
+ # or more selectively
+ :#> ddcmd class DRM_UT_CORE module drm +p
+
+Or the legacy/normal (more convenient) way:
+
+ :#> echo 0x1ff > /sys/module/drm/parameters/debug
+
+Dynamic Debug Classmap API
+==========================
+
+DRM.debug is built upon:
+ ~23 macros, all passing a DRM_UT_* constant as arg-1.
+ ~5000 calls to them, across drivers/gpu/drm/*
+ bits in /sys/module/drm/parameters/debug control all DRM_UT_* together
+
+The const short ints are good for optimizing compilers; a classmaps
+design goal was to keep that. So basically .classid === category.
+
+And since prdbgs are cataloged with just a DRM_UT_* to identify them,
+the "class" keyword maps known classnames to those reserved IDs, and
+by explicitly requiring "class FOO" in queries, we protect FOO class'd
+debugs from overwrite by generic queries.
+
+Its expected that other classmap users will also provide debug-macros
+using an enum-defined categorization scheme like DRM's, and dyndbg can
+be adapted under them similarly.
+
+DYNAMIC_DEBUG_CLASSMAP_DEFINE(var,type,_base,classnames) - this maps
+classnames onto class-ids consecutively, starting at _base, it also
+maps the names onto CLASSMAP_PARAM bits 0..N.
+
+DYNAMIC_DEBUG_CLASSMAP_USE(var) - modules call this to refer to the
+var _DEFINEd elsewhere (and exported).
+
+Classmaps are opt-in: modules invoke _DEFINE or _USE to authorize
+dyndbg to update those classes. "class FOO" queries are validated
+against the classes, this finds the classid to alter; classes are not
+directly selectable by their classid.
+
+There are 2 types of classmaps:
+
+ DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, like DRM.debug
+ DD_CLASS_TYPE_LEVEL_NUM: classes are relative, ordered (V3 > V2)
+
+DYNAMIC_DEBUG_CLASSMAP_PARAM - modelled after module_param_cb, it
+refers to a DEFINEd classmap, and associates it to the param's
+data-store. This state is then applied to DEFINEr and USEr modules
+when they're modprobed.
+
+The PARAM interface also enforces the DD_CLASS_TYPE_LEVEL_NUM relation
+amongst the contained classnames; all classes are independent in the
+control parser itself; there is no implied meaning in names like "V4".
+
+Modules or module-groups (drm & drivers) can define multiple
+classmaps, as long as they share the limited 0..62 per-module-group
+_class_id range, without overlap.
+
+``#define DEBUG`` will enable all pr_debugs in scope, including any
+class'd ones. This won't be reflected in the PARAM readback value,
+but the class'd pr_debug callsites can be forced off by toggling the
+classmap-kparam all-on then all-off.
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 33/59] docs/dyndbg: add classmap info to howto (TBD)
2025-03-20 18:52 ` [PATCH v2 33/59] docs/dyndbg: add classmap info to howto (TBD) Jim Cromie
@ 2025-03-24 15:23 ` Louis Chauvet
2025-03-25 18:42 ` jim.cromie
0 siblings, 1 reply; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala, linux-doc
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Describe the 3 API macros providing dynamic_debug's classmaps
>
> DYNDBG_CLASSMAP_DEFINE - create & export a classmap
> DYNDBG_CLASSMAP_USE - refer to exported map
> DYNDBG_CLASSMAP_PARAM - bind control param to the classmap
> DYNDBG_CLASSMAP_PARAM_REF + use module's storage - __drm_debug
>
> TBD: some of this might be over-specification, or just over-talked.
>
> NB: The _DEFINE & _USE model makes the user dependent on the definer,
> just like EXPORT_SYMBOL(__drm_debug) already does.
>
> cc: linux-doc@vger.kernel.org
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> v5 adjustments per Randy Dunlap
> v7 checkpatch fixes
> v8 more
> v9 rewords
> ---
> .../admin-guide/dynamic-debug-howto.rst | 80 ++++++++++++++++++-
> 1 file changed, 79 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
> index d2928884c92b..9422dc4917d0 100644
> --- a/Documentation/admin-guide/dynamic-debug-howto.rst
> +++ b/Documentation/admin-guide/dynamic-debug-howto.rst
> @@ -243,7 +243,6 @@ the ``p`` flag has meaning, other flags are ignored.
> Note the regexp ``^[-+=][fslmpt_]+$`` matches a flags specification.
> To clear all flags at once, use ``=_`` or ``-fslmpt``.
>
> -
> Debug messages during Boot Process
> ==================================
>
> @@ -393,3 +392,82 @@ just a shortcut for ``print_hex_dump(KERN_DEBUG)``.
> For ``print_hex_dump_debug()``/``print_hex_dump_bytes()``, format string is
> its ``prefix_str`` argument, if it is constant string; or ``hexdump``
> in case ``prefix_str`` is built dynamically.
> +
> +Dynamic Debug classmaps
> +=======================
> +
> +The "class" keyword selects prdbgs based on author supplied,
> +domain-oriented names. This complements the nested-scope keywords:
> +module, file, function, line.
> +
> +The main difference from the others: class'd prdbgs must be named to
> +be changed. This protects them from generic overwrite:
> +
> + # IOW this cannot undo any DRM.debug settings
> + :#> ddcmd -p
Patch 30/59 just dropped this behavior no?
> +So each class must be enabled individually (no wildcards):
> +
> + :#> ddcmd class DRM_UT_CORE +p
> + :#> ddcmd class DRM_UT_KMS +p
> + # or more selectively
> + :#> ddcmd class DRM_UT_CORE module drm +p
> +
> +Or the legacy/normal (more convenient) way:
> +
> + :#> echo 0x1ff > /sys/module/drm/parameters/debug
> +
> +Dynamic Debug Classmap API
> +==========================
> +
> +DRM.debug is built upon:
> + ~23 macros, all passing a DRM_UT_* constant as arg-1.
> + ~5000 calls to them, across drivers/gpu/drm/*
> + bits in /sys/module/drm/parameters/debug control all DRM_UT_* together
> +
> +The const short ints are good for optimizing compilers; a classmaps
> +design goal was to keep that. So basically .classid === category.
> +
> +And since prdbgs are cataloged with just a DRM_UT_* to identify them,
> +the "class" keyword maps known classnames to those reserved IDs, and
> +by explicitly requiring "class FOO" in queries, we protect FOO class'd
> +debugs from overwrite by generic queries.
> +
> +Its expected that other classmap users will also provide debug-macros
> +using an enum-defined categorization scheme like DRM's, and dyndbg can
> +be adapted under them similarly.
> +
> +DYNAMIC_DEBUG_CLASSMAP_DEFINE(var,type,_base,classnames) - this maps
> +classnames onto class-ids consecutively, starting at _base, it also
> +maps the names onto CLASSMAP_PARAM bits 0..N.
> +
> +DYNAMIC_DEBUG_CLASSMAP_USE(var) - modules call this to refer to the
> +var _DEFINEd elsewhere (and exported).
> +
> +Classmaps are opt-in: modules invoke _DEFINE or _USE to authorize
> +dyndbg to update those classes. "class FOO" queries are validated
> +against the classes, this finds the classid to alter; classes are not
> +directly selectable by their classid.
> +
> +There are 2 types of classmaps:
> +
> + DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, like DRM.debug
> + DD_CLASS_TYPE_LEVEL_NUM: classes are relative, ordered (V3 > V2)
> +
> +DYNAMIC_DEBUG_CLASSMAP_PARAM - modelled after module_param_cb, it
> +refers to a DEFINEd classmap, and associates it to the param's
> +data-store. This state is then applied to DEFINEr and USEr modules
> +when they're modprobed.
> +
> +The PARAM interface also enforces the DD_CLASS_TYPE_LEVEL_NUM relation
> +amongst the contained classnames; all classes are independent in the
> +control parser itself; there is no implied meaning in names like "V4".
> +
> +Modules or module-groups (drm & drivers) can define multiple
> +classmaps, as long as they share the limited 0..62 per-module-group
> +_class_id range, without overlap.
Maybe clarify that a driver using _USE macro should take care that he
only use distinct non-overlaping classmaps?
> +``#define DEBUG`` will enable all pr_debugs in scope, including any
> +class'd ones. This won't be reflected in the PARAM readback value,
> +but the class'd pr_debug callsites can be forced off by toggling the
> +classmap-kparam all-on then all-off.
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 33/59] docs/dyndbg: add classmap info to howto (TBD)
2025-03-24 15:23 ` Louis Chauvet
@ 2025-03-25 18:42 ` jim.cromie
0 siblings, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-25 18:42 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, linux-doc
On Mon, Mar 24, 2025 at 9:23 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>
>
>
> Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> > Describe the 3 API macros providing dynamic_debug's classmaps
> >
> > DYNDBG_CLASSMAP_DEFINE - create & export a classmap
...
> > +Dynamic Debug classmaps
> > +=======================
> > +
> > +The "class" keyword selects prdbgs based on author supplied,
> > +domain-oriented names. This complements the nested-scope keywords:
> > +module, file, function, line.
> > +
> > +The main difference from the others: class'd prdbgs must be named to
> > +be changed. This protects them from generic overwrite:
> > +
> > + # IOW this cannot undo any DRM.debug settings
> > + :#> ddcmd -p
>
> Patch 30/59 just dropped this behavior no?
Yes, that chunk is obsolete, given my capitulation :-/
>
> > +So each class must be enabled individually (no wildcards):
> > +
> > + :#> ddcmd class DRM_UT_CORE +p
> > + :#> ddcmd class DRM_UT_KMS +p
> > + # or more selectively
> > + :#> ddcmd class DRM_UT_CORE module drm +p
> > +
> > +Or the legacy/normal (more convenient) way:
> > +
> > + :#> echo 0x1ff > /sys/module/drm/parameters/debug
> > +
> > +Dynamic Debug Classmap API
> > +==========================
> > +
> > +DRM.debug is built upon:
> > + ~23 macros, all passing a DRM_UT_* constant as arg-1.
> > + ~5000 calls to them, across drivers/gpu/drm/*
> > + bits in /sys/module/drm/parameters/debug control all DRM_UT_* together
> > +
> > +The const short ints are good for optimizing compilers; a classmaps
> > +design goal was to keep that. So basically .classid === category.
> > +
> > +And since prdbgs are cataloged with just a DRM_UT_* to identify them,
> > +the "class" keyword maps known classnames to those reserved IDs, and
> > +by explicitly requiring "class FOO" in queries, we protect FOO class'd
> > +debugs from overwrite by generic queries.
> > +
> > +Its expected that other classmap users will also provide debug-macros
> > +using an enum-defined categorization scheme like DRM's, and dyndbg can
> > +be adapted under them similarly.
> > +
> > +DYNAMIC_DEBUG_CLASSMAP_DEFINE(var,type,_base,classnames) - this maps
> > +classnames onto class-ids consecutively, starting at _base, it also
> > +maps the names onto CLASSMAP_PARAM bits 0..N.
> > +
> > +DYNAMIC_DEBUG_CLASSMAP_USE(var) - modules call this to refer to the
> > +var _DEFINEd elsewhere (and exported).
> > +
> > +Classmaps are opt-in: modules invoke _DEFINE or _USE to authorize
> > +dyndbg to update those classes. "class FOO" queries are validated
> > +against the classes, this finds the classid to alter; classes are not
> > +directly selectable by their classid.
> > +
> > +There are 2 types of classmaps:
> > +
> > + DD_CLASS_TYPE_DISJOINT_BITS: classes are independent, like DRM.debug
> > + DD_CLASS_TYPE_LEVEL_NUM: classes are relative, ordered (V3 > V2)
> > +
> > +DYNAMIC_DEBUG_CLASSMAP_PARAM - modelled after module_param_cb, it
> > +refers to a DEFINEd classmap, and associates it to the param's
> > +data-store. This state is then applied to DEFINEr and USEr modules
> > +when they're modprobed.
> > +
> > +The PARAM interface also enforces the DD_CLASS_TYPE_LEVEL_NUM relation
> > +amongst the contained classnames; all classes are independent in the
> > +control parser itself; there is no implied meaning in names like "V4".
> > +
> > +Modules or module-groups (drm & drivers) can define multiple
> > +classmaps, as long as they share the limited 0..62 per-module-group
> > +_class_id range, without overlap.
>
> Maybe clarify that a driver using _USE macro should take care that he
> only use distinct non-overlaping classmaps?
ack
>
> > +``#define DEBUG`` will enable all pr_debugs in scope, including any
> > +class'd ones. This won't be reflected in the PARAM readback value,
> > +but the class'd pr_debug callsites can be forced off by toggling the
> > +classmap-kparam all-on then all-off.
>
> --
> Louis Chauvet, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (32 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 33/59] docs/dyndbg: add classmap info to howto (TBD) Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-21 3:14 ` Joe Perches
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 35/59] drm: use correct ccflags-y spelling Jim Cromie
` (24 subsequent siblings)
58 siblings, 2 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie,
Andy Whitcroft, Joe Perches, Dwaipayan Ray, Lukas Bulwahn
we currently get:
WARNING: Argument 'name' is not used in function-like macro
on:
#define DRM_CLASSMAP_USE(name) /* nothing here */
Following this advice is wrong here, and shouldn't be fixed by
ignoring args altogether; the macro should properly fail if invoked
with 0 or 2+ args.
cc: Andy Whitcroft <apw@canonical.com>
cc: Joe Perches <joe@perches.com>
cc: Dwaipayan Ray <dwaipayanray1@gmail.com>
cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
scripts/checkpatch.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 7b28ad331742..0c4f578ea6e7 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -6037,7 +6037,7 @@ sub process {
}
# check if this is an unused argument
- if ($define_stmt !~ /\b$arg\b/) {
+ if ($define_stmt !~ /\b$arg\b/ && $define_stmt) {
WARN("MACRO_ARG_UNUSED",
"Argument '$arg' is not used in function-like macro\n" . "$herectx");
}
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body
2025-03-20 18:52 ` [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body Jim Cromie
@ 2025-03-21 3:14 ` Joe Perches
2025-03-24 15:23 ` Louis Chauvet
1 sibling, 0 replies; 103+ messages in thread
From: Joe Perches @ 2025-03-21 3:14 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot, Andrew Morton
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Andy Whitcroft,
Dwaipayan Ray, Lukas Bulwahn
On Thu, 2025-03-20 at 12:52 -0600, Jim Cromie wrote:
> we currently get:
> WARNING: Argument 'name' is not used in function-like macro
> on:
> #define DRM_CLASSMAP_USE(name) /* nothing here */
>
> Following this advice is wrong here, and shouldn't be fixed by
> ignoring args altogether; the macro should properly fail if invoked
> with 0 or 2+ args.
>
> cc: Andy Whitcroft <apw@canonical.com>
> cc: Joe Perches <joe@perches.com>
> cc: Dwaipayan Ray <dwaipayanray1@gmail.com>
> cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Completely sensible, thanks Jim.
> ---
> scripts/checkpatch.pl | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index 7b28ad331742..0c4f578ea6e7 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -6037,7 +6037,7 @@ sub process {
> }
>
> # check if this is an unused argument
> - if ($define_stmt !~ /\b$arg\b/) {
> + if ($define_stmt !~ /\b$arg\b/ && $define_stmt) {
> WARN("MACRO_ARG_UNUSED",
> "Argument '$arg' is not used in function-like macro\n" . "$herectx");
> }
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body
2025-03-20 18:52 ` [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body Jim Cromie
2025-03-21 3:14 ` Joe Perches
@ 2025-03-24 15:23 ` Louis Chauvet
1 sibling, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala, Andy Whitcroft, Joe Perches,
Dwaipayan Ray, Lukas Bulwahn
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> we currently get:
> WARNING: Argument 'name' is not used in function-like macro
> on:
> #define DRM_CLASSMAP_USE(name) /* nothing here */
>
> Following this advice is wrong here, and shouldn't be fixed by
> ignoring args altogether; the macro should properly fail if invoked
> with 0 or 2+ args.
>
> cc: Andy Whitcroft <apw@canonical.com>
> cc: Joe Perches <joe@perches.com>
> cc: Dwaipayan Ray <dwaipayanray1@gmail.com>
> cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> scripts/checkpatch.pl | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index 7b28ad331742..0c4f578ea6e7 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -6037,7 +6037,7 @@ sub process {
> }
>
> # check if this is an unused argument
> - if ($define_stmt !~ /\b$arg\b/) {
> + if ($define_stmt !~ /\b$arg\b/ && $define_stmt) {
> WARN("MACRO_ARG_UNUSED",
> "Argument '$arg' is not used in function-like macro\n" . "$herectx");
> }
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 35/59] drm: use correct ccflags-y spelling
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (33 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 34/59] checkpatch: dont warn about unused macro arg on empty body Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 36/59] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2 Jim Cromie
` (23 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Incorrectly spelled CFLAGS- failed to add -DDYNAMIC_DEBUG_MODULE,
which disabled dynamic-debug in modules built with:
CONFIG_DYNAMIC_DEBUG=n # 1
CONFIG_DYNAMIC_DEBUG_CORE=y # 2
CONFIG_DRM_USE_DYNAMIC_DEBUG=y # 3
NB: this adds the flag (when 3) more often than strictly needed;
modules built with CONFIG_DYNAMIC_DEBUG=y (!1) don't need the flag.
Fixes: 84ec67288c10 ("drm_print: wrap drm_*_dbg in dyndbg descriptor factory macro")
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 19fb370fbc56..704f94efc804 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -3,7 +3,8 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
-CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
+ccflags-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
+subdir-ccflags-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
# Unconditionally enable W=1 warnings locally
# --- begin copy-paste W=1 warnings from scripts/Makefile.extrawarn
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 36/59] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (34 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 35/59] drm: use correct ccflags-y spelling Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 37/59] drm-dyndbg: adapt DRM to invoke DYNAMIC_DEBUG_CLASSMAP_PARAM Jim Cromie
` (22 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
dyndbg's CLASSMAP-v1 api was broken; DECLARE_DYNDBG_CLASSMAP tried to
do too much. Its replaced by DRM_CLASSMAP_DEFINE, which creates &
EXPORTs a classmap (in DRM core), and DRM_CLASSMAP_USE which refers to
the classmap defined elsewhere.
The drivers still use DECLARE_DYNDBG_CLASSMAP for now, so they still
redundantly re-declare the classmap, but we can convert the drivers
later to DYNDBG_CLASSMAP_USE
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
this ignores a checkpatch
WARNING: Argument 'name' is not used in function-like macro
#70: FILE: include/drm/drm_print.h:148:
+#define DRM_CLASSMAP_USE(name)
the macro is empty, and correct. only 1 arg is expected.
---
drivers/gpu/drm/drm_print.c | 25 +++++++++++++------------
include/drm/drm_print.h | 8 ++++++++
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 79517bd4418f..a3b70d104afa 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -55,18 +55,19 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
module_param_named(debug, __drm_debug, ulong, 0600);
#else
-/* classnames must match vals of enum drm_debug_category */
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "DRM_UT_CORE",
- "DRM_UT_DRIVER",
- "DRM_UT_KMS",
- "DRM_UT_PRIME",
- "DRM_UT_ATOMIC",
- "DRM_UT_VBL",
- "DRM_UT_STATE",
- "DRM_UT_LEASE",
- "DRM_UT_DP",
- "DRM_UT_DRMRES");
+/* classnames must match value-symbols of enum drm_debug_category */
+DRM_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS,
+ DRM_UT_CORE,
+ "DRM_UT_CORE",
+ "DRM_UT_DRIVER",
+ "DRM_UT_KMS",
+ "DRM_UT_PRIME",
+ "DRM_UT_ATOMIC",
+ "DRM_UT_VBL",
+ "DRM_UT_STATE",
+ "DRM_UT_LEASE",
+ "DRM_UT_DP",
+ "DRM_UT_DRMRES");
static struct ddebug_class_param drm_debug_bitmap = {
.bits = &__drm_debug,
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 9732f514566d..e86ebb716b4c 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -141,6 +141,14 @@ enum drm_debug_category {
DRM_UT_DRMRES
};
+#ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG
+#define DRM_CLASSMAP_DEFINE(...) DYNAMIC_DEBUG_CLASSMAP_DEFINE(__VA_ARGS__)
+#define DRM_CLASSMAP_USE(name) DYNAMIC_DEBUG_CLASSMAP_USE(name)
+#else
+#define DRM_CLASSMAP_DEFINE(...)
+#define DRM_CLASSMAP_USE(name)
+#endif
+
static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
{
return unlikely(__drm_debug & BIT(category));
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 36/59] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2
2025-03-20 18:52 ` [PATCH v2 36/59] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2 Jim Cromie
@ 2025-03-24 15:23 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> dyndbg's CLASSMAP-v1 api was broken; DECLARE_DYNDBG_CLASSMAP tried to
> do too much. Its replaced by DRM_CLASSMAP_DEFINE, which creates &
> EXPORTs a classmap (in DRM core), and DRM_CLASSMAP_USE which refers to
> the classmap defined elsewhere.
>
> The drivers still use DECLARE_DYNDBG_CLASSMAP for now, so they still
> redundantly re-declare the classmap, but we can convert the drivers
> later to DYNDBG_CLASSMAP_USE
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> this ignores a checkpatch
> WARNING: Argument 'name' is not used in function-like macro
> #70: FILE: include/drm/drm_print.h:148:
> +#define DRM_CLASSMAP_USE(name)
>
> the macro is empty, and correct. only 1 arg is expected.
The patch to remove this warning is before, so I think this is not an
issue anymore.
> ---
> drivers/gpu/drm/drm_print.c | 25 +++++++++++++------------
> include/drm/drm_print.h | 8 ++++++++
> 2 files changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> index 79517bd4418f..a3b70d104afa 100644
> --- a/drivers/gpu/drm/drm_print.c
> +++ b/drivers/gpu/drm/drm_print.c
> @@ -55,18 +55,19 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
> #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
> module_param_named(debug, __drm_debug, ulong, 0600);
> #else
> -/* classnames must match vals of enum drm_debug_category */
> -DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> - "DRM_UT_CORE",
> - "DRM_UT_DRIVER",
> - "DRM_UT_KMS",
> - "DRM_UT_PRIME",
> - "DRM_UT_ATOMIC",
> - "DRM_UT_VBL",
> - "DRM_UT_STATE",
> - "DRM_UT_LEASE",
> - "DRM_UT_DP",
> - "DRM_UT_DRMRES");
> +/* classnames must match value-symbols of enum drm_debug_category */
> +DRM_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS,
> + DRM_UT_CORE,
> + "DRM_UT_CORE",
> + "DRM_UT_DRIVER",
> + "DRM_UT_KMS",
> + "DRM_UT_PRIME",
> + "DRM_UT_ATOMIC",
> + "DRM_UT_VBL",
> + "DRM_UT_STATE",
> + "DRM_UT_LEASE",
> + "DRM_UT_DP",
> + "DRM_UT_DRMRES");
>
> static struct ddebug_class_param drm_debug_bitmap = {
> .bits = &__drm_debug,
> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> index 9732f514566d..e86ebb716b4c 100644
> --- a/include/drm/drm_print.h
> +++ b/include/drm/drm_print.h
> @@ -141,6 +141,14 @@ enum drm_debug_category {
> DRM_UT_DRMRES
> };
>
> +#ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG
> +#define DRM_CLASSMAP_DEFINE(...) DYNAMIC_DEBUG_CLASSMAP_DEFINE(__VA_ARGS__)
> +#define DRM_CLASSMAP_USE(name) DYNAMIC_DEBUG_CLASSMAP_USE(name)
> +#else
> +#define DRM_CLASSMAP_DEFINE(...)
> +#define DRM_CLASSMAP_USE(name)
> +#endif
> +
> static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
> {
> return unlikely(__drm_debug & BIT(category));
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 37/59] drm-dyndbg: adapt DRM to invoke DYNAMIC_DEBUG_CLASSMAP_PARAM
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (35 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 36/59] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2 Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 38/59] drm-print: fix config-dependent unused variable Jim Cromie
` (21 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Invoke DYNAMIC_DEBUG_CLASSMAP_PARAM to hook drm.debug (__drm_debug) to the
DRM_UT_* classmap, replacing the ad-hoc wiring previously doing it.
Add DRM_CLASSMAP_* adapter macros to selectively use
DYNAMIC_DEBUG_CLASSMAP_* when DRM_USE_DYNAMIC_DEBUG=y is configured.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/drm_print.c | 8 ++------
include/drm/drm_print.h | 4 ++++
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index a3b70d104afa..46d53fe30204 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -69,12 +69,8 @@ DRM_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS,
"DRM_UT_DP",
"DRM_UT_DRMRES");
-static struct ddebug_class_param drm_debug_bitmap = {
- .bits = &__drm_debug,
- .flags = "p",
- .map = &drm_debug_classes,
-};
-module_param_cb(debug, ¶m_ops_dyndbg_classes, &drm_debug_bitmap, 0600);
+DRM_CLASSMAP_PARAM_REF(debug, __drm_debug, drm_debug_classes, p);
+
#endif
void __drm_puts_coredump(struct drm_printer *p, const char *str)
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index e86ebb716b4c..8758449491b8 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -144,9 +144,13 @@ enum drm_debug_category {
#ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG
#define DRM_CLASSMAP_DEFINE(...) DYNAMIC_DEBUG_CLASSMAP_DEFINE(__VA_ARGS__)
#define DRM_CLASSMAP_USE(name) DYNAMIC_DEBUG_CLASSMAP_USE(name)
+#define DRM_CLASSMAP_PARAM_REF(...) DYNAMIC_DEBUG_CLASSMAP_PARAM_REF(__VA_ARGS__)
+#define DRM_CLASSMAP_PARAM(...) DYNAMIC_DEBUG_CLASSMAP_PARAM(__VA_ARGS__)
#else
#define DRM_CLASSMAP_DEFINE(...)
#define DRM_CLASSMAP_USE(name)
+#define DRM_CLASSMAP_PARAM_REF(...)
+#define DRM_CLASSMAP_PARAM(...)
#endif
static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 37/59] drm-dyndbg: adapt DRM to invoke DYNAMIC_DEBUG_CLASSMAP_PARAM
2025-03-20 18:52 ` [PATCH v2 37/59] drm-dyndbg: adapt DRM to invoke DYNAMIC_DEBUG_CLASSMAP_PARAM Jim Cromie
@ 2025-03-24 15:23 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Invoke DYNAMIC_DEBUG_CLASSMAP_PARAM to hook drm.debug (__drm_debug) to the
> DRM_UT_* classmap, replacing the ad-hoc wiring previously doing it.
>
> Add DRM_CLASSMAP_* adapter macros to selectively use
> DYNAMIC_DEBUG_CLASSMAP_* when DRM_USE_DYNAMIC_DEBUG=y is configured.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/drm_print.c | 8 ++------
> include/drm/drm_print.h | 4 ++++
> 2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> index a3b70d104afa..46d53fe30204 100644
> --- a/drivers/gpu/drm/drm_print.c
> +++ b/drivers/gpu/drm/drm_print.c
> @@ -69,12 +69,8 @@ DRM_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS,
> "DRM_UT_DP",
> "DRM_UT_DRMRES");
>
> -static struct ddebug_class_param drm_debug_bitmap = {
> - .bits = &__drm_debug,
> - .flags = "p",
> - .map = &drm_debug_classes,
> -};
> -module_param_cb(debug, ¶m_ops_dyndbg_classes, &drm_debug_bitmap, 0600);
> +DRM_CLASSMAP_PARAM_REF(debug, __drm_debug, drm_debug_classes, p);
> +
> #endif
>
> void __drm_puts_coredump(struct drm_printer *p, const char *str)
> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> index e86ebb716b4c..8758449491b8 100644
> --- a/include/drm/drm_print.h
> +++ b/include/drm/drm_print.h
> @@ -144,9 +144,13 @@ enum drm_debug_category {
> #ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG
> #define DRM_CLASSMAP_DEFINE(...) DYNAMIC_DEBUG_CLASSMAP_DEFINE(__VA_ARGS__)
> #define DRM_CLASSMAP_USE(name) DYNAMIC_DEBUG_CLASSMAP_USE(name)
> +#define DRM_CLASSMAP_PARAM_REF(...) DYNAMIC_DEBUG_CLASSMAP_PARAM_REF(__VA_ARGS__)
> +#define DRM_CLASSMAP_PARAM(...) DYNAMIC_DEBUG_CLASSMAP_PARAM(__VA_ARGS__)
> #else
> #define DRM_CLASSMAP_DEFINE(...)
> #define DRM_CLASSMAP_USE(name)
> +#define DRM_CLASSMAP_PARAM_REF(...)
> +#define DRM_CLASSMAP_PARAM(...)
> #endif
>
> static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 38/59] drm-print: fix config-dependent unused variable
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (36 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 37/59] drm-dyndbg: adapt DRM to invoke DYNAMIC_DEBUG_CLASSMAP_PARAM Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 39/59] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver Jim Cromie
` (20 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
With CONFIG_DRM_USE_DYNAMIC_DEBUG=y, __drm_printfn_dbg() gets an
unused variable warning/error on 'category', even though the usage
follows immediately, in drm_debug_enabled(category).
For static-key optimized dyndbg, the macro doesn't actually check the
category var, since the static-key patches in the proper state. The
compiler evidently sees this lack of reference and complains.
So this drops the local var and refs the field directly in the
macro-call, which avoids the warning/error.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/drm_print.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 46d53fe30204..41ad11247b48 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -212,9 +212,8 @@ void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf)
{
const struct drm_device *drm = p->arg;
const struct device *dev = drm ? drm->dev : NULL;
- enum drm_debug_category category = p->category;
- if (!__drm_debug_enabled(category))
+ if (!__drm_debug_enabled(p->category))
return;
__drm_dev_vprintk(dev, KERN_DEBUG, p->origin, p->prefix, vaf);
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 38/59] drm-print: fix config-dependent unused variable
2025-03-20 18:52 ` [PATCH v2 38/59] drm-print: fix config-dependent unused variable Jim Cromie
@ 2025-03-24 15:23 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> With CONFIG_DRM_USE_DYNAMIC_DEBUG=y, __drm_printfn_dbg() gets an
> unused variable warning/error on 'category', even though the usage
> follows immediately, in drm_debug_enabled(category).
>
> For static-key optimized dyndbg, the macro doesn't actually check the
> category var, since the static-key patches in the proper state. The
> compiler evidently sees this lack of reference and complains.
>
> So this drops the local var and refs the field directly in the
> macro-call, which avoids the warning/error.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
I believe I can merge it before the entire series. Does anyone have any
objections?
> ---
> drivers/gpu/drm/drm_print.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
> index 46d53fe30204..41ad11247b48 100644
> --- a/drivers/gpu/drm/drm_print.c
> +++ b/drivers/gpu/drm/drm_print.c
> @@ -212,9 +212,8 @@ void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf)
> {
> const struct drm_device *drm = p->arg;
> const struct device *dev = drm ? drm->dev : NULL;
> - enum drm_debug_category category = p->category;
>
> - if (!__drm_debug_enabled(category))
> + if (!__drm_debug_enabled(p->category))
> return;
>
> __drm_dev_vprintk(dev, KERN_DEBUG, p->origin, p->prefix, vaf);
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 39/59] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (37 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 38/59] drm-print: fix config-dependent unused variable Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:24 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 40/59] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver Jim Cromie
` (19 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
than re-declaring it redundantly, and error-prone-ly.
This resolves the appearance of "class:_UNKNOWN_" in the control file
for the driver's drm_dbg()s.
Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index c0ddbe7d6f0b..e1367f66c4d2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -234,17 +234,7 @@ int amdgpu_wbrf = -1;
int amdgpu_damage_clips = -1; /* auto */
int amdgpu_umsch_mm_fwlog;
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "DRM_UT_CORE",
- "DRM_UT_DRIVER",
- "DRM_UT_KMS",
- "DRM_UT_PRIME",
- "DRM_UT_ATOMIC",
- "DRM_UT_VBL",
- "DRM_UT_STATE",
- "DRM_UT_LEASE",
- "DRM_UT_DP",
- "DRM_UT_DRMRES");
+DRM_CLASSMAP_USE(drm_debug_classes);
struct amdgpu_mgpu_info mgpu_info = {
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 39/59] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver
2025-03-20 18:52 ` [PATCH v2 39/59] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver Jim Cromie
@ 2025-03-24 15:24 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:24 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
> DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
> than re-declaring it redundantly, and error-prone-ly.
>
> This resolves the appearance of "class:_UNKNOWN_" in the control file
> for the driver's drm_dbg()s.
>
> Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 +-----------
> 1 file changed, 1 insertion(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index c0ddbe7d6f0b..e1367f66c4d2 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -234,17 +234,7 @@ int amdgpu_wbrf = -1;
> int amdgpu_damage_clips = -1; /* auto */
> int amdgpu_umsch_mm_fwlog;
>
> -DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> - "DRM_UT_CORE",
> - "DRM_UT_DRIVER",
> - "DRM_UT_KMS",
> - "DRM_UT_PRIME",
> - "DRM_UT_ATOMIC",
> - "DRM_UT_VBL",
> - "DRM_UT_STATE",
> - "DRM_UT_LEASE",
> - "DRM_UT_DP",
> - "DRM_UT_DRMRES");
> +DRM_CLASSMAP_USE(drm_debug_classes);
>
> struct amdgpu_mgpu_info mgpu_info = {
> .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 40/59] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (38 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 39/59] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:24 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 41/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper Jim Cromie
` (18 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
than re-declaring it redundantly, and error-prone-ly.
This resolves the appearance of "class:_UNKNOWN_" in the control file
for the driver's drm_dbg()s.
Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/i915/i915_params.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 37746dd619fd..2dc0e2c06e09 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -29,17 +29,7 @@
#include "i915_params.h"
#include "i915_drv.h"
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "DRM_UT_CORE",
- "DRM_UT_DRIVER",
- "DRM_UT_KMS",
- "DRM_UT_PRIME",
- "DRM_UT_ATOMIC",
- "DRM_UT_VBL",
- "DRM_UT_STATE",
- "DRM_UT_LEASE",
- "DRM_UT_DP",
- "DRM_UT_DRMRES");
+DRM_CLASSMAP_USE(drm_debug_classes);
#define i915_param_named(name, T, perm, desc) \
module_param_named(name, i915_modparams.name, T, perm); \
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 40/59] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver
2025-03-20 18:52 ` [PATCH v2 40/59] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver Jim Cromie
@ 2025-03-24 15:24 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:24 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
> DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
> than re-declaring it redundantly, and error-prone-ly.
>
> This resolves the appearance of "class:_UNKNOWN_" in the control file
> for the driver's drm_dbg()s.
>
> Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/i915/i915_params.c | 12 +-----------
> 1 file changed, 1 insertion(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
> index 37746dd619fd..2dc0e2c06e09 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -29,17 +29,7 @@
> #include "i915_params.h"
> #include "i915_drv.h"
>
> -DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> - "DRM_UT_CORE",
> - "DRM_UT_DRIVER",
> - "DRM_UT_KMS",
> - "DRM_UT_PRIME",
> - "DRM_UT_ATOMIC",
> - "DRM_UT_VBL",
> - "DRM_UT_STATE",
> - "DRM_UT_LEASE",
> - "DRM_UT_DP",
> - "DRM_UT_DRMRES");
> +DRM_CLASSMAP_USE(drm_debug_classes);
>
> #define i915_param_named(name, T, perm, desc) \
> module_param_named(name, i915_modparams.name, T, perm); \
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 41/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (39 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 40/59] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:23 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 42/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper Jim Cromie
` (17 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
than re-declaring it redundantly, and error-prone-ly.
This resolves the appearance of "class:_UNKNOWN_" in the control file
for the driver's drm_dbg()s.
Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/drm_crtc_helper.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 0955f1c385dd..1d08d759f238 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -50,17 +50,7 @@
#include "drm_crtc_helper_internal.h"
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "DRM_UT_CORE",
- "DRM_UT_DRIVER",
- "DRM_UT_KMS",
- "DRM_UT_PRIME",
- "DRM_UT_ATOMIC",
- "DRM_UT_VBL",
- "DRM_UT_STATE",
- "DRM_UT_LEASE",
- "DRM_UT_DP",
- "DRM_UT_DRMRES");
+DRM_CLASSMAP_USE(drm_debug_classes);
/**
* DOC: overview
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 41/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper
2025-03-20 18:52 ` [PATCH v2 41/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper Jim Cromie
@ 2025-03-24 15:23 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:23 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
> DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
> than re-declaring it redundantly, and error-prone-ly.
>
> This resolves the appearance of "class:_UNKNOWN_" in the control file
> for the driver's drm_dbg()s.
>
> Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/drm_crtc_helper.c | 12 +-----------
> 1 file changed, 1 insertion(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index 0955f1c385dd..1d08d759f238 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -50,17 +50,7 @@
>
> #include "drm_crtc_helper_internal.h"
>
> -DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> - "DRM_UT_CORE",
> - "DRM_UT_DRIVER",
> - "DRM_UT_KMS",
> - "DRM_UT_PRIME",
> - "DRM_UT_ATOMIC",
> - "DRM_UT_VBL",
> - "DRM_UT_STATE",
> - "DRM_UT_LEASE",
> - "DRM_UT_DP",
> - "DRM_UT_DRMRES");
> +DRM_CLASSMAP_USE(drm_debug_classes);
>
> /**
> * DOC: overview
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 42/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (40 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 41/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:24 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 43/59] drm-dyndbg: DRM_CLASSMAP_USE in nouveau Jim Cromie
` (16 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
than re-declaring it redundantly, and error-prone-ly.
This resolves the appearance of "class:_UNKNOWN_" in the control file
for the driver's drm_dbg()s.
Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/display/drm_dp_helper.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 61c7c2c588c6..68ba17eb2541 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -43,17 +43,7 @@
#include "drm_dp_helper_internal.h"
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "DRM_UT_CORE",
- "DRM_UT_DRIVER",
- "DRM_UT_KMS",
- "DRM_UT_PRIME",
- "DRM_UT_ATOMIC",
- "DRM_UT_VBL",
- "DRM_UT_STATE",
- "DRM_UT_LEASE",
- "DRM_UT_DP",
- "DRM_UT_DRMRES");
+DRM_CLASSMAP_USE(drm_debug_classes);
struct dp_aux_backlight {
struct backlight_device *base;
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 42/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper
2025-03-20 18:52 ` [PATCH v2 42/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper Jim Cromie
@ 2025-03-24 15:24 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:24 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
> DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
> than re-declaring it redundantly, and error-prone-ly.
>
> This resolves the appearance of "class:_UNKNOWN_" in the control file
> for the driver's drm_dbg()s.
>
> Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/display/drm_dp_helper.c | 12 +-----------
> 1 file changed, 1 insertion(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
> index 61c7c2c588c6..68ba17eb2541 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -43,17 +43,7 @@
>
> #include "drm_dp_helper_internal.h"
>
> -DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
> - "DRM_UT_CORE",
> - "DRM_UT_DRIVER",
> - "DRM_UT_KMS",
> - "DRM_UT_PRIME",
> - "DRM_UT_ATOMIC",
> - "DRM_UT_VBL",
> - "DRM_UT_STATE",
> - "DRM_UT_LEASE",
> - "DRM_UT_DP",
> - "DRM_UT_DRMRES");
> +DRM_CLASSMAP_USE(drm_debug_classes);
>
> struct dp_aux_backlight {
> struct backlight_device *base;
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 43/59] drm-dyndbg: DRM_CLASSMAP_USE in nouveau
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (41 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 42/59] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 44/59] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver Jim Cromie
` (15 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Following the dyndbg-api-fix, replace DECLARE_DYNDBG_CLASSMAP with
DRM_CLASSMAP_USE. This refs the defined & exported classmap, rather
than re-declaring it redundantly, and error-prone-ly.
This resolves the appearance of "class:_UNKNOWN_" in the control file
for the driver's drm_dbg()s.
Fixes: f158936b60a7 ("drm: POC drm on dyndbg - use in core, 2 helpers, 3 drivers.")
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/nouveau/nouveau_drm.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 5664c4c71faf..bdecd27efabf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -74,17 +74,7 @@
#include "nouveau_uvmm.h"
#include "nouveau_sched.h"
-DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
- "DRM_UT_CORE",
- "DRM_UT_DRIVER",
- "DRM_UT_KMS",
- "DRM_UT_PRIME",
- "DRM_UT_ATOMIC",
- "DRM_UT_VBL",
- "DRM_UT_STATE",
- "DRM_UT_LEASE",
- "DRM_UT_DP",
- "DRM_UT_DRMRES");
+DRM_CLASSMAP_USE(drm_debug_classes);
MODULE_PARM_DESC(config, "option string to pass to driver core");
static char *nouveau_config;
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 44/59] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (42 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 43/59] drm-dyndbg: DRM_CLASSMAP_USE in nouveau Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:24 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 45/59] drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu Jim Cromie
` (14 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Invoke DRM_CLASSMAP_USE from xe_drm_client.c. When built with
CONFIG_DRM_USE_DYNAMIC_DEBUG=y, this tells dydnbg that Xe uses
has drm.debug calls.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/xe/xe_drm_client.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c
index 2d4874d2b922..756dba5c88f8 100644
--- a/drivers/gpu/drm/xe/xe_drm_client.c
+++ b/drivers/gpu/drm/xe/xe_drm_client.c
@@ -21,6 +21,8 @@
#include "xe_pm.h"
#include "xe_trace.h"
+DRM_CLASSMAP_USE(drm_debug_classes);
+
/**
* DOC: DRM Client usage stats
*
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 44/59] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver
2025-03-20 18:52 ` [PATCH v2 44/59] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver Jim Cromie
@ 2025-03-24 15:24 ` Louis Chauvet
2025-03-25 18:56 ` jim.cromie
0 siblings, 1 reply; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:24 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Invoke DRM_CLASSMAP_USE from xe_drm_client.c. When built with
> CONFIG_DRM_USE_DYNAMIC_DEBUG=y, this tells dydnbg that Xe uses
> has drm.debug calls.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> drivers/gpu/drm/xe/xe_drm_client.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c
> index 2d4874d2b922..756dba5c88f8 100644
> --- a/drivers/gpu/drm/xe/xe_drm_client.c
> +++ b/drivers/gpu/drm/xe/xe_drm_client.c
> @@ -21,6 +21,8 @@
> #include "xe_pm.h"
> #include "xe_trace.h"
>
> +DRM_CLASSMAP_USE(drm_debug_classes);
> +
Is xe_drm_client.c the best place to do it? I think the module entry
point is a bit better [1].
[1]:https://elixir.bootlin.com/linux/v6.13.7/source/drivers/gpu/drm/xe/xe_module.c
> /**
> * DOC: DRM Client usage stats
> *
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 44/59] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver
2025-03-24 15:24 ` Louis Chauvet
@ 2025-03-25 18:56 ` jim.cromie
0 siblings, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-25 18:56 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
On Mon, Mar 24, 2025 at 9:24 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>
>
>
> Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> > Invoke DRM_CLASSMAP_USE from xe_drm_client.c. When built with
> > CONFIG_DRM_USE_DYNAMIC_DEBUG=y, this tells dydnbg that Xe uses
> > has drm.debug calls.
> >
> > Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> > ---
> > drivers/gpu/drm/xe/xe_drm_client.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c
> > index 2d4874d2b922..756dba5c88f8 100644
> > --- a/drivers/gpu/drm/xe/xe_drm_client.c
> > +++ b/drivers/gpu/drm/xe/xe_drm_client.c
> > @@ -21,6 +21,8 @@
> > #include "xe_pm.h"
> > #include "xe_trace.h"
> >
> > +DRM_CLASSMAP_USE(drm_debug_classes);
> > +
>
> Is xe_drm_client.c the best place to do it? I think the module entry
> point is a bit better [1].
>
yes perhaps. I was drawn by the _client in the file-name.
Im not sure Im fully consistent, iirc the drivers get it near driver-iinit ops.
> [1]:https://elixir.bootlin.com/linux/v6.13.7/source/drivers/gpu/drm/xe/xe_module.c
>
> > /**
> > * DOC: DRM Client usage stats
> > *
>
> --
> Louis Chauvet, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 45/59] drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (43 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 44/59] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 46/59] drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm Jim Cromie
` (13 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
virtio_gpu has 10 DRM_UT_CORE debugs, make them controllable when
CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
class'd debugs.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/virtio/virtgpu_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 6a67c6297d58..3bc4e6694fc2 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -45,6 +45,8 @@ static const struct drm_driver driver;
static int virtio_gpu_modeset = -1;
+DRM_CLASSMAP_USE(drm_debug_classes);
+
MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
module_param_named(modeset, virtio_gpu_modeset, int, 0400);
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 46/59] drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (44 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 45/59] drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 47/59] drm-dyndbg: add DRM_CLASSMAP_USE to bochs Jim Cromie
` (12 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
tiny/simpledrm has 3 DRM_UT_DRIVER debugs, make them controllable when
CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
class'd debugs.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/tiny/simpledrm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 5d9ab8adf800..bcf2cccac0ec 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -34,6 +34,8 @@
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
+DRM_CLASSMAP_USE(drm_debug_classes);
+
/*
* Helpers for simplefb
*/
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 47/59] drm-dyndbg: add DRM_CLASSMAP_USE to bochs
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (45 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 46/59] drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:03 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 48/59] drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv Jim Cromie
` (11 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
tiny/bochs has 5 DRM_UT_* debugs, make them controllable when
CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
class'd debugs.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/tiny/bochs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index 8706763af8fb..dbcc8ba70dfa 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -59,6 +59,8 @@ static int bochs_modeset = -1;
static int defx = 1024;
static int defy = 768;
+DRM_CLASSMAP_USE(drm_debug_classes);
+
module_param_named(modeset, bochs_modeset, int, 0444);
MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 47/59] drm-dyndbg: add DRM_CLASSMAP_USE to bochs
2025-03-20 18:52 ` [PATCH v2 47/59] drm-dyndbg: add DRM_CLASSMAP_USE to bochs Jim Cromie
@ 2025-03-24 15:03 ` Louis Chauvet
2025-03-25 19:34 ` jim.cromie
0 siblings, 1 reply; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:03 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> tiny/bochs has 5 DRM_UT_* debugs, make them controllable when
> CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
> class'd debugs.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/tiny/bochs.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
> index 8706763af8fb..dbcc8ba70dfa 100644
> --- a/drivers/gpu/drm/tiny/bochs.c
> +++ b/drivers/gpu/drm/tiny/bochs.c
> @@ -59,6 +59,8 @@ static int bochs_modeset = -1;
> static int defx = 1024;
> static int defy = 768;
>
> +DRM_CLASSMAP_USE(drm_debug_classes);
Do we need to add it for each driver that use drm_* print macros? Is it
reasonable to add this directly in drm_print.h, so there is no way to
miss this call if you use drm_* macros.
> module_param_named(modeset, bochs_modeset, int, 0444);
> MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* Re: [PATCH v2 47/59] drm-dyndbg: add DRM_CLASSMAP_USE to bochs
2025-03-24 15:03 ` Louis Chauvet
@ 2025-03-25 19:34 ` jim.cromie
0 siblings, 0 replies; 103+ messages in thread
From: jim.cromie @ 2025-03-25 19:34 UTC (permalink / raw)
To: Louis Chauvet
Cc: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot, jbaron, gregkh, ukaszb, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala
On Mon, Mar 24, 2025 at 9:03 AM Louis Chauvet <louis.chauvet@bootlin.com> wrote:
>
>
>
> Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> > tiny/bochs has 5 DRM_UT_* debugs, make them controllable when
> > CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
> > class'd debugs.
> >
> > Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
>
> Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
>
> > ---
> > drivers/gpu/drm/tiny/bochs.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
> > index 8706763af8fb..dbcc8ba70dfa 100644
> > --- a/drivers/gpu/drm/tiny/bochs.c
> > +++ b/drivers/gpu/drm/tiny/bochs.c
> > @@ -59,6 +59,8 @@ static int bochs_modeset = -1;
> > static int defx = 1024;
> > static int defy = 768;
> >
> > +DRM_CLASSMAP_USE(drm_debug_classes);
>
> Do we need to add it for each driver that use drm_* print macros? Is it
> reasonable to add this directly in drm_print.h, so there is no way to
> miss this call if you use drm_* macros.
>
Yes, AFAIK.
Ive tried to invoke declarators from a header,
It never works out.
59/59 was an attempt to do it for everyone, but it falls down...
> > module_param_named(modeset, bochs_modeset, int, 0444);
> > MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
> >
>
> --
> Louis Chauvet, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
>
>
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 48/59] drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (46 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 47/59] drm-dyndbg: add DRM_CLASSMAP_USE to bochs Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 49/59] drm-dyndbg: add DRM_CLASSMAP_USE to gma500 driver Jim Cromie
` (10 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
etnaviv has 5 DRM_UT_CORE debugs, make them controllable when
CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
class'd debugs as well as plain-old pr_debug()s
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/etnaviv/etnaviv_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 3e91747ed339..70759b7d338f 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -25,6 +25,8 @@
#include "etnaviv_mmu.h"
#include "etnaviv_perfmon.h"
+DRM_CLASSMAP_USE(drm_debug_classes);
+
/*
* DRM operations:
*/
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 49/59] drm-dyndbg: add DRM_CLASSMAP_USE to gma500 driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (47 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 48/59] drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 50/59] drm-dyndbg: add DRM_CLASSMAP_USE to radeon Jim Cromie
` (9 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The gma500 has 126 DRM_UT_* debugs, make them controllable when
CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg that the module has
class'd debugs.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/gma500/psb_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 85d3557c2eb9..dc72388ed08d 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -40,6 +40,8 @@
static const struct drm_driver driver;
static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+DRM_CLASSMAP_USE(drm_debug_classes);
+
/*
* The table below contains a mapping of the PCI vendor ID and the PCI Device ID
* to the different groups of PowerVR 5-series chip designs
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 50/59] drm-dyndbg: add DRM_CLASSMAP_USE to radeon
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (48 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 49/59] drm-dyndbg: add DRM_CLASSMAP_USE to gma500 driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 51/59] drm-dyndbg: add DRM_CLASSMAP_USE to vmwgfx driver Jim Cromie
` (8 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
radeon has some DRM_UT_* debugs, make them controllable when
CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg about its use of
the class'd debugs.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/radeon/radeon_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 267f082bc430..6eaac728e966 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -253,6 +253,8 @@ static const struct pci_device_id pciidlist[] = {
};
MODULE_DEVICE_TABLE(pci, pciidlist);
+DRM_CLASSMAP_USE(drm_debug_classes);
+
static const struct drm_driver kms_driver;
static int radeon_pci_probe(struct pci_dev *pdev,
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 51/59] drm-dyndbg: add DRM_CLASSMAP_USE to vmwgfx driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (49 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 50/59] drm-dyndbg: add DRM_CLASSMAP_USE to radeon Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 52/59] drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver Jim Cromie
` (7 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The vmwgfx driver has a number of DRM_UT_* debugs, make them
controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 0f32471c8533..2b4f862fe5d4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -279,6 +279,8 @@ static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
void *ptr);
+DRM_CLASSMAP_USE(drm_debug_classes);
+
MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages");
module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600);
MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 52/59] drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (50 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 51/59] drm-dyndbg: add DRM_CLASSMAP_USE to vmwgfx driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:00 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 53/59] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver Jim Cromie
` (6 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The vkms driver has a number of DRM_UT_* debugs, make them
controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/vkms/vkms_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index e0409aba9349..4b9da64661fb 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -39,6 +39,8 @@
static struct vkms_config *default_config;
+DRM_CLASSMAP_USE(drm_debug_classes);
+
static bool enable_cursor = true;
module_param_named(enable_cursor, enable_cursor, bool, 0444);
MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 52/59] drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver
2025-03-20 18:52 ` [PATCH v2 52/59] drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver Jim Cromie
@ 2025-03-24 15:00 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:00 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> The vkms driver has a number of DRM_UT_* debugs, make them
> controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
> that the module uses them.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_drv.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
> index e0409aba9349..4b9da64661fb 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.c
> +++ b/drivers/gpu/drm/vkms/vkms_drv.c
> @@ -39,6 +39,8 @@
>
> static struct vkms_config *default_config;
>
> +DRM_CLASSMAP_USE(drm_debug_classes);
> +
> static bool enable_cursor = true;
> module_param_named(enable_cursor, enable_cursor, bool, 0444);
> MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 53/59] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (51 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 52/59] drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:00 ` Louis Chauvet
2025-03-20 18:52 ` [PATCH v2 54/59] drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver Jim Cromie
` (5 subsequent siblings)
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The udl driver has a number of DRM_UT_* debugs, make them
controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/udl/udl_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 3ebe2ce55dfd..ba57c14454e5 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -19,6 +19,8 @@
#define NR_USB_REQUEST_CHANNEL 0x12
+DRM_CLASSMAP_USE(drm_debug_classes);
+
#define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
#define WRITES_IN_FLIGHT (20)
#define MAX_VENDOR_DESCRIPTOR_SIZE 256
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 53/59] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver
2025-03-20 18:52 ` [PATCH v2 53/59] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver Jim Cromie
@ 2025-03-24 15:00 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:00 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> The udl driver has a number of DRM_UT_* debugs, make them
> controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
> that the module uses them.
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> drivers/gpu/drm/udl/udl_main.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
> index 3ebe2ce55dfd..ba57c14454e5 100644
> --- a/drivers/gpu/drm/udl/udl_main.c
> +++ b/drivers/gpu/drm/udl/udl_main.c
> @@ -19,6 +19,8 @@
>
> #define NR_USB_REQUEST_CHANNEL 0x12
>
> +DRM_CLASSMAP_USE(drm_debug_classes);
ditto, is it better to put it near the module entry point [1]?
[1]:https://elixir.bootlin.com/linux/v6.13.7/source/drivers/gpu/drm/udl/udl_drv.c
> +
> #define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
> #define WRITES_IN_FLIGHT (20)
> #define MAX_VENDOR_DESCRIPTOR_SIZE 256
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread
* [PATCH v2 54/59] drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (52 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 53/59] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 55/59] drm-dyndbg: add DRM_CLASSMAP_USE to the gud driver Jim Cromie
` (4 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The mgag200 driver has a number of DRM_UT_* debugs, make them
controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/mgag200/mgag200_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 069fdd2dc8f6..5b6ec1550da3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -27,6 +27,8 @@ static int mgag200_modeset = -1;
MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
module_param_named(modeset, mgag200_modeset, int, 0400);
+DRM_CLASSMAP_USE(drm_debug_classes);
+
int mgag200_init_pci_options(struct pci_dev *pdev, u32 option, u32 option2)
{
struct device *dev = &pdev->dev;
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 55/59] drm-dyndbg: add DRM_CLASSMAP_USE to the gud driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (53 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 54/59] drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 56/59] drm-dyndbg: add DRM_CLASSMAP_USE to the qxl driver Jim Cromie
` (3 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The gud driver has a number of DRM_UT_* debugs, make them
controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/gud/gud_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index cb405771d6e2..3843c0e47169 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -32,6 +32,8 @@
#include "gud_internal.h"
+DRM_CLASSMAP_USE(drm_debug_classes);
+
/* Only used internally */
static const struct drm_format_info gud_drm_format_r1 = {
.format = GUD_DRM_FORMAT_R1,
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 56/59] drm-dyndbg: add DRM_CLASSMAP_USE to the qxl driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (54 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 55/59] drm-dyndbg: add DRM_CLASSMAP_USE to the gud driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 57/59] drm-dyndbg: add DRM_CLASSMAP_USE to the drm_gem_shmem_helper driver Jim Cromie
` (2 subsequent siblings)
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The qxl driver has a number of DRM_UT_* debugs, make them
controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling dyndbg
that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/qxl/qxl_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index 417061ae59eb..c18577a3153d 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -66,6 +66,8 @@ module_param_named(modeset, qxl_modeset, int, 0400);
MODULE_PARM_DESC(num_heads, "Number of virtual crtcs to expose (default 4)");
module_param_named(num_heads, qxl_num_crtc, int, 0400);
+DRM_CLASSMAP_USE(drm_debug_classes);
+
static struct drm_driver qxl_driver;
static struct pci_driver qxl_pci_driver;
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 57/59] drm-dyndbg: add DRM_CLASSMAP_USE to the drm_gem_shmem_helper driver
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (55 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 56/59] drm-dyndbg: add DRM_CLASSMAP_USE to the qxl driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 58/59] drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN Jim Cromie
2025-03-20 18:52 ` [PATCH v2 59/59] drm: RFC - make drm_dyndbg_user.o for drm-*_helpers, drivers Jim Cromie
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
The drm_gem_shmem_helper driver has a number of DRM_UT_* debugs, make
them controllable when CONFIG_DRM_USE_DYNAMIC_DEBUG=y by telling
dyndbg that the module uses them.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/drm_gem_shmem_helper.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 5ab351409312..481d18561688 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -23,6 +23,7 @@
#include <drm/drm_print.h>
MODULE_IMPORT_NS("DMA_BUF");
+DRM_CLASSMAP_USE(drm_debug_classes);
/**
* DOC: overview
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 58/59] drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (56 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 57/59] drm-dyndbg: add DRM_CLASSMAP_USE to the drm_gem_shmem_helper driver Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-20 18:52 ` [PATCH v2 59/59] drm: RFC - make drm_dyndbg_user.o for drm-*_helpers, drivers Jim Cromie
58 siblings, 0 replies; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Time for some thorough CI.
Also, the previous 18 patches could perhaps be replaced by a single
invocation of DYNDBG_CLASSMAP_USE, from a C-file linked into all drm
drivers & helpers. I didn't find such a file, nor a drm-client
linkage item in the Makefile.
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index fbef3f471bd0..c7d6adbe17eb 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -53,8 +53,7 @@ config DRM_DEBUG_MM
config DRM_USE_DYNAMIC_DEBUG
bool "use dynamic debug to implement drm.debug"
- default n
- depends on BROKEN
+ default y
depends on DRM
depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
depends on JUMP_LABEL
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* [PATCH v2 59/59] drm: RFC - make drm_dyndbg_user.o for drm-*_helpers, drivers
2025-03-20 18:51 [PATCH v2 00/59] Fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y Jim Cromie
` (57 preceding siblings ...)
2025-03-20 18:52 ` [PATCH v2 58/59] drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN Jim Cromie
@ 2025-03-20 18:52 ` Jim Cromie
2025-03-24 15:00 ` Louis Chauvet
58 siblings, 1 reply; 103+ messages in thread
From: Jim Cromie @ 2025-03-20 18:52 UTC (permalink / raw)
To: linux-kernel, dri-devel, amd-gfx, intel-gvt-dev, intel-gfx,
intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, louis.chauvet, daniel.vetter,
tvrtko.ursulin, jani.nikula, ville.syrjala, Jim Cromie
Add new drm_dyndbg_user.c with a single call to
DYNDBG_CLASSMAP_USE(drm_debug_classes). This creates a _class_user
record (and a linkage dependency).
If a driver adds this object to its Makefile target, it gets the
record, which authorizes dyndbg to enable the module's class'd
pr_debugs, such as DRMs <category>_dbg() macros.
So Id like to automatically inject this object into drivers. I tried
subdir-objs-y, but thats not a thing.
In drm/Makefile:
Add object dependency to drm_*_helper-y targets:
$targ-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
Attempt a foreach:
to add $driver-y += ../drm_dyndbg_user.o
this appears to be a train-wreck for impl reasons, but it describes a
want/need reasonably well. It might not be a good maintainble idea.
Explicitly adding to radeon/Makefile worked:
$radeon-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += ../drm_dyndbg_user.o
But doing this is just as per-module as just adding the _USE()
explicitly to the main .c file, which is less magical than make-fu.
Also, it appears to cause make && make rebuilds.
and try to link it to helpers and everything
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
drivers/gpu/drm/Makefile | 9 +++++++++
drivers/gpu/drm/drm_dyndbg_user.c | 11 +++++++++++
2 files changed, 20 insertions(+)
create mode 100644 drivers/gpu/drm/drm_dyndbg_user.c
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 704f94efc804..1adb5a262180 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -74,10 +74,12 @@ drm-y := \
drm_vblank_work.o \
drm_vma_manager.o \
drm_writeback.o
+
drm-$(CONFIG_DRM_CLIENT) += \
drm_client.o \
drm_client_event.o \
drm_client_modeset.o
+
drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_PANEL) += drm_panel.o
@@ -111,20 +113,25 @@ obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
drm_dma_helper-y := drm_gem_dma_helper.o
drm_dma_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_dma.o
drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_dma_helper.o
+drm_dma_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o
drm_shmem_helper-y := drm_gem_shmem_helper.o
drm_shmem_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_shmem.o
+drm_shmem_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
drm_suballoc_helper-y := drm_suballoc.o
+drm_suballoc_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-$(CONFIG_DRM_SUBALLOC_HELPER) += drm_suballoc_helper.o
drm_vram_helper-y := drm_gem_vram_helper.o
+drm_vram_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
drm_ttm_helper-y := drm_gem_ttm_helper.o
drm_ttm_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_ttm.o
+drm_ttm_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
#
@@ -149,11 +156,13 @@ drm_kms_helper-y := \
drm_simple_kms_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
+drm_kms_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
#
# Drivers and the rest
#
+subdir-obj-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
obj-y += tests/
diff --git a/drivers/gpu/drm/drm_dyndbg_user.c b/drivers/gpu/drm/drm_dyndbg_user.c
new file mode 100644
index 000000000000..9e4aa87d4b58
--- /dev/null
+++ b/drivers/gpu/drm/drm_dyndbg_user.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "drm/drm_print.h"
+/*
+ * if DRM_USE_DYNAMIC_DEBBUG:
+ * DYNDBG_CLASSMAP_USE(drm_debug_classes);
+ *
+ * dyndbg classmaps are opt-in, so modules which call drm:_*_dbg must
+ * link this to authorize dyndbg to change the static-keys underneath.
+ */
+DRM_CLASSMAP_USE(drm_debug_classes);
--
2.49.0
^ permalink raw reply related [flat|nested] 103+ messages in thread
* Re: [PATCH v2 59/59] drm: RFC - make drm_dyndbg_user.o for drm-*_helpers, drivers
2025-03-20 18:52 ` [PATCH v2 59/59] drm: RFC - make drm_dyndbg_user.o for drm-*_helpers, drivers Jim Cromie
@ 2025-03-24 15:00 ` Louis Chauvet
0 siblings, 0 replies; 103+ messages in thread
From: Louis Chauvet @ 2025-03-24 15:00 UTC (permalink / raw)
To: Jim Cromie, linux-kernel, dri-devel, amd-gfx, intel-gvt-dev,
intel-gfx, intel-gfx-trybot
Cc: jbaron, gregkh, ukaszb, daniel.vetter, tvrtko.ursulin,
jani.nikula, ville.syrjala
Le 20/03/2025 à 19:52, Jim Cromie a écrit :
> Add new drm_dyndbg_user.c with a single call to
> DYNDBG_CLASSMAP_USE(drm_debug_classes). This creates a _class_user
> record (and a linkage dependency).
I agree, this could be a very nice thing to automagically have the _USE
call included. But if this remains a per-module work, I think it is
better in the C code, it is less error-prone.
Maybe to clarify this is a per-module call, you can move it near the
MODULE_* macros.
> If a driver adds this object to its Makefile target, it gets the
> record, which authorizes dyndbg to enable the module's class'd
> pr_debugs, such as DRMs <category>_dbg() macros.
>
> So Id like to automatically inject this object into drivers. I tried
> subdir-objs-y, but thats not a thing.
>
> In drm/Makefile:
>
> Add object dependency to drm_*_helper-y targets:
>
> $targ-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
>
> Attempt a foreach:
>
> to add $driver-y += ../drm_dyndbg_user.o
>
> this appears to be a train-wreck for impl reasons, but it describes a
> want/need reasonably well. It might not be a good maintainble idea.
>
> Explicitly adding to radeon/Makefile worked:
>
> $radeon-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += ../drm_dyndbg_user.o
>
> But doing this is just as per-module as just adding the _USE()
> explicitly to the main .c file, which is less magical than make-fu.
>
> Also, it appears to cause make && make rebuilds.
>
> and try to link it to helpers and everything
>
> Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
> ---
> drivers/gpu/drm/Makefile | 9 +++++++++
> drivers/gpu/drm/drm_dyndbg_user.c | 11 +++++++++++
> 2 files changed, 20 insertions(+)
> create mode 100644 drivers/gpu/drm/drm_dyndbg_user.c
>
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 704f94efc804..1adb5a262180 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -74,10 +74,12 @@ drm-y := \
> drm_vblank_work.o \
> drm_vma_manager.o \
> drm_writeback.o
> +
> drm-$(CONFIG_DRM_CLIENT) += \
> drm_client.o \
> drm_client_event.o \
> drm_client_modeset.o
> +
> drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> drm-$(CONFIG_COMPAT) += drm_ioc32.o
> drm-$(CONFIG_DRM_PANEL) += drm_panel.o
> @@ -111,20 +113,25 @@ obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
> drm_dma_helper-y := drm_gem_dma_helper.o
> drm_dma_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_dma.o
> drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_dma_helper.o
> +drm_dma_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
> obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o
>
> drm_shmem_helper-y := drm_gem_shmem_helper.o
> drm_shmem_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_shmem.o
> +drm_shmem_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
> obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
>
> drm_suballoc_helper-y := drm_suballoc.o
> +drm_suballoc_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
> obj-$(CONFIG_DRM_SUBALLOC_HELPER) += drm_suballoc_helper.o
>
> drm_vram_helper-y := drm_gem_vram_helper.o
> +drm_vram_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
> obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
>
> drm_ttm_helper-y := drm_gem_ttm_helper.o
> drm_ttm_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_ttm.o
> +drm_ttm_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
> obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
>
> #
> @@ -149,11 +156,13 @@ drm_kms_helper-y := \
> drm_simple_kms_helper.o
> drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
> drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
> +drm_kms_helper-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
> obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
>
> #
> # Drivers and the rest
> #
> +subdir-obj-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += drm_dyndbg_user.o
>
> obj-y += tests/
>
> diff --git a/drivers/gpu/drm/drm_dyndbg_user.c b/drivers/gpu/drm/drm_dyndbg_user.c
> new file mode 100644
> index 000000000000..9e4aa87d4b58
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_dyndbg_user.c
> @@ -0,0 +1,11 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +#include "drm/drm_print.h"
> +/*
> + * if DRM_USE_DYNAMIC_DEBBUG:
> + * DYNDBG_CLASSMAP_USE(drm_debug_classes);
> + *
> + * dyndbg classmaps are opt-in, so modules which call drm:_*_dbg must
> + * link this to authorize dyndbg to change the static-keys underneath.
> + */
> +DRM_CLASSMAP_USE(drm_debug_classes);
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 103+ messages in thread