[PATCH v9-resend 46/54] drm-dyndbg: add DRM_CLASSMAP_USE to vkms driver

2024-07-17 Thread 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 
---
 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 dd0af086e7fa..086797c4b82b 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.45.2



[PATCH v9-resend 31/54] drm-dyndbg: adapt DRM to invoke DYNDBG_CLASSMAP_PARAM

2024-07-17 Thread Jim Cromie
Invoke DYNDBG_CLASSMAP_PARAM to hook drm.debug (__drm_debug) to the
DRM_UT_* classmap, replacing the ad-hoc wiring previously doing it.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 8 ++--
 include/drm/drm_print.h | 6 --
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 41f167082042..c7455f2076b4 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 = _debug_classes,
-};
-module_param_cb(debug, _ops_dyndbg_classes, _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 b467ee67a281..aa3708c7b6d8 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -141,11 +141,13 @@ enum drm_debug_category {
 };
 
 #ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG
-#define DRM_CLASSMAP_DEFINE(...) DYNDBG_CLASSMAP_DEFINE(__VA_ARGS__)
-#define DRM_CLASSMAP_USE(name)   DYNDBG_CLASSMAP_USE(name)
+#define DRM_CLASSMAP_DEFINE(...)DYNDBG_CLASSMAP_DEFINE(__VA_ARGS__)
+#define DRM_CLASSMAP_USE(name)  DYNDBG_CLASSMAP_USE(name)
+#define DRM_CLASSMAP_PARAM_REF(...) DYNDBG_CLASSMAP_PARAM_REF(__VA_ARGS__)
 #else
 #define DRM_CLASSMAP_DEFINE(...)
 #define DRM_CLASSMAP_USE(name)
+#define DRM_CLASSMAP_PARAM_REF(...)
 #endif
 
 static inline bool drm_debug_enabled_raw(enum drm_debug_category category)
-- 
2.45.2



[PATCH v9-resend 03/54] dyndbg: reword "class unknown, " to "class:_UNKNOWN_"

2024-07-17 Thread 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 exceedingly greppable.

NB: pr_debugs are only alterable via >control, and to protect class'd
debug's from unintended alteration, "class name" must be given to
change them.  Classmaps map known classes to reserved .class_ids (the
1..64 val range per module).

Signed-off-by: Jim Cromie 
---
 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 f2c5e7910bb1..73ccf947d4aa 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_puts(m, "\n");
 
-- 
2.45.2



[PATCH v9-resend 38/54] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver

2024-07-17 Thread 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 
---
 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 08f0b7c95901..ffd6e237f3c6 100644
--- a/drivers/gpu/drm/xe/xe_drm_client.c
+++ b/drivers/gpu/drm/xe/xe_drm_client.c
@@ -15,6 +15,8 @@
 #include "xe_drm_client.h"
 #include "xe_trace.h"
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 /**
  * xe_drm_client_alloc() - Allocate drm client
  * @void: No arg
-- 
2.45.2



[PATCH v9-resend 21/54] dyndbg: split multi-query strings with %

2024-07-17 Thread 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=<
[  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 
---
 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 235d85765b63..dcec7b3657bb 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -596,7 +596,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.45.2



[PATCH v9-resend 24/54] selftests-dyndbg: add test_mod_submod

2024-07-17 Thread Jim Cromie
This new test-fn runs 3 module/submodule modprobe scenarios, variously
using both the generic dyndbg= 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 
---
 .../dynamic_debug/dyndbg_selftest.sh  | 67 +++
 1 file changed, 67 insertions(+)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index 996e6fdcfb52..fccd2012b548 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -246,10 +246,77 @@ 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 -v
+check_match_ct =plt 1 -v
+check_match_ct =pml 1 -v
+#  submod changed too
+check_match_ct =mf 1 -v
+check_match_ct =lt 1 -v
+check_match_ct =ml 1 -v
+
+# 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 -v
+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 -v
+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 -v
+
+# 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 -v
+modprobe test_dynamic_debug_submod
+# see them picked up by submod
+check_match_ct =p 14 -v
+}
+
 tests_list=(
 basic_tests
+# these require test_dynamic_debug*.ko
 comma_terminator_tests
 test_percent_splitting
+test_mod_submod
 )
 
 # Run tests
-- 
2.45.2



[PATCH v9-resend 28/54] dyndbg-selftest: reduce default verbosity

2024-07-17 Thread Jim Cromie
Remove the '-v' arg from the tests in test_mod_submod().
Setting V=1 in the environment turns it back on, for all tests.

Signed-off-by: Jim Cromie 
---
 .../dynamic_debug/dyndbg_selftest.sh  | 23 +--
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index d09ef26b2308..b3d7155cb45c 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -168,7 +168,6 @@ function error_log_ref {
 }
 
 function ifrmmod {
-lsmod | grep $1 2>&1>/dev/null || echo $1 not there
 lsmod | grep $1 2>&1>/dev/null && rmmod $1
 }
 
@@ -316,13 +315,13 @@ function test_mod_submod {
 
 # 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 -v
-check_match_ct =plt 1 -v
-check_match_ct =pml 1 -v
+check_match_ct =pmf 1
+check_match_ct =plt 1
+check_match_ct =pml 1
 #  submod changed too
-check_match_ct =mf 1 -v
-check_match_ct =lt 1 -v
-check_match_ct =ml 1 -v
+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)
@@ -333,25 +332,25 @@ function test_mod_submod {
 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 -v
+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 -v
+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 -v
+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 -v
+check_match_ct =p 7
 modprobe test_dynamic_debug_submod
 # see them picked up by submod
-check_match_ct =p 14 -v
+check_match_ct =p 14
 }
 
 tests_list=(
-- 
2.45.2



[PATCH v9-resend 10/54] dyndbg: silence debugs with no-change updates

2024-07-17 Thread Jim Cromie
In ddebug_apply_class_bitmap(), check for actual changes to the bits
before announcing them, to declutter logs.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 368381dbd266..8320cadeb251 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -595,7 +595,7 @@ 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,
 const char *query_modname)
@@ -606,8 +606,9 @@ static int ddebug_apply_class_bitmap(const struct 
ddebug_class_param *dcp,
int matches = 0;
int bi, ct;
 
-   v2pr_info("apply bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
- query_modname ?: "");
+   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))
@@ -622,8 +623,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);
}
-   v2pr_info("applied bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
- query_modname ?: "");
+   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;
 }
-- 
2.45.2



[PATCH v9-resend 19/54] dyndbg: treat comma as a token separator

2024-07-17 Thread 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 
Co-developed-by: Łukasz Bartosik 
Signed-off-by: Łukasz Bartosik 
---
 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 e9a95b0f3757..235d85765b63 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -290,6 +290,14 @@ static int ddebug_change(const struct ddebug_query *query,
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,
@@ -303,8 +311,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 == '#')
@@ -320,7 +328,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,
@@ -592,7 +600,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.45.2



[PATCH v9-resend 25/54] dyndbg-doc: explain flags parse 1st

2024-07-17 Thread Jim Cromie
When writing queries to >control, flags are parsed 1st, since they are
the only required field.  So if the flags draw an error, then keyword
errors aren't reported.  This can be mildly confusing/annoying, so
explain it instead.

This note could be moved up to just after the grammar id's the flags,
and before the match-spec is detailed.  Opinions ?

Signed-off-by: Jim Cromie 
---
 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 7b570f29ae98..ccf3704f2143 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -106,6 +106,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.45.2



[PATCH v9-resend 44/54] drm-dyndbg: add DRM_CLASSMAP_USE to radeon

2024-07-17 Thread 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 
---
 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 7bf08164140e..d22308328c76 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -247,6 +247,8 @@ int radeon_cik_support = 1;
 MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = 
disabled)");
 module_param_named(cik_support, radeon_cik_support, int, 0444);
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
 };
-- 
2.45.2



[PATCH v9-resend 23/54] docs/dyndbg: explain new delimiters: comma, percent

2024-07-17 Thread Jim Cromie
Add mention of comma and percent delimiters into the respective
paragraphs describing their equivalents: space and newline.

Signed-off-by: Jim Cromie 
---
 .../admin-guide/dynamic-debug-howto.rst| 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index 742eb4230c6e..7b570f29ae98 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -73,16 +73,18 @@ 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 <<"EOC"
   func pnpacpi_get_resources +p
   func pnp_assign_mem +p
@@ -104,7 +106,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:::
@@ -128,7 +129,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
@@ -153,9 +153,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.45.2



[PATCH v9-resend 15/54] dyndbg-API: fix DECLARE_DYNDBG_CLASSMAP

2024-07-17 Thread Jim Cromie
ogether, 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 DYNDBG_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/N).  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.

DEBUG details:

``#define DEBUG`` in src enables all pr_debugs after it, including any
class'd pr_debugs; its not necessarily all-or-nothing, unless you do
the define in a header.  Also, the only way to disable a class'd
pr_debug is via the classmap-kparam or using "class foo" in control
queries, to address the classes by name.

NB: this patch ignores a checkpatch do-while warning; which is wrong
for declarative macros like these:

arch/powerpc/platforms/cell/spu_base.c
48:static DEFINE_SPINLOCK(spu_lock);
62:static DEFINE_SPINLOCK(spu_full_list_lock);
63:static DEFINE_MUTEX(spu_full_list_mutex);

Fixes: aad0214f3026 ("dyndbg: add DECLARE_DYNDBG_CLASSMAP macro")
Signed-off-by: Jim Cromie 
---
v8 - split drm parts to separate commits.
 preserve DECLARE_DYNDBG_CLASSMAP to decouple DRM, no flag day.
 fixup block comment

v7 - 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
---
 MAINTAINERS   |   2 +-
 include/asm-generic/vmlinux.lds.h |   1 +
 include/linux/dynamic_debug.h |  62 --
 kernel/module/main.c  |   3 +
 lib/Kconfig.debug |  24 +++-
 lib/Makefile  |   3 +
 lib/dynamic_debug.c   | 184 ++
 lib/test_dynamic_debug.c  | 111 --
 lib/test_dynamic_debug_submod.c   |  10 ++
 9 files changed, 332 insertions(+), 68 deletions(-)
 create mode 100644 lib/test_dynamic_debug_submod.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 958e935449e5..eb8312ea681f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7684,7 +7684,7 @@ M:Jim Cromie 
 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 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 5703526d6ebf..05fbf9f05eb4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -367,6 +367,7 @@
/* implement dynamic printk debug */\
. = ALIGN(8);   \
BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes) \
+   BOUNDED_SECTION_BY(__dyndbg_class_users, ___dyndbg_class_users) \
BOUNDED_SECTION_BY(__dyndbg, ___dyndbg) \
CODETAG_SECTIONS()  \
LIKELY_PROFILE()\
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index c8102e89beb2..189e3f60c31a 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -72,8 +72,8 @@ enum ddebug_class_map_type {
 };
 
 struct ddebug_class_map {
-   struct module *mod;
-   const char *mod_name;   /* needed for builtins */
+   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 */
@@ -81,11 +81,34 @@ 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
+ * DYNDBG_CLASSMAP_DEFINE -

[PATCH v9-resend 54/54] docs-dyndbg: improve howto classmaps api section

2024-07-17 Thread Jim Cromie
reword the classmaps-api section to better explain how it supports
DRM, and (a little bit) to steer clear of designated-inits in the
_DEFINE description.

probably just squash this back in

Signed-off-by: Jim Cromie 
---
 .../admin-guide/dynamic-debug-howto.rst   | 64 +++
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index ccf3704f2143..1ffab6be07fc 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -390,42 +390,56 @@ in case ``prefix_str`` is built dynamically.
 Dynamic Debug classmaps
 ===
 
-Dyndbg allows selection/grouping of *prdbg* callsites using structural
-info: module, file, function, line.  Classmaps allow authors to add
-their own domain-oriented groupings using class-names.  Classmaps are
-exported, so they referencable from other modules.
+Classmaps adds the "class" keyword, which selects prdbgs based on
+author supplied, domain-oriented names; this complements the code
+organizational 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):
 
