[PATCH v2 11/27] dyndbg: support symbolic class-names in bitmap

Jim Cromie jim.cromie at gmail.com
Mon May 16 15:56:24 PDT 2022


Extend the sysfs-node bitmap support to accept class-names
registered by the module, allowing:

   #> echo DRM_UT_CORE,-DRM_UT_ATOMIC,+DRM_UT_KMS \
    	 > /sys/module/drm/parameters/debug

Do this in param_set_dyndbg_class_strings(), which is called from
param_set_dyndbg_classes() when the input string isn't a integer.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>

---
. continue/skip on unknown class, so following symbols are processed.
. better loadable module handling, no more KP_MOD_NAME
. add do_callback_changes
---
 lib/dynamic_debug.c | 63 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 42dce2e76014..8e1b9159e881 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -618,6 +618,61 @@ static int do_callback_changes(const struct ddebug_classes_bitmap_param *dcp,
 	return matches;
 }
 
+/* support for [+-] symbolic-name boolean list */
+static int param_set_dyndbg_class_strings(const char *instr, const struct kernel_param *kp)
+{
+	const struct ddebug_classes_bitmap_param *dcp = kp->arg;
+	unsigned long inbits;
+	int idx_rc, totct = 0;
+	bool wanted;
+	char *cls, *p;
+
+	if (!dcp || !dcp->map) {
+		pr_err("set_dyndbg_classes: no bits=>queries map\n");
+		return -EINVAL;
+	}
+
+	cls = kstrdup(instr, GFP_KERNEL);
+	p = strchr(cls, '\n');
+	if (p)
+		*p = '\0';
+
+	inbits = *dcp->bits;
+	vpr_info("set_dyndbg_class_strings: %s on 0x%lx\n", cls, inbits);
+
+	for (; cls; cls = p) {
+		p = strchr(cls, ',');
+		if (p)
+			*p++ = '\0';
+
+		if (*cls == '-') {
+			wanted = false;
+			cls++;
+		} else {
+			wanted = true;
+			if (*cls == '+')
+				cls++;
+		}
+		idx_rc = match_string(dcp->map->classes, dcp->map->length, cls);
+		if (idx_rc < 0) {
+			pr_err("%s not found for module: %s\n", cls, dcp->map->mod_name);
+			continue;
+		}
+		if (test_bit(idx_rc, &inbits) == wanted) {
+			v3pr_info("no change on %s\n", cls);
+			continue;
+		}
+
+		vpr_info("set_dyndbg_classes: bit %d: %s\n", idx_rc, dcp->map->classes[idx_rc]);
+		inbits ^= BIT(idx_rc);
+		totct += do_callback_changes(dcp, idx_rc, &inbits);
+	}
+	kfree(cls);
+	*dcp->bits = inbits;
+	vpr_info("total matches: %d\n", totct);
+	return 0;
+}
+
 /**
  * param_set_dyndbg_classes - bits => categories >control setter
  * @instr: string echo>d to sysfs
@@ -639,10 +694,9 @@ int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
 		return -EINVAL;
 	}
 	rc = kstrtoul(instr, 0, &inbits);
-	if (rc) {
-		pr_err("set_dyndbg_classes: expecting bits/integer\n");
-		return -EINVAL;
-	}
+	if (rc)
+		return param_set_dyndbg_class_strings(instr, kp);
+
 	vpr_info("set_dyndbg_classes: new 0x%lx current 0x%lx\n", inbits, *dcp->bits);
 
 	for (i = 0; i < dcp->map->length; i++) {
@@ -650,6 +704,7 @@ int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp)
 		if (test_bit(i, &inbits) == test_bit(i, dcp->bits))
 			continue;
 
+		vpr_info("set_dyndbg_classes: bit %d: %s\n", i, dcp->map->classes[i]);
 		totct += do_callback_changes(dcp, i, &inbits);
 	}
 	*dcp->bits = inbits;
-- 
2.35.3




More information about the linux-arm-kernel mailing list