[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