-  # enable classes individually
   :#> ddcmd class DRM_UT_CORE +p
   :#> ddcmd class DRM_UT_KMS +p
   # or more selectively
   :#> ddcmd class DRM_UT_CORE module drm +p
 
-The "class FOO" syntax protects class'd prdbgs from generic overwrite::
-
-  # IOW this doesn't wipe any DRM.debug settings
-  :#> ddcmd -p
+Or the legacy/normal (convenient) way:
 
-To support the DRM.debug parameter, DYNDBG_CLASSMAP_PARAM* updates all
-classes in a classmap, mapping param-bits 0..N onto the classes:
-DRM_UT_<*> for the DRM use-case.
+  :#> echo 0x1ff > /sys/module/drm/parameters/debug
 
 Dynamic Debug Classmap API
 ==
 
-DYNDBG_CLASSMAP_DEFINE - modules use this to create classmaps, naming
-each of the classes (stringified enum-symbols: "DRM_UT_<*>"), and
-type, and mapping the class-names to consecutive _class_ids.
+The classmap API is closely modeled on DRM, which has:
+
+enum drm_debug_category: DRM_UT_* // 10 independent categories. 
+dyndbg's .classid encodes that directly, allowing 0..62 classes
+
+DRM has ~5k calls like: drm_dbg(DRM_UT_KMS, "kms msg");
+these are unchanged, even in argtype, since classid === category.
+
+DRM controls the classes together via sysfs; bits 0..9 control the
+classes independently.
+
+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.
+
+DYNDBG_CLASSMAP_DEFINE(var,type,_base,classnames) - this maps
+classnames onto class-ids starting at _base, it also maps the
+names onto CLASSMAP_PARAM bits 0..N.
 
-By doing so, modules tell dyndbg that they have prdbgs with those
-class_ids, and they authorize dyndbg to accept "class FOO" for the
-module defining the classmap, and its contained classnames.
+DYNDBG_CLASSMAP_USE(var) - modules call this to refer to the var
+_DEFINEd elsewhere (and exported).
 
-DYNDBG_CLASSMAP_USE - drm drivers invoke this to ref the CLASSMAP that
-drm DEFINEs.  This shares the classmap definition, and authorizes
-dyndbg to apply changes to the user module's class'd pr_debugs.  It
-also tells dyndbg how to initialize the user's prdbgs at modprobe,
-based upon the current setting of the parent's controlling param.
+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:
 
@@ -436,9 +450,9 @@ DYNDBG_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.
 
-This interface also enforces the DD_CLASS_TYPE_LEVEL_NUM relation
+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.
+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
-- 
2.45.2



[PATCH v9-resend 16/54] selftests-dyndbg: add tools/testing/selftests/dynamic_debug/*

2024-07-17 Thread 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(), it modifies pr_debug flags in a few
builtins (init/main, params), counts the callsite flags changed, and
verifies against expected values.

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:

  $> vng --verbose --name v6.8-32-g30d431000676 --user root \
 --cwd ../.. -a dynamic_debug.verbose=2 -p 4 \
 ./tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh

virtme: waiting for virtiofsd to start
virtme: use 'microvm' QEMU architecture
...
[4.136168] virtme-init: Setting hostname to v6.8-32-g30d431000676...
[4.240874] virtme-init: starting script
test_dynamic_debug_submod not there
test_dynamic_debug not there
...
[4.474435] virtme-init: script returned {0}
Powering off.
[4.529318] ACPI: PM: Preparing to enter system sleep state S5
[4.529991] kvm: exiting hardware virtualization
[4.530428] reboot: Power down

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
...

TLDR:

This selftest is slightly naive wrt the init state of call-site flags.

In particular, it fails if class'd pr_debugs have been set

  $ cat /etc/modprobe.d/drm-test.conf
  options drm dyndbg=class,DRM_UT_CORE,+mfslt%class,DRM_UT_KMS,+mf

By Contract, class'd pr_debugs are protected from alteration by
default (only by direct "class FOO" queries), so the "=_" logged above
(TAP version 13) cannot affect the DRM_UT_CORE,KMS pr_debugs.

These class'd flag-settings, added by modprobe, alter the counts of
flag-matching patterns, breaking the tests' expectations.

Signed-off-by: Jim Cromie 
Co-developed-by: Łukasz Bartosik 
Signed-off-by: Łukasz Bartosik 
---
 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  | 231 ++
 5 files changed, 244 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 eb8312ea681f..a5197bac717f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7685,6 +7685,7 @@ S:Maintained
 F: include/linux/dynamic_debug.h
 F: lib/dynamic_debug.c
 F: lib/test_dynamic_debug*.c
+F: tools/testing/selftest/dynamic_debug/*
 
 DYNAMIC INTERRUPT MODERATION
 M: Tal Gilboa 
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 9039f3709aff..1b4826d5d09c 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -22,6 +22,7 @@ TARGETS += drivers/net/bonding
 TARGETS += drivers/net/team
 TARGETS += drivers/net/virtio_net
 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 ..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 ..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 ..1be70af26a38
--- /dev/null
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -0,0 +1,231 @@
+#!/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;0

[PATCH v9-resend 14/54] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code

2024-07-17 Thread Jim Cromie
Remove the NAMED class types; 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, simplify things.

also rename enum class_map_type to enum ddebug_class_map_type.

Signed-off-by: Jim Cromie 
---
 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 e458d4b838ac..c8102e89beb2 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -58,27 +58,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
 */
 };
 
