[PATCH 63/64] dyndbg: refactor ddebug_attach_*module_classes

Jim Cromie jim.cromie at gmail.com
Sun Oct 6 19:22:43 UTC 2024


These 2 funcs are extremely similar, they differ mostly by working on
2 different array types: structs ddebug_class_map & ddebug_class_user.
Add several macros to encapsulate the boilerplate.

1. for_subvec(_i, _cur, _box, _arr_ref):

This encapsulates the iteration over num_##_arr_ref elements in
_box->_arr_ref.  IE: _box->_arr_ref [ 0 .. _box->num_##_arr_ref ].
_curr exposes the items to the loop body.

2. dd_mark_vector_subrange(i, dt, cur, box, _arr):

Both of ddebug_attach_*classes() start with a block of code that scans
the (linker-ordered) class_{maps,users}, and finds the subrange which
matches on mod_name.  Rewrite this as a macro.  It finds the start and
length of the matching sub-array, and saves it into the dt record.

With the 2 blocks reduced to calls to dd_mark_vector_subrange(), hoist
the calls up to the functions' common caller: ddebug_add_module(), so we
can drop the early returns in those funcs, and explain the purpose
just once.

dd_mark_vector_subrange() exists to "clean up" the classmaps, and is
only needed to handle multiple builtin class_maps,_users; loadable
modules contain only the classmaps they DYNDBG_CLASSMAP_{DEFINE,USE},
and the macro will match on the whole array-range given.

It's task is analogous to how ddebug_init() segments the large array
of builtin descriptors by marking each module's subrange (start,len)
in the di cursor.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 lib/dynamic_debug.c | 107 +++++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 51 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f757f3d6bde4..3281eb7383b1 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -53,7 +53,7 @@ struct ddebug_table {
 	struct ddebug_class_map *classes;
 	struct ddebug_class_user *class_users;
 	unsigned int num_ddebugs, num_classes, num_class_users;
-};
+} __packed;
 
 struct ddebug_query {
 	const char *filename;
@@ -1257,77 +1257,72 @@ static int ddebug_class_range_overlap(struct ddebug_class_map *cm,
 }
 
 /*
- * Find this module's classmaps in a sub/whole-range of the builtin/
- * modular classmap vector/section.  Save the start and length of the
- * subrange at its edges.
+ * simplify a repeated for-loop pattern walking N steps in a T _vec
+ * member inside a struct _box.  It expects int i and T *_sp to be
+ * declared in the caller.
+ * @_i:  caller provided counter.
+ * @_sp: cursor into _vec, to examine each item.
+ * @_vec: name of array-ref member in _box.
+ * @_box: ptr to a struct containing _vec, num__##_vec fields.
+ */
+#define for_subvec(_i, _sp, _box, _vec)					\
+	for (_i = 0, (_sp) = (_box)->_vec;				\
+	     _i < (_box)->num_##_vec;					\
+	     _i++, (_sp)++)
+/*
+ * scan the linker-ordered @_vec, of num_##_vec elements, for the
+ * start,len of the elements matching on ->mod_name; remember them in
+ * _dst.  Macro depends upon the fields being in both _box and _dst.
+ * @_i:   caller provided counter.
+ * @_sp:  cursor into @_vec.
+ * @_box: ptr to a struct with @_vec, num__##@_vec, mod_name fields.
+ * @_vec: name of ref into array[T] of builtin/modular __section data.
+ * @_dst: ptr to struct with @_vec and num__##@_vec fields, both updated.
  */
+#define __evalout /* macro "return" val */
+#define dd_mark_vector_subrange(_i, _dst, _sp, _box, _vec) ({		\
+	int nc = 0;							\
+	for_subvec(_i, _sp, _box, _vec) {				\
+		if (!strcmp((_sp)->mod_name, (_dst)->mod_name)) {	\
+			if (!nc++)					\
+				(_dst)->_vec = (_sp);			\
+		} else {						\
+			if (nc)						\
+				break; /* end of consecutive matches */ \
+		}							\
+	}								\
+	__evalout _dst->num_##_vec = nc;				\
+})
+
 static int ddebug_attach_module_classes(struct ddebug_table *dt,
 					const struct _ddebug_info *di,
 					u64 *reserved_ids)
 {
 	struct ddebug_class_map *cm;
-	int i, nc = 0;
-
-	for (i = 0, cm = di->classes; i < di->num_classes; i++, cm++) {
-		if (!strcmp(cm->mod_name, dt->mod_name)) {
-			vpr_cm_info(cm, "classes[%d]:", i);
-			if (!nc++)
-				dt->classes = cm;
-		}
-	}
-	if (!nc)
-		return 0;
-
-	vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
-	dt->num_classes = nc;
+	int i;
 
-	for (i = 0, cm = dt->classes; i < dt->num_classes; i++, cm++) {
+	for_subvec(i, cm, di, classes) {
 		if (ddebug_class_range_overlap(cm, reserved_ids))
 			return -EINVAL;
 		ddebug_apply_params(cm, cm->mod_name);
 	}
+	vpr_info("module:%s attached %d classmaps\n", dt->mod_name, dt->num_classes);
 	return 0;
 }
 
-/*
- * propagates class-params thru their classmaps to class-users.  this
- * means a query against the dt/module, which means it must be on the
- * list to be seen by ddebug_change.
- */
 static int ddebug_attach_user_module_classes(struct ddebug_table *dt,
 					     const struct _ddebug_info *di,
 					     u64 *reserved_ids)
 {
 	struct ddebug_class_user *cli;
-	int i, nc = 0;
-
-	/*
-	 * For builtins: scan the array, find start/length of this
-	 * module's refs, save to dt.  For loadables, this is the
-	 * whole array.
-	 */
-	for (i = 0, cli = di->class_users; i < di->num_class_users; i++, cli++) {
-		if (WARN_ON_ONCE(!cli || !cli->map || !cli->mod_name))
-			continue;
-		if (!strcmp(cli->mod_name, dt->mod_name)) {
-			vpr_cm_info(cli->map, "class_ref[%d] %s -> %s", i,
-				    cli->mod_name, cli->map->mod_name);
-			if (!nc++)
-				dt->class_users = cli;
-		}
-	}
-	if (!nc)
-		return 0;
-
-	dt->num_class_users = nc;
+	int i;
 
-	/* now iterate dt */
-	for (i = 0, cli = dt->class_users; i < dt->num_class_users; i++, cli++) {
+	for_subvec(i, cli, dt, class_users) {
 		if (ddebug_class_range_overlap(cli->map, reserved_ids))
 			return -EINVAL;
 		ddebug_apply_params(cli->map, cli->mod_name);
 	}
-	vpr_dt_info(dt, "attach-client-module: ");
+	vpr_info("module:%s attached %d classmap uses\n", dt->mod_name, dt->num_class_users);
 	return 0;
 }
 
@@ -1338,8 +1333,10 @@ static int ddebug_attach_user_module_classes(struct ddebug_table *dt,
 static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
 {
 	struct ddebug_table *dt;
+	struct ddebug_class_map *cm;
+	struct ddebug_class_user *cli;
 	u64 reserved_ids = 0;
-	int rc;
+	int rc, i;
 
 	if (!di->num_descs)
 		return 0;
@@ -1362,8 +1359,16 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
 	dt->num_ddebugs = di->num_descs;
 
 	INIT_LIST_HEAD(&dt->link);
+	/*
+	 * for builtin modules, ddebug_init() insures that the di
+	 * cursor marks just the module's descriptors, but it doesn't
+	 * do so for the builtin class _maps & _users.  find the
+	 * start,len of the vectors by mod_name, save to dt.
+	 */
+	dd_mark_vector_subrange(i, dt, cm, di, classes);
+	dd_mark_vector_subrange(i, dt, cli, di, class_users);
 
-	if (di->num_classes) {
+	if (dt->num_classes) {
 		rc = ddebug_attach_module_classes(dt, di, &reserved_ids);
 		if (rc) {
 			kfree(dt);
@@ -1375,7 +1380,7 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname)
 	list_add_tail(&dt->link, &ddebug_tables);
 	mutex_unlock(&ddebug_lock);
 
-	if (di->num_class_users) {
+	if (dt->num_class_users) {
 		rc = ddebug_attach_user_module_classes(dt, di, &reserved_ids);
 		if (rc)
 			return rc;
-- 
2.46.2



More information about the Intel-gfx-trybot mailing list