[PATCH 58/65] dyndbg: drop "protection" of class'd pr_debugs from legacy queries

Jim Cromie jim.cromie at gmail.com
Tue Oct 1 19:34:47 UTC 2024


Current classmap code protects class'd pr_debugs from unintended
changes by "legacy" unclassed queries:

  # this doesn't disable all of DRM_UT_* categories
  echo "-p" > /proc/dynamic_debug/control

  # name the class to change it - protective but tedious
  echo "class DRM_UT_CORE +p" > /proc/dynamic_debug/control

  # or do it the subsystem way
  echo 1 > /sys/module/drm/parameters/debug

This "name the class to change it" behavior gave a modicum of
protection to classmap users, so their debug settings aren't trivially
and unintentionally altered underneath them.

But this made the class keyword special; the other keywords follow
the rule: no "keyword value" given means no skipping on that
criterion.

Jason Baron didn't like this special case when I 1st proposed it; I
argued the above, and thought I'd convinced him, but he noted it again
when he reviewed this series.  So this commit removes the special
case.  The change is surprisingly small, and also bigger than strictly
necessary, so it warrants more explanation.

When given a "class FOO" query, ddebug_change() may examine class 2x
for each module; the outer loop determines if FOO is a valid_class for
the module, skipping the whole module on invalid ones like "class
JUNK"; the inner loop matches the module's pr_debugs against the
valid_class.

The special case is when no "class FOO" is given;
  previously: valid_class = _DPRINTK_CLASS_DFLT
  updated:    valid_class = _DPRINTK_CLASS_ANY

The inner loop skips pr_debugs not matching valid_class, so it needs a
definite value out of the else clause in the outer loop.  It *now*
also checks != _DPRINTK_CLASS_ANY.  This added condition allows
unclass'd queries to fall thru to adjust the class'd pr_debugs.

NB: The new _DPRINTK_CLASS_ANY const aliases to _DPRINTK_CLASS_DFLT,
since theres no need for a distinct value; the name change marks how
the value is now used, both where valid_class is set (in the outer
loop), then the added check(s) against it in the inner loop.

CC: jbaron at akamai.com
Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/linux/dynamic_debug.h |  2 ++
 lib/dynamic_debug.c           | 15 ++++++++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 93069f9e9689..e729aff78ea7 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -26,6 +26,8 @@ struct _ddebug {
 #define CLS_BITS 6
 	unsigned int class_id:CLS_BITS;
 #define _DPRINTK_CLASS_DFLT		((1 << CLS_BITS) - 1)
+#define _DPRINTK_CLASS_ANY		_DPRINTK_CLASS_DFLT /* 2nd meaning */
+
 	/*
 	 * The flags field controls the behaviour at the callsite.
 	 * The bits here are changed dynamically when the user
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index d62fa8dadf14..697e8050ae83 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -209,17 +209,22 @@ static int ddebug_change(const struct ddebug_query *query, struct flag_settings
 		if (query->class_string) {
 			valid_class = ddebug_find_valid_class(dt, query->class_string);
 			if (valid_class < 0)
+				/* skip/reject unknown classes */
 				continue;
 		} else {
-			/* constrain query, do not touch class'd callsites */
-			valid_class = _DPRINTK_CLASS_DFLT;
+			valid_class = _DPRINTK_CLASS_ANY;
 		}
 
 		for (i = 0; i < dt->num_ddebugs; i++) {
 			struct _ddebug *dp = &dt->ddebugs[i];
-
-			/* match site against query-class */
-			if (dp->class_id != valid_class)
+			/*
+			 * skip site if its class isn't the one
+			 * queried, unless its the default class.
+			 * 2nd term drops protection of class'd
+			 * prdbgs from unclassed queries.
+			 */
+			if (dp->class_id != valid_class &&
+			    valid_class != _DPRINTK_CLASS_ANY)
 				continue;
 
 			/* match against the source filename */
-- 
2.46.2



More information about the Intel-gfx-trybot mailing list