@@ -88,7 +77,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 43a8e04b8599..d5701207febc 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -636,76 +636,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, _bits) == wanted) {
-   v3pr_info("no change on %s\n", cl_str);
-   continue;
-   }
-   curr_bits ^= BIT(cls_id);
-   totct += ddebug_apply_class_bitmap(dcp, _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_

[PATCH v9-resend 52/54] drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN

2024-07-17 Thread Jim Cromie
end of official submission.

Time for some quality CI

Signed-off-by: Jim Cromie 
---
 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 d0aa277fc3bf..c508c0834641 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -56,8 +56,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.45.2



[PATCH v9-resend 45/54] drm-dyndbg: add DRM_CLASSMAP_USE to vmwgfx driver

2024-07-17 Thread 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 
---
 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 823d8d2da17c..fd6cd62608a9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -277,6 +277,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.45.2



[PATCH v9-resend 51/54] drm-dyndbg: add DRM_CLASSMAP_USE to the drm_gem_shmem_helper driver

2024-07-17 Thread 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 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 53c003983ad1..2b269ae9ea18 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -22,6 +22,8 @@
 #include 
 #include 
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 MODULE_IMPORT_NS(DMA_BUF);
 
 /**
-- 
2.45.2



[PATCH v9-resend 40/54] drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm

2024-07-17 Thread 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 
---
 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 1d8fa07572c5..69cb580ca9d1 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.45.2



[PATCH v9-resend 39/54] drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu

2024-07-17 Thread 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 
---
 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 188e126383c2..d69d517de2a3 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -44,6 +44,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.45.2



[PATCH v9-resend 37/54] drm-print: workaround unused variable compiler meh

2024-07-17 Thread Jim Cromie
With CONFIG_DRM_USE_DYNAMIC_DEBUG=y, I'm getting an unused variable
warning/error on 'category', though the usage follows immediately, in
drm_debug_enabled().

This drops the local var and refs the field directly in the
macro-call, which avoids the warning.  For static-key optimized
dyndbg, the macro doesn't actually check the category, since the
static-key patches in the proper state.  This is also likely why the
auto var appears to be unused by the compiler.

commit 9fd6f61a297e ("drm/print: add drm_dbg_printer() for drm device specific 
printer")
CC: Jani Nikula 
Signed-off-by: Jim Cromie 
---
 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 c7455f2076b4..0980210a5146 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -183,11 +183,10 @@ 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;
const char *prefix = p->prefix ?: "";
const char *prefix_pad = p->prefix ? " " : "";
 
-   if (!__drm_debug_enabled(category))
+   if (!__drm_debug_enabled(p->category))
return;
 
/* Note: __builtin_return_address(0) is useless here. */
-- 
2.45.2



[PATCH v9-resend 07/54] dyndbg: split param_set_dyndbg_classes to _module & wrapper fns

2024-07-17 Thread Jim Cromie
Split api-fn: param_set_dyndbg_classes(), adding modname param and
passing NULL in from api-fn.

The new arg allows caller to specify that only one module is affected
by a prdbgs update.  This selectivity will be used later to narrow the
scope of changes made.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index a1fd2e9dbafb..4a48f830507f 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -711,18 +711,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;
@@ -759,8 +750,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, , dcp->bits, 
NULL);
+   v2pr_info("bits:0x%lx > %s.%s\n", inrep, modnm ?: "*", 
KP_NAME(kp));
+   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits, 
modnm);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -773,7 +764,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, _bits, _bits, 
NULL);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, _bits, 
modnm);
*dcp->lvl = inrep;
break;
default:
@@ -782,6 +773,22 @@ 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 - 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)
+{
+   return param_set_dyndbg_module_classes(instr, kp, NULL);
+}
 EXPORT_SYMBOL(param_set_dyndbg_classes);
 
 /**
-- 
2.45.2



[PATCH v9-resend 09/54] dyndbg: reduce verbose/debug clutter

2024-07-17 Thread 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=0x

 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=0x
 dyndbg: no-match: func="" file="" module="" format="" lineno=0-0 class=...
 dyndbg: processed 1 queries, with 0 matches, 0 errs

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 4a48f830507f..368381dbd266 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -266,9 +266,6 @@ static int ddebug_change(const struct ddebug_query *query,
}
mutex_unlock(_lock);
 
-   if (!nfound && verbose)
-   pr_info("no matches for query\n");
-
return nfound;
 }
 
@@ -501,7 +498,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--) {
@@ -515,7 +511,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) {
@@ -531,7 +526,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;
 }
@@ -541,7 +536,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);
@@ -559,10 +554,7 @@ static int ddebug_exec_query(char *query_string, const 
char *modname)
return -EINVAL;
}
/* actually go and implement the change */
-   nfound = ddebug_change(, );
-   vpr_info_dq(, nfound ? "applied" : "no-match");
-
-   return nfound;
+   return ddebug_change(, );
 }
 
 /* handle multiple queries in query string, continue on error, return
-- 
2.45.2



[PATCH v9-resend 33/54] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver

2024-07-17 Thread 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 
---
 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 8c00169e3ab7..a8f51f138895 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.45.2



[PATCH v9-resend 34/54] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper

2024-07-17 Thread 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 
---
 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.45.2



[PATCH v9-resend 29/54] drm: use correct ccflags-y spelling

2024-07-17 Thread Jim Cromie
Incorrectly spelled CFLAGS- failed to add -DDYNAMIC_DEBUG_MODULE,
which broke builds with:

CONFIG_DRM_USE_DYNAMIC_DEBUG=y
CONFIG_DYNAMIC_DEBUG_CORE=y
CONFIG_DYNAMIC_DEBUG=n

Also add subdir-ccflags so that all drivers pick up the addition.

Fixes: 84ec67288c10 ("drm_print: wrap drm_*_dbg in dyndbg descriptor factory 
macro")
Signed-off-by: Jim Cromie 
---
 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 f9ca4f8fa6c5..78b464cd4348 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.45.2



[PATCH v9-resend 08/54] dyndbg: drop NUM_TYPE_ARRAY

2024-07-17 Thread Jim Cromie
ARRAY_SIZE works here, since array decl is complete.

no functional change

Signed-off-by: Jim Cromie 
---
 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 2b0057058ecf..e458d4b838ac 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -106,11 +106,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.45.2



[PATCH v9-resend 22/54] selftests-dyndbg: test_percent_splitting

2024-07-17 Thread 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 
---
 .../dynamic_debug/dyndbg_selftest.sh  | 21 +++
 1 file changed, 21 insertions(+)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index b4ba293ab227..996e6fdcfb52 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -226,9 +226,30 @@ 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.45.2



[PATCH v9-resend 05/54] dyndbg: replace classmap list with a vector

2024-07-17 Thread Jim Cromie
Classmaps are stored in an elf section/array, but are individually
list-linked onto dyndbg's per-module ddebug_table for operation.

This is unnecessary; even when ddebug_attach_classmap() is handling
the builtin section (with classmaps for multiple builtin modules), its
contents are ordered, so a module's possibly multiple classmaps will
be consecutive in the section, and could be treated as a vector/block,
since both start-address and subrange length are in the ddebug_info arg.

IOW, this treats classmaps similarly to _ddebugs, which are already
kept as vector-refs (address+len).

So this changes:

struct ddebug_class_map drops list-head link.

struct ddebug_table drops the list-head maps, and gets: classes &
num_classes for the start-address and num_classes, placed to improve
struct packing.

The loading: in ddebug_attach_module_classes(), replace the
for-the-modname list-add loop, with a forloop that finds the module's
subrange (start,length) of matching classmaps within the possibly
builtin classmaps vector, and saves those to the ddebug_table.

The reading/using: change list-foreach loops in ddebug_class_name() &
ddebug_find_valid_class() to walk the array from start to length.

Also:
Move #define __outvar up, above an added use in a fn-prototype.
Simplify ddebug_attach_module_classes args, ref has both address & len.

no functional changes

Signed-off-by: Jim Cromie 
---
 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 b9afc7731b7c..2b0057058ecf 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 152b04c05981..46e4cdd8e6be 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, >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
@@ -1114,9 +1116,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, >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];
 
@@ -1200,30 +1203,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 

[PATCH v9-resend 26/54] dyndbg: change __dynamic_func_call_cls* macros into expressions

2024-07-17 Thread 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 it by changing __dynamic_func_call_cls{,_no_desc} macros into
expressions, by replacing the do-while-0s with a ({ }) wrapper.

In C, all legal expressions are also legal statements, as converted by
the trailing semi-colon in a statement-style macro invocation:

   drm_dbg("statement form");

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 4a9b9cd53eb7..c958085e0df4 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -287,20 +287,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_func_call_cls(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(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.45.2



[PATCH v9-resend 27/54] selftests-dyndbg: check KCONFIG_CONFIG to avoid silly fails

2024-07-17 Thread Jim Cromie
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=.  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.

Signed-off-by: Jim Cromie 

fixup-kconfig
---
 .../dynamic_debug/dyndbg_selftest.sh  | 45 ++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index fccd2012b548..d09ef26b2308 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -11,6 +11,30 @@ 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
 }
@@ -192,6 +216,10 @@ function check_err_msg() {
 
 function basic_tests {
 echo -e "${GREEN}# BASIC_TESTS ${NC}"
+if [ $LACK_DD_BUILTIN -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 ddcmd =_ # zero everything (except class'd sites)
 check_match_ct =p 0
 # there are several main's :-/
@@ -214,6 +242,10 @@ EOF
 
 function comma_terminator_tests {
 echo -e "${GREEN}# COMMA_TERMINATOR_TESTS ${NC}"
+if [ $LACK_DD_BUILTIN -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 # try combos of spaces & commas
 check_match_ct '\[params\]' 4 -r
 ddcmd module,params,=_ # commas as spaces
@@ -226,9 +258,12 @@ function comma_terminator_tests {
 ddcmd =_
 }
 
-
 function test_percent_splitting {
 echo -e "${GREEN}# TEST_PERCENT_SPLITTING - multi-command splitting on % 
${NC}"
+if [ $LACK_TMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 ifrmmod test_dynamic_debug_submod
 ifrmmod test_dynamic_debug
 ddcmd =_
@@ -248,6 +283,14 @@ function test_percent_splitting {
 
 function test_mod_submod {
 echo -e "${GREEN}# TEST_MOD_SUBMOD ${NC}"
+if [ $LACK_TMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
+if [ $LACK_TMOD_SUBMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 ifrmmod test_dynamic_debug_submod
 ifrmmod test_dynamic_debug
 ddcmd =_
-- 
2.45.2



[PATCH v9-resend 18/54] dyndbg-doc: add classmap info to howto

2024-07-17 Thread Jim Cromie
Describe the 3 API macros providing dynamic_debug's classmaps

DYNDBG_CLASSMAP_DEFINE - create, exports a module's 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

cc: linux-...@vger.kernel.org
Signed-off-by: Jim Cromie 
---
v5 adjustments per Randy Dunlap
v7 checkpatch fixes
v8 more
---
 .../admin-guide/dynamic-debug-howto.rst   | 63 ++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index 6a8ce5a34382..742eb4230c6e 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -225,7 +225,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
 ==
 
@@ -375,3 +374,65 @@ 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
+===
+
+Dyndbg allows selection/grouping of *prdbg* callsites using structural
+info: module, file, function, line.  Classmaps allow authors to add
+their own domain-oriented groupings using class-names.  Classmaps are
+exported, so they referencable from other modules.
+
+  # enable classes individually
+  :#> ddcmd class DRM_UT_CORE +p
+  :#> ddcmd class DRM_UT_KMS +p
+  # or more selectively
+  :#> ddcmd class DRM_UT_CORE module drm +p
+
+The "class FOO" syntax protects class'd prdbgs from generic overwrite::
+
+  # IOW this doesn't wipe any DRM.debug settings
+  :#> ddcmd -p
+
+To support the DRM.debug parameter, DYNDBG_CLASSMAP_PARAM* updates all
+classes in a classmap, mapping param-bits 0..N onto the classes:
+DRM_UT_<*> for the DRM use-case.
+
+Dynamic Debug Classmap API
+==
+
+DYNDBG_CLASSMAP_DEFINE - modules use this to create classmaps, naming
+each of the classes (stringified enum-symbols: "DRM_UT_<*>"), and
+type, and mapping the class-names to consecutive _class_ids.
+
+By doing so, modules tell dyndbg that they have prdbgs with those
+class_ids, and they authorize dyndbg to accept "class FOO" for the
+module defining the classmap, and its contained classnames.
+
+DYNDBG_CLASSMAP_USE - drm drivers invoke this to ref the CLASSMAP that
+drm DEFINEs.  This shares the classmap definition, and authorizes
+dyndbg to apply changes to the user module's class'd pr_debugs.  It
+also tells dyndbg how to initialize the user's prdbgs at modprobe,
+based upon the current setting of the parent's controlling param.
+
+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)
+
+DYNDBG_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.
+
+This interface also enforces the DD_CLASS_TYPE_LEVEL_NUM relation
+amongst the contained classnames; all classes are independent in the
+control parser itself.
+
+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.45.2



[PATCH v9-resend 02/54] test-dyndbg: fixup CLASSMAP usage error

2024-07-17 Thread Jim Cromie
A more careful reading of logging output from test_dynamic_debug.ko
reveals:

lib/test_dynamic_debug.c:103 [test_dynamic_debug]do_cats =pmf "doing 
categories\n"
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, 105,106 have LOW/MID and MID/HI skew.

The enum's 1st val (explicitly initialized) was wrong; it must be
_base, not _base+1 (a DECLARE_DYNDBG_CLASSMAP param).  So the last
enumeration exceeded the range of mapped class-id's, which triggered
the "class unknown" report.  I coded in an error, intending to verify
err detection, then forgot, and missed that it was there.

So this patch fixes a bad usage of DECLARE_DYNDBG_CLASSMAP(), showing
that it is too error-prone.  As noted in test-mod comments:

 * 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-62 class_id space !!

Signed-off-by: Jim Cromie 
---
 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 8dd250ad022b..a01f0193a419 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.45.2



[PATCH v9-resend 06/54] dyndbg: ddebug_apply_class_bitmap - add module arg, select on it

2024-07-17 Thread Jim Cromie
Add param: query_module to ddebug_apply_class_bitmap(), and pass it
thru to _ddebug_queries(), replacing NULL with query_module.  This
allows its caller to update just one module, or all (as currently).

We'll use this later to propagate drm.debug to each USEr as they're
modprobed.

No functional change.

Signed-off-by: Jim Cromie 
---

after `modprobe i915`, heres the module dependencies,
though not all on drm.debug.

bash-5.2# lsmod
Module  Size  Used by
i915 3133440  0
drm_buddy  20480  1 i915
ttm90112  1 i915
i2c_algo_bit   16384  1 i915
video  61440  1 i915
wmi32768  1 video
drm_display_helper200704  1 i915
drm_kms_helper208896  2 drm_display_helper,i915
drm   606208  5 
drm_kms_helper,drm_display_helper,drm_buddy,i915,ttm
cec57344  2 drm_display_helper,i915
---
 lib/dynamic_debug.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 46e4cdd8e6be..a1fd2e9dbafb 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -605,7 +605,8 @@ static int ddebug_exec_queries(char *query, const char 
*modname)
 
 /* apply a new bitmap to the sys-knob's current bit-state */
 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];
