diff mbox series

[v2,12/27] dyndbg: change zero-or-one classes-map to maps list

Message ID 20220516225640.3102269-13-jim.cromie@gmail.com (mailing list archive)
State New, archived
Headers show
Series DRM.debug on DYNAMIC_DEBUG, add trace events | expand

Commit Message

Jim Cromie May 16, 2022, 10:56 p.m. UTC
Upgrade single classes-map to list of them:

This allows multiple DYNAMIC_DEBUG_CLASSES(class-map)s per module,
using _base to segment the 0..30 classid space.

alter struct ddebug table:
 replace .classes (a &map) with maps (list-head)

dynamic_debug_register_classes(map) - adds new map to maps list.

dynamic_debug_unregister_classes(map) - deletes map after ID-check.

ddebug_validate_classname() - check all maps in list before failing.

ddebug_class_name() - which supports ```cat control``` now walks maps
list, finds the map whose sub-range of .class_id's spans the one in
the callsite, and returns that class-name.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
. split out validate_classnames()
. fold in fixes for multi class-maps
---
 lib/dynamic_debug.c | 76 +++++++++++++++++++++++++++++++--------------
 1 file changed, 52 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8e1b9159e881..f9c5bbf9d43b 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -43,10 +43,8 @@  extern struct _ddebug __start___dyndbg[];
 extern struct _ddebug __stop___dyndbg[];
 
 struct ddebug_table {
-	struct list_head link;
+	struct list_head link, maps;
 	const char *mod_name;
-	/* a module can have multiple class-sets eventually, but not yet */
-	struct ddebug_known_classes_map const *map;
 	unsigned int num_ddebugs;
 	struct _ddebug *ddebugs;
 };
@@ -149,28 +147,18 @@  static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
 /* return <0 if class-name is unknown/invalid, 0..CLASS_DFLT otherwise */
 static int ddebug_validate_classname(struct ddebug_table *dt, const char *class_string)
 {
-	int query_class = -ENOENT;
+	struct ddebug_known_classes_map *map;
 	int idx;
 
 	if (!class_string)
-		/* all queries w/o class given work only on default class */
 		return _DPRINTK_CLASS_DFLT;
 
-	/*
-	 * XXX single list will need to be a for-list
-	 * so that modules can have 2 sets of class-decls
-	 */
-	if (!dt->map)
-		return -ENOENT;
-
-	idx = match_string(dt->map->classes, dt->map->length, class_string);
-	if (idx < 0) {
-		v3pr_info("class: %s.%s unknown\n", dt->mod_name, class_string);
-		return -ENOENT;
+	list_for_each_entry(map, &dt->maps, link) {
+		idx = match_string(map->classes, map->length, class_string);
+		if (idx >= 0)
+			return idx + map->base;
 	}
-	query_class = idx + dt->map->base;
-
-	return query_class;
+	return -ENOENT;
 }
 
 /*
@@ -1032,8 +1020,14 @@  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)
 {
-	if (iter->table->map)
-		return iter->table->map->classes[dp->class_id];
+	struct ddebug_known_classes_map *map;
+
+	list_for_each_entry(map, &iter->table->maps, link) {
+		if (dp->class_id < map->base ||
+		    dp->class_id >= map->base + map->length)
+			continue;
+		return map->classes[dp->class_id - map->base];
+	}
 	return NULL;
 }
 
@@ -1124,6 +1118,7 @@  int dynamic_debug_register_classes(struct ddebug_known_classes_map *map)
 	struct ddebug_table *dt;
 	int rc = -ENOENT;
 
+	INIT_LIST_HEAD(&map->link);
 	mutex_lock(&ddebug_lock);
 #ifdef CONFIG_MODULES
 	if (map->mod) {
@@ -1131,7 +1126,7 @@  int dynamic_debug_register_classes(struct ddebug_known_classes_map *map)
 		list_for_each_entry(dt, &ddebug_tables, link) {
 			if (dt->mod_name == map->mod->name) {
 				rc = 0;
-				dt->map = map;
+				list_add(&map->link, &dt->maps);
 				break;
 			}
 		}
@@ -1142,7 +1137,7 @@  int dynamic_debug_register_classes(struct ddebug_known_classes_map *map)
 		list_for_each_entry(dt, &ddebug_tables, link) {
 			if (!strcmp(dt->mod_name, map->mod_name)) {
 				rc = 0;
-				dt->map = map;
+				list_add(&map->link, &dt->maps);
 				break;
 			}
 		}
@@ -1159,8 +1154,38 @@  EXPORT_SYMBOL(dynamic_debug_register_classes);
 
 void dynamic_debug_unregister_classes(struct ddebug_known_classes_map *map)
 {
-	vpr_info("unregister_classes: %s\n", map->mod_name);
+	int rc = -ENOENT;
+
+	mutex_lock(&ddebug_lock);
+#ifdef CONFIG_MODULES
+	if (map->mod) {
+		struct ddebug_known_classes_map *dmap;
+		struct ddebug_table *dt;
+
+		list_for_each_entry(dt, &ddebug_tables, link) {
+			if (dt->mod_name != map->mod->name)
+				continue;
+			list_for_each_entry(dmap, &dt->maps, link) {
+				if (dmap != map)
+					continue;
+				rc = 0;
+				list_del(&map->link);
+				break;
+			}
+		}
+	}
+#endif
+	if (!map->mod) {
+		pr_err("shouldn't be unloading a builtin module: %s\n",
+		       map->mod_name);
+	}
+	mutex_unlock(&ddebug_lock);
+	if (rc)
+		pr_warn("unregister_classes: module %s not found\n", map->mod_name);
+	else
+		vpr_info("unregister_classes: %s\n", map->mod_name);
 }
+EXPORT_SYMBOL(dynamic_debug_unregister_classes);
 
 /*
  * Allocate a new ddebug_table for the given module
@@ -1186,6 +1211,9 @@  int ddebug_add_module(struct _ddebug *tab, unsigned int n,
 	dt->num_ddebugs = n;
 	dt->ddebugs = tab;
 
+	INIT_LIST_HEAD(&dt->link);
+	INIT_LIST_HEAD(&dt->maps);
+
 	mutex_lock(&ddebug_lock);
 	list_add(&dt->link, &ddebug_tables);
 	mutex_unlock(&ddebug_lock);