@@ -613,7 +614,8 @@ 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);
+   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))
@@ -622,12 +624,15 @@ 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);
}
+   v2pr_info("applied bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
+ query_modname ?: "");
+
return matches;
 }
 
@@ -682,7 +687,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, _bits, 
dcp->bits);
+   totct += ddebug_apply_class_bitmap(dcp, _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]);
@@ -692,7 +697,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, _bits, 
_bits);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, 
_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);
@@ -755,7 +760,7 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
inrep &= CLASSMAP_BITMASK(map->length);
}
v2pr_info("bits:%lx > %s\n", inrep, KP_NAME(kp));
-   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits);
+   totct += ddebug_apply_class_bitmap(dcp, , dcp->bits, 
NULL);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -768,7 +773,7 @@ int param_set_dyndbg_classes(const char *instr, const 
struct kernel_param *kp)
old_bits = CLASSMAP_BITMASK(*dcp->lvl);
new_bits = CLASSM

[PATCH v9-resend 47/54] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver

2024-07-17 Thread 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 
---
 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.45.2



[PATCH v9-resend 20/54] selftests-dyndbg: add comma_terminator_tests

2024-07-17 Thread 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 
---
 .../selftests/dynamic_debug/dyndbg_selftest.sh | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index 1be70af26a38..b4ba293ab227 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -212,9 +212,23 @@ EOF
 ddcmd =_
 }
 
+function comma_terminator_tests {
+echo -e "${GREEN}# COMMA_TERMINATOR_TESTS ${NC}"
+# 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.45.2



[PATCH v9-resend 36/54] drm-dyndbg: DRM_CLASSMAP_USE in nouveau

2024-07-17 Thread 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 
---
 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 a947e1d5f309..27995c0c9b31 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -72,17 +72,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.45.2



[PATCH v9-resend 35/54] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper

2024-07-17 Thread 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 
---
 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 79a615667aab..26e01845531e 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -41,17 +41,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.45.2



[PATCH v9-resend 13/54] dyndbg: reduce verbose=3 messages in ddebug_add_module

2024-07-17 Thread Jim Cromie
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 
---
 lib/dynamic_debug.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index d4a0ae31d059..43a8e04b8599 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1245,11 +1245,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.45.2



[PATCH v9-resend 04/54] dyndbg: make ddebug_class_param union members same size

2024-07-17 Thread 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 
---
 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 73ccf947d4aa..152b04c05981 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.45.2



[PATCH v9-resend 12/54] dyndbg: tighten fn-sig of ddebug_apply_class_bitmap

2024-07-17 Thread 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 
---
 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 882354e1e78f..d4a0ae31d059 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -597,7 +597,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
@@ -606,12 +607,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, _bits))
continue;
 
snprintf(query, QUERY_SIZE, "class %s %c%s", 
map->class_names[bi],
@@ -623,9 +624,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;
 }
@@ -681,7 +682,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, _bits, 
dcp->bits, NULL);
+   totct += ddebug_apply_class_bitmap(dcp, _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]);
@@ -691,7 +692,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, _bits, 
_bits, NULL);
+   totct += ddebug_apply_class_bitmap(dcp, _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);
@@ -745,7 +746,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, , dcp->bits, 
modnm);
+   totct += ddebug_apply_class_bitmap(dcp, , *dcp->bits, 
modnm);
*dcp->bits = inrep;
break;
case DD_CLASS_TYPE_LEVEL_NUM:
@@ -758,7 +759,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, _bits, _bits, 
modnm);
+   totct += ddebug_apply_class_bitmap(dcp, _bits, old_bits, 
modnm);
*dcp->lvl = inrep;
break;
default:
-- 
2.45.2



[PATCH v9-resend 43/54] drm-dyndbg: add DRM_CLASSMAP_USE to gma500 driver

2024-07-17 Thread 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 
---
 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 8b64f61ffaf9..5e03ac7ff433 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -39,6 +39,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.45.2



[PATCH v9-resend 00/54] fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y

2024-07-17 Thread Jim Cromie
ne and export a classmap (in
core module), and 2. refer to the exported class-struct from the other
modules.

They both tell dynamic-debug that the module has some of these class'd
pr_debugs, so dyndbg can use the classmap's names to validate >control
inputs and change the callsites.  This is the opt-in.

The distinction allows USErs to act differently than the DEFINEr; they
have to follow the ref back to the DEFINEing module, find the kparam
connected to the classmap, and lookup and apply its modprobed value.
(this is the bug-fix).

Dyndbg uses the classnames to validate "class FOO" >control inputs,
and apply the changes to each module that has DEFINEd or USEd the
classmap.

This makes classmaps opt-in: modules must _DEFINE or _USE a classmap
for their class'd pr_debug()s to be >control'd.

NOTE: __pr_dbg_class(1, "const-int unreachable class 1"); is legal,
but not controllable unless the const 1 has been mapped to a _DEFINE'd
classname.

NB: and __pr_dbg_class(i++, "undeclared class") is illegal.

In drm_print.c we have: (theres room for better words...)

/* classnames must match value-symbols of enum drm_debug_category */
DRM_CLASSMAP_DEFINE(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS,
DRM_UT_CORE, // _base
/* this effectively names the bits in drm.debug */
"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");

This maps the sequence of "classnames" to ints starting with DRM_UT_CORE.
other _bases allow sharing the per-module 0..62 class-id space.
(63 is default/unclassed/common prdbg).

Only complete, linear maps are recommended.  This suits DRM.

DYNDBG_CLASSMAP_PARAM_REF() creates the sysfs-kparam classbits knob,
binding the extern'd long-int/bitvec to the classmap.  The extern
insures that old users of __drm_debug can still check its value.

DRM's categories are independent of each other.  The other possible
classmap-type/behavior is "related", ie somehow "ordered": V3>V2.  The
relatedness of classes in a classmap is enforced at the kparam, where
they are all set together, not at the >control interface.

THE PATCHSET has 2 halves:

1- dynamic-debug fix - API change

The root cause was DECLARE_DYNDBG_CLASSMAP tried to do too much, and
its use in both core and drivers, helpers couldnt sort the difference.

The fix is to replace it with DYNDBG_CLASSMAP_DEFINE in core, and
DYNDBG_CLASSMAP_USE in drivers,helpers. The 1st differs from -v1 by
exporting the classmap, allowing 2nd to ref it.  They respectively add
records to 2 ELF sections in the module.

Now, dyndbg's on-modprobe handler follows the _USE/refs to the owning
module, finds the controlling kparam: drm.debug, and applies its value
thru the classmap, to the module's pr_debugs.

A selftest script is included:
  :#> ./tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh

It recapitulates the DRM regression scenario using the 2 test modules.
The test verifies that the dependent module is initialized properly
from the parent's classmap kparam, and the classed prdbgs get enabled.

This latest rev fixes the test for the various CONFIG_DYNAMIC_DEBUG*
build combos, by skipping some subtests where the expected counts are
wrong. Lukasz Bartosik caught this - thanks.
CC: uka...@chromium.org

And 2 tweaks to kdoc & howto, to steer api users away from using
designated initializers to _DEFINE the classmap.


2- DRM fixes - use new api.

a. update core/drivers to invoke DRM_CLASSMAP_DEFINE/_USE
b. wrap DYNDBG_CLASSMAP_* with DRM_CLASSMAP_* - hide ifdef

c. now with separate +DRM_CLASSMAP_USE patches for each driver/helper: 
d. and defer dropping DECLARE_DYNDBG_CLASSMAP til later

Maybe theres a single place to invoke DRM_CLASSMAP_USE just once,
perhaps from a client library c-file. I poked a little, didn't find it.
It would be a bit obscured for an opt-in style declaration.

Patches are against v6.10
theyre also at:
tree/branch: https://github.com/jimc/linux.git dd-fix-9d
and lkp-robot told me:
[jimc:dd-fix-9d] BUILD SUCCESS 7c38f1d94f9919fec887113b620b83d60061c035


Finally, classmaps are in a meta-stable state right now; some governor
might yet walk it over to the gravel pit out back.

Tested-bys would help greatly, help get it off the fence it straddles.
Please specify your test method: selftest or drm.debug=0x1ff boot.

Next Im gonna try to haul this over to the freedesktop DRM-CI river,
presuming I can find the way (accts,etc)

Also entertaining Reviewed-bys :-}

Jim Cromie (54):

DYNAMIC-DEBUG parts:

cleanup:
  docs/dyndbg: update exam

[PATCH v9-resend 42/54] drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv

2024-07-17 Thread 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 
---
 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 6500f3999c5f..1d1ddbedcb5a 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.45.2



[PATCH v9-resend 50/54] drm-dyndbg: add DRM_CLASSMAP_USE to the qxl driver

2024-07-17 Thread 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 
---
 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 beee5563031a..1971bfa8a8a6 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -65,6 +65,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.45.2



[PATCH v9-resend 48/54] drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver

2024-07-17 Thread 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 
---
 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 573dbe256aa8..88c5e24cc894 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -25,6 +25,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 = >dev;
-- 
2.45.2



[PATCH v9-resend 32/54] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver

2024-07-17 Thread 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 
---
 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 ea14f1c8f430..83763d37566d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -217,17 +217,7 @@ int amdgpu_damage_clips = -1; /* auto */
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
-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.45.2



[PATCH v9-resend 11/54] dyndbg: tighten ddebug_class_name() 1st arg type

2024-07-17 Thread Jim Cromie
Change function's 1st arg-type, and deref in the caller.
The fn doesn't need any other fields in the struct.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8320cadeb251..882354e1e78f 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1120,12 +1120,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 = dt->classes;
+   int i;
 
-   for (i = 0; i < nc; i++, map++)
+   for (i = 0; i < dt->num_classes; i++, map++)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
 
@@ -1159,7 +1159,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
seq_puts(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
-- 
2.45.2



[PATCH v9-resend 49/54] drm-dyndbg: add DRM_CLASSMAP_USE to the gud driver

2024-07-17 Thread 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 
---
 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 9d7bf8ee45f1..5b555045fce4 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -31,6 +31,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.45.2



[PATCH v9-resend 53/54] dyndbg: tighten up kdoc about DYNDBG_CLASSMAP_* macros

2024-07-17 Thread Jim Cromie
The DYNDBG_CLASSMAP_DEFINE expects a list of classnames, and
maps them to consecutive classids starting at _base.  That
1- list-of-classnames can be syntactically replaced by a
2- designated-initializers-list/map.

But this creates ambiguity. The 1st thing the macro does:

   static const char *_var##_classnames[] = { __VA_ARGS__ };

This construct accepts either list form, cannot distinguish between
them, and they place data differently.

1. puts the string values into array[0..N-1]
2. puts them into array[_base..N+_base-1]

2 wastes 0.._base-1 indices, and more importantly, also spec's _base
twice: as a parameter, and then in the designated-initializers-list/map.

Further, the code is written for a contiguous range of classnames and
classids, and passing a map allows casual violation of this reasonable
design choice.

In particular, DRM_UT_* is a contiguous range, and each maps to a bit
in drm.debug.  The macro interface shouldn't suggest a sparse map is
possible.

So reword DYNDBG_CLASSMAP_* macro kdoc to more actively guide reader
away from designated initializers here.

TBD probably squash this back into the patchset.

CC: ville.syrj...@linux.intel.com
Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 52 +--
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index c958085e0df4..d75a5d3ae388 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -80,15 +80,22 @@ struct ddebug_class_map {
enum ddebug_class_map_type map_type;
 };
 
+/*
+ * modules using dyndbg-classmaps must invoke either
+ */
 /**
- * DYNDBG_CLASSMAP_DEFINE - define a set of debug-classes used by a module.
+ * DYNDBG_CLASSMAP_DEFINE - define debug classes used by a module.
  * @_var:   name of the classmap, exported for other modules coordinated use.
- * @_type:  enum ddebug_class_map_type, chooses bits/verbose, numeric/names.
- * @_base:  offset of 1st class-name, used to share 0..62 classid space
- * @classes: vals are stringified enum-vals, like DRM_UT_*
+ * @_type:  enum ddebug_class_map_type: DISJOINT - independent, LEVEL - v2>v1
+ * @_base:  reserve N classids starting at _base, to split 0..62 classid space
+ * @classes: names of the N classes.
  *
- * Defines and exports a struct ddebug_class_map whose @classes are
- * used to validate a "class FOO .." >control command on the module
+ * This tells dyndbg what classids the module is using, by mapping
+ * names onto them.  This qualifies "class NAME" >controls on the
+ * defining module, ignoring unknown names.
+ *
+ * The @classes also name the bits 0.. in any CLASSMAP_PARAM referring
+ * to the classmap.
  */
 #define __DYNDBG_CLASSMAP_DEFINE(_var, _maptype, _base, ...)   \
static const char *_var##_classnames[] = { __VA_ARGS__ };   \
@@ -131,9 +138,9 @@ struct ddebug_class_user {
  * DYNDBG_CLASSMAP_USE - refer to a classmap, DEFINEd elsewhere.
  * @_var: name of the exported classmap var
  *
- * This registers a module's use of another module's classmap defn, so
- * dyndbg can authorize "class DRM_CORE ..." >control commands upon
- * this module.
+ * 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 DYNDBG_CLASSMAP_USE(_var)  \
DYNDBG_CLASSMAP_USE_(_var, __UNIQUE_ID(ddebug_class_user))
@@ -165,27 +172,30 @@ struct ddebug_class_param {
 };
 
 /**
- * DYNDBG_CLASSMAP_PARAM - wrap a dyndbg-classmap with a controlling sys-param
- * @_name  sysfs node name
- * @_var   name of the struct classmap var defining the controlled classes
- * @_flags flags to be toggled, typically just 'p'
+ * DYNDBG_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
- * classmap.  Keeps bits in a private/static
+ * exported classmap, with bits 0..N-1 mapped to the classes named.
+ * This version keeps class-state in a private long int.
  */
 #define DYNDBG_CLASSMAP_PARAM(_name, _var, _flags) \
static unsigned long _name##_bvec;  \
__DYNDBG_CLASSMAP_PARAM(_name, _name##_bvec, _var, _flags)
 
 /**
- * DYNDBG_CLASSMAP_PARAM_REF - wrap a dyndbg-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 struct classmap var defining the controlled classes
- * @_flags flags to be toggled, typically just 'p'
+ * DYNDBG_CLASSMAP_PARAM_REF - wrap a classmap with a controlling sys-param
+ * @_name:  sys

[PATCH v9-resend 01/54] docs/dyndbg: update examples \012 to \n

2024-07-17 Thread 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 
---
 Documentation/admin-guide/dynamic-debug-howto.rst | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index 0e9b48daf690..6a8ce5a34382 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -52,12 +52,12 @@ query/commands to the control file.  Example::
   # grease the interface
   :#> alias ddcmd='echo $* > /proc/dynamic_debug/control'
 
-  :#> ddcmd '-p; module main func run* +p'
+  :#> ddcmd '-p; module main func run* +p' # disable all, then enable main
   :#> 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.45.2



[PATCH v9-resend 17/54] dyndbg-API: promote DYNDBG_CLASSMAP_PARAM to API

2024-07-17 Thread Jim Cromie
move the DYNDBG_CLASSMAP_PARAM macro from test-dynamic-debug.c into
the header, and refine it, by distinguishing the 2 use cases:

1.DYNDBG_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.DYNDBG_CLASSMAP_PARAM
new user (test_dynamic_debug) doesn't need to share state,
decls a static long unsigned int to store the bitvec.

__DYNDBG_CLASSMAP_PARAM
   bottom layer - allocate,init a ddebug-class-param, module-param-cb.

Also clean up and improve comments in test-code, and add
MODULE_DESCRIPTIONs.

Signed-off-by: Jim Cromie 
---

fixup drm-print.h  add PARAM_REF forwarding macros

with DYNDBG_CLASSMAP_PARAM_REF in the API, add DRM_ variant
---
 include/linux/dynamic_debug.h   | 37 -
 lib/dynamic_debug.c | 70 ++---
 lib/test_dynamic_debug.c| 50 +--
 lib/test_dynamic_debug_submod.c |  9 -
 4 files changed, 110 insertions(+), 56 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 189e3f60c31a..4a9b9cd53eb7 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -91,7 +91,7 @@ struct ddebug_class_map {
  * used to validate a "class FOO .." >control command on the module
  */
 #define __DYNDBG_CLASSMAP_DEFINE(_var, _maptype, _base, ...)   \
-   const char *_var##_classnames[] = { __VA_ARGS__ };  \
+   static const char *_var##_classnames[] = { __VA_ARGS__ };   \
struct ddebug_class_map __aligned(8) __used \
__section("__dyndbg_classes") _var = {  \
.mod = THIS_MODULE, \
@@ -164,6 +164,41 @@ struct ddebug_class_param {
const struct ddebug_class_map *map;
 };
 
+/**
+ * DYNDBG_CLASSMAP_PARAM - wrap a dyndbg-classmap with a controlling sys-param
+ * @_name  sysfs node name
+ * @_var   name of the struct classmap var defining the controlled classes
+ * @_flags flags to be toggled, typically just 'p'
+ *
+ * Creates a sysfs-param to control the classes defined by the
+ * classmap.  Keeps bits in a private/static
+ */
+#define DYNDBG_CLASSMAP_PARAM(_name, _var, _flags) \
+   static unsigned long _name##_bvec;  \
+   __DYNDBG_CLASSMAP_PARAM(_name, _name##_bvec, _var, _flags)
+
+/**
+ * DYNDBG_CLASSMAP_PARAM_REF - wrap a dyndbg-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 struct classmap var defining the controlled classes
+ * @_flags flags to be toggled, typically just 'p'
+ *
+ * Creates a sysfs-param to control the classmap, keeping bitvec in user 
@_bits.
+ * This lets drm use __drm_debug elsewhere too.
+ */
+#define DYNDBG_CLASSMAP_PARAM_REF(_name, _bits, _var, _flags)  \
+   __DYNDBG_CLASSMAP_PARAM(_name, _bits, _var, _flags)
+
+#define __DYNDBG_CLASSMAP_PARAM(_name, _bits, _var, _flags)\
+   static struct ddebug_class_param _name##_##_flags = {   \
+   .bits = &(_bits),   \
+   .flags = #_flags,   \
+   .map = &(_var), \
+   };  \
+   module_param_cb(_name, _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 9150e0e5145f..e9a95b0f3757 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -657,6 +657,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:%

[PATCH v9-resend 30/54] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2

2024-07-17 Thread 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 the classmap when CONFIG_DRM_USE_DYNAMIC_DEBUG=y, for direct
reference by drivers.

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 
---
 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 cf2efb44722c..41f167082042 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 089950ad8681..b467ee67a281 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -140,6 +140,14 @@ enum drm_debug_category {
DRM_UT_DRMRES
 };
 
+#ifdef CONFIG_DRM_USE_DYNAMIC_DEBUG
+#define DRM_CLASSMAP_DEFINE(...) DYNDBG_CLASSMAP_DEFINE(__VA_ARGS__)
+#define DRM_CLASSMAP_USE(name)   DYNDBG_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.45.2



[PATCH v9-resend 41/54] drm-dyndbg: add DRM_CLASSMAP_USE to bochs

2024-07-17 Thread 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 
---
 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 c23c9f0cf49c..ee98fab5597e 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -54,6 +54,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.45.2



Re: [PATCH v9 00/53] fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y

2024-07-16 Thread jim . cromie
On Mon, Jul 15, 2024 at 4:05 AM Łukasz Bartosik  wrote:
>
> On Sat, Jul 13, 2024 at 11:45 PM  wrote:
> >
> > On Fri, Jul 12, 2024 at 9:44 AM Łukasz Bartosik  wrote:
> > >
> > > On Wed, Jul 3, 2024 at 12:14 AM  wrote:
> > > >
> > > > On Tue, Jul 2, 2024 at 4:01 PM Luis Chamberlain  
> > > > wrote:
> > > > >
> > > > > On Tue, Jul 02, 2024 at 03:56:50PM -0600, Jim Cromie wrote:
> > > > > > This fixes dynamic-debug support for DRM.debug, added via classmaps.
> > > > > > commit bb2ff6c27bc9 (drm: Disable dynamic debug as broken)
> > > > > >
> > > > > > CONFIG_DRM_USE_DYNAMIC_DEBUG=y was marked broken because 
> > > > > > drm.debug=val
> > > > > > was applied when drm.ko was modprobed; too early for the yet-to-load
> > > > > > drivers, which thus missed the enablement.  My testing with
> > > > > > /etc/modprobe.d/ entries and modprobes with dyndbg=$querycmd options
> > > > > > obscured this omission.
> > > > > >
> > > > > > The fix is to replace invocations of DECLARE_DYNDBG_CLASSMAP with
> > > > > > DYNDBG_CLASSMAP_DEFINE for core, and DYNDBG_CLASSMAP_USE for 
> > > > > > drivers.
> > > > > > The distinction allows dyndbg to also handle the users properly.
> > > > > >
> > > > > > DRM is the only current classmaps user, and is not really using it,
> > > > > > so if you think DRM could benefit from zero-off-cost debugs based on
> > > > > > static-keys, please test.
> > > > > >
> > > > > > HISTORY
> > > > > >
> > > > > > 9/4/22  - ee879be38bc8..ace7c4bbb240 commited - classmaps-v1 dyndbg 
> > > > > > parts
> > > > > > 9/11/22 - 0406faf25fb1..16deeb8e18ca commited - classmaps-v1 drm 
> > > > > > parts
> > > > > >
> > > > > > https://lore.kernel.org/lkml/y3xurogav4i7b...@kroah.com/
> > > > > > greg k-h says:
> > > > > > This should go through the drm tree now.  The rest probably should 
> > > > > > also
> > > > > > go that way and not through my tree as well.
> > > > >
> > > > > Can't this just be defined as a coccinelle smpl patch? Must easier
> > > > > to read than 53 patches?
> > > > >
> > > >
> > > > perhaps it could - Im not sure that would be easier to review
> > > > than a file-scoped struct declaration or reference per driver
> > > >
> > > > Also, I did it hoping to solicit more Tested-by:s with drm.debug=0x1ff
> > > >
> > > > Jim
> > > >
> > >
> > > Jim,
> > >
> > > When testing different combinations of Y/M for TEST_DYNAMIC_DEBUG and
> > > TEST_DYNAMIC_DEBUG_SUBMOD in virtme-ng I spotted test failures:
> > >
> > > When the TEST_DYNAMIC_DEBUG=M and TEST_DYNAMIC_DEBUG_SUBMOD=M -
> > > BASIC_TESTS, COMMA_TERMINATOR_TESTS, TEST_PERCENT_SPLITTING,
> > > TEST_MOD_SUBMOD selftests passed
> > > When the TEST_DYNAMIC_DEBUG=Y and TEST_DYNAMIC_DEBUG_SUBMOD=M -
> > > BASIC_TESTS, COMMA_TERMINATOR_TESTS selftests passed, however
> > > TEST_PERCENT_SPLITTING selftest fails with ": ./dyndbg_selftest.sh:270
> > > check failed expected 1 on =pf, got 0"
> > > When the TEST_DYNAMIC_DEBUG=Y and TEST_DYNAMIC_DEBUG_SUBMOD=Y -
> > > BASIC_TESTS, COMMA_TERMINATOR_TESTS selftests passed, however
> > > TEST_PERCENT_SPLITTING selftest fails also with ":
> > > ./dyndbg_selftest.sh:270 check failed expected 1 on =pf, got 0"
> > >
> > > Have I missed something ?
> > >
> >
> > I am not seeing those 2 failures on those 2 configs.
> >
> > most of my recent testing has been on x86-defconfig + minimals,
> > built and run using/inside virtme-ng
> >
> > the last kernel I installed on this hw was june 16, I will repeat that,
> > and report soon if I see the failure outside the vm
> >
> > I'll also send you my script, to maybe speed isolation of the differences.
> >
>
> Jim,
>
> I know why I saw these failures.
> I ran dyndbg_selftest.sh directly in thw directory
> tools/testing/selftests/dynamic_debug/.

thats odd.
I mostly run it from src-root,
also whereever make selftest target is/works (I forgot)

I went into that subdir and ran it there
I got no test differe

Re: [PATCH v9 27/52] selftests-dyndbg: check KCONFIG_CONFIG to avoid silly fails

2024-07-15 Thread jim . cromie
On Wed, Jul 10, 2024 at 2:23 PM Helen Koike  wrote:
>
>
>
> On 02/07/2024 18:57, Jim Cromie wrote:
> > Several tests are dependent upon config choices. Lets avoid failing
> > where that is noise.
> >
...
> >
> > test_mod_submod() recaps the bug found in DRM-CI where drivers werent
>
> If this fixes any but listed in drm/ci/xfails folder, please update it too.
>
> Regards,
> Helen

This looks like a good avenue to follow, thanks for the hint


Re: [PATCH v9 00/53] fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y

2024-07-15 Thread jim . cromie
On Fri, Jul 12, 2024 at 9:44 AM Łukasz Bartosik  wrote:
>
> On Wed, Jul 3, 2024 at 12:14 AM  wrote:
> >
> > On Tue, Jul 2, 2024 at 4:01 PM Luis Chamberlain  wrote:
> > >
> > > On Tue, Jul 02, 2024 at 03:56:50PM -0600, Jim Cromie wrote:
> > > > This fixes dynamic-debug support for DRM.debug, added via classmaps.
> > > > commit bb2ff6c27bc9 (drm: Disable dynamic debug as broken)
> > > >
> > > > CONFIG_DRM_USE_DYNAMIC_DEBUG=y was marked broken because drm.debug=val
> > > > was applied when drm.ko was modprobed; too early for the yet-to-load
> > > > drivers, which thus missed the enablement.  My testing with
> > > > /etc/modprobe.d/ entries and modprobes with dyndbg=$querycmd options
> > > > obscured this omission.
> > > >
> > > > The fix is to replace invocations of DECLARE_DYNDBG_CLASSMAP with
> > > > DYNDBG_CLASSMAP_DEFINE for core, and DYNDBG_CLASSMAP_USE for drivers.
> > > > The distinction allows dyndbg to also handle the users properly.
> > > >
> > > > DRM is the only current classmaps user, and is not really using it,
> > > > so if you think DRM could benefit from zero-off-cost debugs based on
> > > > static-keys, please test.
> > > >
> > > > HISTORY
> > > >
> > > > 9/4/22  - ee879be38bc8..ace7c4bbb240 commited - classmaps-v1 dyndbg 
> > > > parts
> > > > 9/11/22 - 0406faf25fb1..16deeb8e18ca commited - classmaps-v1 drm parts
> > > >
> > > > https://lore.kernel.org/lkml/y3xurogav4i7b...@kroah.com/
> > > > greg k-h says:
> > > > This should go through the drm tree now.  The rest probably should also
> > > > go that way and not through my tree as well.
> > >
> > > Can't this just be defined as a coccinelle smpl patch? Must easier
> > > to read than 53 patches?
> > >
> >
> > perhaps it could - Im not sure that would be easier to review
> > than a file-scoped struct declaration or reference per driver
> >
> > Also, I did it hoping to solicit more Tested-by:s with drm.debug=0x1ff
> >
> > Jim
> >
>
> Jim,
>
> When testing different combinations of Y/M for TEST_DYNAMIC_DEBUG and
> TEST_DYNAMIC_DEBUG_SUBMOD in virtme-ng I spotted test failures:
>
> When the TEST_DYNAMIC_DEBUG=M and TEST_DYNAMIC_DEBUG_SUBMOD=M -
> BASIC_TESTS, COMMA_TERMINATOR_TESTS, TEST_PERCENT_SPLITTING,
> TEST_MOD_SUBMOD selftests passed
> When the TEST_DYNAMIC_DEBUG=Y and TEST_DYNAMIC_DEBUG_SUBMOD=M -
> BASIC_TESTS, COMMA_TERMINATOR_TESTS selftests passed, however
> TEST_PERCENT_SPLITTING selftest fails with ": ./dyndbg_selftest.sh:270
> check failed expected 1 on =pf, got 0"
> When the TEST_DYNAMIC_DEBUG=Y and TEST_DYNAMIC_DEBUG_SUBMOD=Y -
> BASIC_TESTS, COMMA_TERMINATOR_TESTS selftests passed, however
> TEST_PERCENT_SPLITTING selftest fails also with ":
> ./dyndbg_selftest.sh:270 check failed expected 1 on =pf, got 0"
>
> Have I missed something ?
>

I am not seeing those 2 failures on those 2 configs.

most of my recent testing has been on x86-defconfig + minimals,
built and run using/inside virtme-ng

the last kernel I installed on this hw was june 16, I will repeat that,
and report soon if I see the failure outside the vm

I'll also send you my script, to maybe speed isolation of the differences.

> Thanks,
> Lukasz
>
> > >   Luis
> > >


Re: [PATCH v9 30/52] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2

2024-07-10 Thread jim . cromie
On Wed, Jul 3, 2024 at 10:11 AM  wrote:
>
> Got it.
> I had some mental block about passing designated intializers as macro args.
> it just worked, I needed to eyeball the .i file just to be sure.
> thanks.
> I have a fixup patch.
> whats the best thing to do with it, squash it in for later ? send in
> reply here ?
>

I have to retract on designated-initializers into DYNDBG_CLASSMAP_DEFINE

While it works for DRM, and looks good, and self-documenting,
it only works cuz DRM_UT_CORE = 0,
and breaks when I used it 2x in test-dynamic-debug.ko.
the 2nd _DEFINE needs a _base > DRM_UT_LAST.


With designated-init exprs passed in thru the macro, I get:

1st classmap below is bad - the length should be 8, but is 28 cuz
init started at 20.

(gdb) p *di->classes@di->num_classes
$2 = {{mod = 0xc0203740, mod_name = 0xc0206220
"test_dynamic_debug",
class_names = 0xc0203080, length = 28, base = 20,
map_type = DD_CLASS_TYPE_LEVEL_NUM}, {
mod = 0xc0203740, mod_name = 0xc0206220
"test_dynamic_debug",
class_names = 0xc0203160, length = 10, base = 0,
map_type = DD_CLASS_TYPE_DISJOINT_BITS}}
(gdb)

so 1st 20 classnames are empty, and classnames -> index -> classid
translation fails later.

(gdb) p *di->classes[0]->class_names@di->classes[0]->length
$4 = {0x0  ,
0xc0206356 "V0", 0xc0206359 "V1",
  0xc020635c "V2", 0xc020635f "V3",
0xc0206362 "V4", 0xc0206365 "V5",
  0xc0206368 "V6", 0xc020636b "V7"}
(gdb)

Basically, when designated-inits are passed in, the _base param is redundant,
and the once guaranteed contiguous 0-based classnames list is now
guaranteed sparse.

the macro could be altered to expect designated-inits,
but I couldnt distinguish between the 2 different uses,
so theres a mis-use potential either way.

Id prefer to keep the _DEFINE the way it is,
and better kdoc & howto this to explain away the potential.

BTW: Im aware I failed to delete some v9*patch files before git send-email,
Im considering my penance, will resend soon.


Re: [PATCH v9 30/52] drm-dyndbg: adapt drm core to use dyndbg classmaps-v2

2024-07-04 Thread jim . cromie
Got it.
I had some mental block about passing designated intializers as macro args.
it just worked, I needed to eyeball the .i file just to be sure.
thanks.
I have a fixup patch.
whats the best thing to do with it, squash it in for later ? send in
reply here ?

On Wed, Jul 3, 2024 at 5:52 AM Ville Syrjälä
 wrote:
>
> On Tue, Jul 02, 2024 at 08:34:39PM -0600, jim.cro...@gmail.com wrote:
> > On Tue, Jul 2, 2024 at 5:33 PM Ville Syrjälä
> >  wrote:
> > >
> > > On Tue, Jul 02, 2024 at 03:57:20PM -0600, Jim Cromie wrote:
> > > > dyndbg's CLASSMAP-v1 api was broken; DECLARE_DYNDBG_CLASSMAP tried to
> > > > do too much.  Its replaced by DRM_CLASSMAP_DEFINE, which creates &
> > > > EXPORTs the classmap when CONFIG_DRM_USE_DYNAMIC_DEBUG=y, for direct
> > > > reference by drivers.
> > > >
> > > > 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 
> > > > ---
> > > >  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 699b7dbffd7b..4a5f2317229b 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");
> > >
> > > Looks like this stuff just ends up in an array, so presumably
> > > it should be possible to use designated initializers to make this
> > > less fragile?
> >
> > Im not sure I got your whole point, but:
>
> I mean using
>  [DRM_UT_CORE] = "DRM_UT_CORE"
> instead of
>  "DRM_UT_CORE"
> so there is no chance of screwing up the order.
> Or maybe the order doesn't even matter here?
>
> Could also stringify to avoid accidental of typos.
>
> >
> > the fragility is the repetitive re-statement of the map,
> > in those un-modified DECLARE_s,
> > once replaced, the USEs just ref the struct built by the _DEFINE
> > (once, and exported)
> >
> > I dont really like the _DEFINEs restatement of the enum-values: DRM_UT_*
> > especially as "strings".
> > I can automate the stringification with an APPLY_FN_(__stringify, ...)
> > but the enum-list DRM_UT_* (w.o quotes) is still needed as args.
> >
> > unless there is something C can do thats like Enum.values() ?
> >
> >
> >
> > >
> > > --
> > > Ville Syrjälä
> > > Intel
>
> --
> Ville Syrjälä
> Intel


[PATCH v9 40/52] drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm

2024-07-03 Thread 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 
---
 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 7ce1c4617675..9cab48bd0581 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -33,6 +33,8 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 /*
  * Helpers for simplefb
  */
-- 
2.45.2



[PATCH v9 13/52] dyndbg: reduce verbose=3 messages in ddebug_add_module

2024-07-03 Thread Jim Cromie
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 
---
 lib/dynamic_debug.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index d4a0ae31d059..43a8e04b8599 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1245,11 +1245,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.45.2



[PATCH v9 52/53] drm-dyndbg: add DRM_CLASSMAP_USE to the drm_gem_shmem_helper driver

2024-07-03 Thread 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 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index e435f986cd13..066d906e3199 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -23,6 +23,8 @@
 #include 
 #include 
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 MODULE_IMPORT_NS(DMA_BUF);
 
 /**
-- 
2.45.2



[PATCH v9 48/52] drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver

2024-07-03 Thread 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 
---
 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 573dbe256aa8..88c5e24cc894 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -25,6 +25,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 = >dev;
-- 
2.45.2



[PATCH v9 33/52] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver

2024-07-03 Thread 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 
---
 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 de43048543e8..dccf12d05105 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.45.2



[PATCH v9 45/52] drm-dyndbg: add DRM_CLASSMAP_USE to vmwgfx driver

2024-07-03 Thread 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 
---
 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 58fb40c93100..c159f4d186a3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -275,6 +275,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.45.2



[PATCH v9 34/53] drm-dyndbg: DRM_CLASSMAP_USE in i915 driver

2024-07-03 Thread 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 
---
 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 de43048543e8..dccf12d05105 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.45.2



[PATCH v9 44/52] drm-dyndbg: add DRM_CLASSMAP_USE to radeon

2024-07-03 Thread 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 
---
 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 7bf08164140e..d22308328c76 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -247,6 +247,8 @@ int radeon_cik_support = 1;
 MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = 
disabled)");
 module_param_named(cik_support, radeon_cik_support, int, 0444);
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
 };
-- 
2.45.2



[PATCH v9 21/52] dyndbg: split multi-query strings with %

2024-07-03 Thread 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=<
[  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 
---
 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 235d85765b63..dcec7b3657bb 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -596,7 +596,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.45.2



[PATCH v9 41/52] drm-dyndbg: add DRM_CLASSMAP_USE to bochs

2024-07-03 Thread 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 
---
 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 c23c9f0cf49c..ee98fab5597e 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -54,6 +54,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.45.2



[PATCH v9 37/52] drm-print: workaround unused variable compiler meh

2024-07-03 Thread Jim Cromie
With CONFIG_DRM_USE_DYNAMIC_DEBUG=y, I'm getting an unused variable
warning/error on 'category', though the usage follows immediately, in
drm_debug_enabled().

This drops the local var and refs the field directly in the
macro-call, which avoids the warning.  For static-key optimized
dyndbg, the macro doesn't actually check the category, since the
static-key patches in the proper state.  This is also likely why the
auto var appears to be unused by the compiler.

commit 9fd6f61a297e ("drm/print: add drm_dbg_printer() for drm device specific 
printer")
CC: Jani Nikula 
Signed-off-by: Jim Cromie 
---
 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 efdf82f8cbbb..c400441cd77e 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -183,11 +183,10 @@ 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;
const char *prefix = p->prefix ?: "";
const char *prefix_pad = p->prefix ? " " : "";
 
-   if (!__drm_debug_enabled(category))
+   if (!__drm_debug_enabled(p->category))
return;
 
/* Note: __builtin_return_address(0) is useless here. */
-- 
2.45.2



[PATCH v9 34/52] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper

2024-07-03 Thread 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 
---
 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 2dafc39a27cb..e9d229a393f4 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.45.2



[PATCH v9 43/53] drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv

2024-07-03 Thread 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 
---
 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 6500f3999c5f..1d1ddbedcb5a 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.45.2



[PATCH v9 42/52] drm-dyndbg: add DRM_CLASSMAP_USE to etnaviv

2024-07-03 Thread 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 
---
 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 6500f3999c5f..1d1ddbedcb5a 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.45.2



[PATCH v9 32/52] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver

2024-07-03 Thread 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 
---
 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 e4277298cf1a..b287f0cfd8fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -217,17 +217,7 @@ int amdgpu_damage_clips = -1; /* auto */
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
-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.45.2



[PATCH v9 10/52] dyndbg: silence debugs with no-change updates

2024-07-03 Thread Jim Cromie
In ddebug_apply_class_bitmap(), check for actual changes to the bits
before announcing them, to declutter logs.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 368381dbd266..8320cadeb251 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -595,7 +595,7 @@ 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,
 const char *query_modname)
@@ -606,8 +606,9 @@ static int ddebug_apply_class_bitmap(const struct 
ddebug_class_param *dcp,
int matches = 0;
int bi, ct;
 
-   v2pr_info("apply bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
- query_modname ?: "");
+   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))
@@ -622,8 +623,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);
}
-   v2pr_info("applied bitmap: 0x%lx to: 0x%lx for %s\n", *new_bits, 
*old_bits,
- query_modname ?: "");
+   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;
 }
-- 
2.45.2



[PATCH v9 22/52] selftests-dyndbg: test_percent_splitting

2024-07-03 Thread 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 
---
 .../dynamic_debug/dyndbg_selftest.sh  | 21 +++
 1 file changed, 21 insertions(+)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index b4ba293ab227..996e6fdcfb52 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -226,9 +226,30 @@ 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.45.2



[PATCH v9 05/52] dyndbg: replace classmap list with a vector

2024-07-03 Thread Jim Cromie
Classmaps are stored in an elf section/array, but are individually
list-linked onto dyndbg's per-module ddebug_table for operation.

This is unnecessary; even when ddebug_attach_classmap() is handling
the builtin section (with classmaps for multiple builtin modules), its
contents are ordered, so a module's possibly multiple classmaps will
be consecutive in the section, and could be treated as a vector/block,
since both start-address and subrange length are in the ddebug_info arg.

IOW, this treats classmaps similarly to _ddebugs, which are already
kept as vector-refs (address+len).

So this changes:

struct ddebug_class_map drops list-head link.

struct ddebug_table drops the list-head maps, and gets: classes &
num_classes for the start-address and num_classes, placed to improve
struct packing.

The loading: in ddebug_attach_module_classes(), replace the
for-the-modname list-add loop, with a forloop that finds the module's
subrange (start,length) of matching classmaps within the possibly
builtin classmaps vector, and saves those to the ddebug_table.

The reading/using: change list-foreach loops in ddebug_class_name() &
ddebug_find_valid_class() to walk the array from start to length.

Also:
Move #define __outvar up, above an added use in a fn-prototype.
Simplify ddebug_attach_module_classes args, ref has both address & len.

no functional changes

Signed-off-by: Jim Cromie 
---
 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 5231aaf361c4..b53217e4b711 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 152b04c05981..46e4cdd8e6be 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, >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
@@ -1114,9 +1116,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, >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];
 
@@ -1200,30 +1203,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 

[PATCH v9 44/53] drm-dyndbg: add DRM_CLASSMAP_USE to gma500 driver

2024-07-03 Thread 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 
---
 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 8b64f61ffaf9..5e03ac7ff433 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -39,6 +39,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.45.2



[PATCH v9 14/52] dyndbg-API: remove DD_CLASS_TYPE_(DISJOINT|LEVEL)_NAMES and code

2024-07-03 Thread Jim Cromie
Remove the NAMED class types; 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, simplify things.

also rename enum class_map_type to enum ddebug_class_map_type.

Signed-off-by: Jim Cromie 
---
 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 8116d0a0d33a..dd304e231f08 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -58,27 +58,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
 */
 };
 
@@ -88,7 +77,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 43a8e04b8599..d5701207febc 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -636,76 +636,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, _bits) == wanted) {
-   v3pr_info("no change on %s\n", cl_str);
-   continue;
-   }
-   curr_bits ^= BIT(cls_id);
-   totct += ddebug_apply_class_bitmap(dcp, _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_

[PATCH v9 41/53] drm-dyndbg: add DRM_CLASSMAP_USE to simpledrm

2024-07-03 Thread 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 
---
 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 7ce1c4617675..9cab48bd0581 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -33,6 +33,8 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 /*
  * Helpers for simplefb
  */
-- 
2.45.2



[PATCH v9 33/53] drm-dyndbg: DRM_CLASSMAP_USE in amdgpu driver

2024-07-03 Thread 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 
---
 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 e4277298cf1a..b287f0cfd8fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -217,17 +217,7 @@ int amdgpu_damage_clips = -1; /* auto */
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
-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.45.2



[PATCH v9 11/52] dyndbg: tighten ddebug_class_name() 1st arg type

2024-07-03 Thread Jim Cromie
Change function's 1st arg-type, and deref in the caller.
The fn doesn't need any other fields in the struct.

no functional change.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8320cadeb251..882354e1e78f 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1120,12 +1120,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 = dt->classes;
+   int i;
 
-   for (i = 0; i < nc; i++, map++)
+   for (i = 0; i < dt->num_classes; i++, map++)
if (class_in_range(dp->class_id, map))
return map->class_names[dp->class_id - map->base];
 
@@ -1159,7 +1159,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
seq_puts(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
-- 
2.45.2



[PATCH v9 35/53] drm-dyndbg: DRM_CLASSMAP_USE in drm_crtc_helper

2024-07-03 Thread 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 
---
 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 2dafc39a27cb..e9d229a393f4 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.45.2



[PATCH v9 37/53] drm-dyndbg: DRM_CLASSMAP_USE in nouveau

2024-07-03 Thread 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 
---
 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 a947e1d5f309..27995c0c9b31 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -72,17 +72,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.45.2



[PATCH v9 39/52] drm-dyndbg: add DRM_CLASSMAP_USE to virtio_gpu

2024-07-03 Thread 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 
---
 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 9539aa28937f..bb3a3e042264 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -44,6 +44,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.45.2



[PATCH v9 32/53] DRM-CLASSMAP-USE in drm-drv.c

2024-07-03 Thread Jim Cromie
---
 drivers/gpu/drm/drm_drv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 243cacb3575c..f511d40f577a 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -56,6 +56,9 @@ MODULE_LICENSE("GPL and additional rights");
 static DEFINE_SPINLOCK(drm_minor_lock);
 static struct idr drm_minors_idr;
 
+/* single ref for all clients ? */
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 /*
  * If the drm core fails to init for whatever reason,
  * we should prevent any drivers from registering with it.
-- 
2.45.2



[PATCH v9 27/52] selftests-dyndbg: check KCONFIG_CONFIG to avoid silly fails

2024-07-03 Thread Jim Cromie
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=.  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.

Signed-off-by: Jim Cromie 

fixup-kconfig
---
 .../dynamic_debug/dyndbg_selftest.sh  | 45 ++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index fccd2012b548..d09ef26b2308 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -11,6 +11,30 @@ 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
 }
@@ -192,6 +216,10 @@ function check_err_msg() {
 
 function basic_tests {
 echo -e "${GREEN}# BASIC_TESTS ${NC}"
+if [ $LACK_DD_BUILTIN -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 ddcmd =_ # zero everything (except class'd sites)
 check_match_ct =p 0
 # there are several main's :-/
@@ -214,6 +242,10 @@ EOF
 
 function comma_terminator_tests {
 echo -e "${GREEN}# COMMA_TERMINATOR_TESTS ${NC}"
+if [ $LACK_DD_BUILTIN -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 # try combos of spaces & commas
 check_match_ct '\[params\]' 4 -r
 ddcmd module,params,=_ # commas as spaces
@@ -226,9 +258,12 @@ function comma_terminator_tests {
 ddcmd =_
 }
 
-
 function test_percent_splitting {
 echo -e "${GREEN}# TEST_PERCENT_SPLITTING - multi-command splitting on % 
${NC}"
+if [ $LACK_TMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 ifrmmod test_dynamic_debug_submod
 ifrmmod test_dynamic_debug
 ddcmd =_
@@ -248,6 +283,14 @@ function test_percent_splitting {
 
 function test_mod_submod {
 echo -e "${GREEN}# TEST_MOD_SUBMOD ${NC}"
+if [ $LACK_TMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
+if [ $LACK_TMOD_SUBMOD -eq 1 ]; then
+   echo "SKIP"
+   return
+fi
 ifrmmod test_dynamic_debug_submod
 ifrmmod test_dynamic_debug
 ddcmd =_
-- 
2.45.2



[PATCH v9 36/53] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper

2024-07-03 Thread 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 
---
 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 f5d4be897866..d3a7df09846f 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -41,17 +41,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.45.2



[PATCH v9 53/53] drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN

2024-07-03 Thread Jim Cromie
end of official submission.

Time for some quality CI

Signed-off-by: Jim Cromie 
---
 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 5a0c476361c3..b2ea73ae48f0 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -54,8 +54,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.45.2



[PATCH v9 36/52] drm-dyndbg: DRM_CLASSMAP_USE in nouveau

2024-07-03 Thread 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 
---
 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 a947e1d5f309..27995c0c9b31 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -72,17 +72,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.45.2



[PATCH v9 45/53] drm-dyndbg: add DRM_CLASSMAP_USE to radeon

2024-07-03 Thread 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 
---
 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 7bf08164140e..d22308328c76 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -247,6 +247,8 @@ int radeon_cik_support = 1;
 MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = 
disabled)");
 module_param_named(cik_support, radeon_cik_support, int, 0444);
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
 };
-- 
2.45.2



[PATCH v9 26/52] dyndbg: change __dynamic_func_call_cls* macros into expressions

2024-07-03 Thread 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 it by changing __dynamic_func_call_cls{,_no_desc} macros into
expressions, by replacing the do-while-0s with a ({ }) wrapper.

In C, all legal expressions are also legal statements, as converted by
the trailing semi-colon in a statement-style macro invocation:

   drm_dbg("statement form");

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 19f959f9a6b4..121a66b0ca25 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -287,20 +287,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_func_call_cls(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(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.45.2



[PATCH v9 48/53] drm-dyndbg: add DRM_CLASSMAP_USE to udl driver

2024-07-03 Thread 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 
---
 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.45.2



[PATCH v9 52/52] drm: restore CONFIG_DRM_USE_DYNAMIC_DEBUG un-BROKEN

2024-07-03 Thread Jim Cromie
end of official submission.

Time for some quality CI

Signed-off-by: Jim Cromie 
---
 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 5a0c476361c3..b2ea73ae48f0 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -54,8 +54,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.45.2



[PATCH v9 24/52] selftests-dyndbg: add test_mod_submod

2024-07-03 Thread Jim Cromie
This new test-fn runs 3 module/submodule modprobe scenarios, variously
using both the generic dyndbg= 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 
---
 .../dynamic_debug/dyndbg_selftest.sh  | 67 +++
 1 file changed, 67 insertions(+)

diff --git a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh 
b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
index 996e6fdcfb52..fccd2012b548 100755
--- a/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
+++ b/tools/testing/selftests/dynamic_debug/dyndbg_selftest.sh
@@ -246,10 +246,77 @@ 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 -v
+check_match_ct =plt 1 -v
+check_match_ct =pml 1 -v
+#  submod changed too
+check_match_ct =mf 1 -v
+check_match_ct =lt 1 -v
+check_match_ct =ml 1 -v
+
+# 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 -v
+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 -v
+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 -v
+
+# 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 -v
+modprobe test_dynamic_debug_submod
+# see them picked up by submod
+check_match_ct =p 14 -v
+}
+
 tests_list=(
 basic_tests
+# these require test_dynamic_debug*.ko
 comma_terminator_tests
 test_percent_splitting
+test_mod_submod
 )
 
 # Run tests
-- 
2.45.2



Re: [PATCH v9 00/53] fix CONFIG_DRM_USE_DYNAMIC_DEBUG=y

2024-07-03 Thread jim . cromie
On Tue, Jul 2, 2024 at 4:01 PM Luis Chamberlain  wrote:
>
> On Tue, Jul 02, 2024 at 03:56:50PM -0600, Jim Cromie wrote:
> > This fixes dynamic-debug support for DRM.debug, added via classmaps.
> > commit bb2ff6c27bc9 (drm: Disable dynamic debug as broken)
> >
> > CONFIG_DRM_USE_DYNAMIC_DEBUG=y was marked broken because drm.debug=val
> > was applied when drm.ko was modprobed; too early for the yet-to-load
> > drivers, which thus missed the enablement.  My testing with
> > /etc/modprobe.d/ entries and modprobes with dyndbg=$querycmd options
> > obscured this omission.
> >
> > The fix is to replace invocations of DECLARE_DYNDBG_CLASSMAP with
> > DYNDBG_CLASSMAP_DEFINE for core, and DYNDBG_CLASSMAP_USE for drivers.
> > The distinction allows dyndbg to also handle the users properly.
> >
> > DRM is the only current classmaps user, and is not really using it,
> > so if you think DRM could benefit from zero-off-cost debugs based on
> > static-keys, please test.
> >
> > HISTORY
> >
> > 9/4/22  - ee879be38bc8..ace7c4bbb240 commited - classmaps-v1 dyndbg parts
> > 9/11/22 - 0406faf25fb1..16deeb8e18ca commited - classmaps-v1 drm parts
> >
> > https://lore.kernel.org/lkml/y3xurogav4i7b...@kroah.com/
> > greg k-h says:
> > This should go through the drm tree now.  The rest probably should also
> > go that way and not through my tree as well.
>
> Can't this just be defined as a coccinelle smpl patch? Must easier
> to read than 53 patches?
>

perhaps it could - Im not sure that would be easier to review
than a file-scoped struct declaration or reference per driver

Also, I did it hoping to solicit more Tested-by:s with drm.debug=0x1ff

Jim

>   Luis
>


[PATCH v9 49/53] drm-dyndbg: add DRM_CLASSMAP_USE to mgag200 driver

2024-07-03 Thread 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 
---
 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 573dbe256aa8..88c5e24cc894 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -25,6 +25,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 = >dev;
-- 
2.45.2



[PATCH v9 38/52] drm-dyndbg: add DRM_CLASSMAP_USE to Xe driver

2024-07-03 Thread 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 
---
 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 87c10bd7958b..c61163d0d945 100644
--- a/drivers/gpu/drm/xe/xe_drm_client.c
+++ b/drivers/gpu/drm/xe/xe_drm_client.c
@@ -15,6 +15,8 @@
 #include "xe_drm_client.h"
 #include "xe_trace.h"
 
+DRM_CLASSMAP_USE(drm_debug_classes);
+
 /**
  * xe_drm_client_alloc() - Allocate drm client
  * @void: No arg
-- 
2.45.2



[PATCH v9 35/52] drm-dyndbg: DRM_CLASSMAP_USE in drm_dp_helper

2024-07-03 Thread 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 
---
 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 f5d4be897866..d3a7df09846f 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -41,17 +41,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.45.2



  1   2   3   4   5   6   7   8   9   >