recompose struct _ddebug_info, inserting proper sub-structs.

The struct currently has 2 pairs of fields: descs, num_descs and
classes, num_classes.  Several for-loops operate on these field pairs,
soon many more will be added.

Looping over these blocks by respective field-pairs is repetitive and
fiddly, differing only by the field-names.  Before adding a 3rd
section and compounding the fiddly details problem, make proper
substructs of each section, with the same named fields.

So this patch does:

Adds 3 "vector<T>" structs, each with { <T> *start, int len; }
components, for _ddebug_descriptors, _ddebug_class_maps, and
_ddebug_class_users respectively.

Invariant: These vectors ref a contiguous subrange of __section memory
in builtin/DATA or in loadable modules via mod->dyndbg_info; with
guaranteed life-time for us.

Bundles these 3 vectors (subrange-refs) struct (reformed) _ddebug_info,
where they're __packed to close the paholes introduced otherwise.

The common fields allow improving the for_subvec() macro by dropping
the ugly num_##<T> paste-up.

Also recompose struct ddebug_table to contain a _ddebug_info.  This
reinforces its use as a cursor into relevant data for a builtin
module, and access to the full _ddebug state for modules.

NOTES:

Fixup names: section names improved, struct names normalized to
_ddebug_*

struct module contains a _ddebug_info field and module/main.c sets it
up, so that gets adjusted.

The __packed attribute on _ddebug_info and the 3 contained structs
closes the holes otherwise created by the structification (which was
my excuse for not doing it originally).

Signed-off-by: Jim Cromie <jim.cro...@gmail.com>
---
-v2 rework towards front of series
---
 include/asm-generic/vmlinux.lds.h |  4 +-
 include/linux/dynamic_debug.h     | 28 +++++++---
 kernel/module/main.c              | 12 ++--
 lib/dynamic_debug.c               | 91 ++++++++++++++++---------------
 4 files changed, 74 insertions(+), 61 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index c9c66089ea2f..f834ad1fb8c4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -366,8 +366,8 @@ defined(CONFIG_AUTOFDO_CLANG) || 
defined(CONFIG_PROPELLER_CLANG)
        *(__tracepoints)                                                \
        /* implement dynamic printk debug */                            \
        . = ALIGN(8);                                                   \
-       BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)         \
-       BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)                         \
+       BOUNDED_SECTION_BY(__dyndbg_class_maps, ___dyndbg_class_maps)   \
+       BOUNDED_SECTION_BY(__dyndbg_descriptors, ___dyndbg_descs)       \
        CODETAG_SECTIONS()                                              \
        LIKELY_PROFILE()                                                \
        BRANCH_PROFILE()                                                \
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e458d4b838ac..c388ab05a6e1 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -110,13 +110,23 @@ struct ddebug_class_map {
                .class_names = _var##_classnames,                       \
        }
 
-/* encapsulate linker provided built-in (or module) dyndbg data */
+/*
+ * @_ddebug_info: gathers module/builtin dyndbg_* __sections together.
+ * For builtins, it is used as a cursor, with the inner structs
+ * marking sub-vectors of the builtin __sections in DATA.
+ */
+struct _ddebug_descs {
+       struct _ddebug *start;
+       int len;
+} __packed;
+struct _ddebug_class_maps {
+       struct ddebug_class_map *start;
+       int len;
+} __packed;
 struct _ddebug_info {
-       struct _ddebug *descs;
-       struct ddebug_class_map *classes;
-       unsigned int num_descs;
-       unsigned int num_classes;
-};
+       struct _ddebug_descs descs;
+       struct _ddebug_class_maps maps;
+} __packed;
 
 struct ddebug_class_param {
        union {
@@ -159,7 +169,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt)      \
        static struct _ddebug  __aligned(8)                     \
-       __section("__dyndbg") name = {                          \
+       __section("__dyndbg_descriptors") name = {              \
                .modname = KBUILD_MODNAME,                      \
                .function = __func__,                           \
                .filename = __FILE__,                           \
@@ -242,7 +252,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
  * macro.
  */
 #define _dynamic_func_call_cls(cls, fmt, func, ...)                    \
-       __dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, 
##__VA_ARGS__)
+       __dynamic_func_call_cls(__UNIQUE_ID(_ddebug), cls, fmt, func, 
##__VA_ARGS__)
 #define _dynamic_func_call(fmt, func, ...)                             \
        _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
 
@@ -252,7 +262,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
  * with precisely the macro's varargs.
  */
 #define _dynamic_func_call_cls_no_desc(cls, fmt, func, ...)            \
-       __dynamic_func_call_cls_no_desc(__UNIQUE_ID(ddebug), cls, fmt,  \
+       __dynamic_func_call_cls_no_desc(__UNIQUE_ID(_ddebug), cls, fmt, \
                                        func, ##__VA_ARGS__)
 #define _dynamic_func_call_no_desc(fmt, func, ...)                     \
        _dynamic_func_call_cls_no_desc(_DPRINTK_CLASS_DFLT, fmt,        \
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 1fb9ad289a6f..b60f728e36ac 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2621,12 +2621,12 @@ static int find_module_sections(struct module *mod, 
struct load_info *info)
                pr_warn("%s: Ignoring obsolete parameters\n", mod->name);
 
 #ifdef CONFIG_DYNAMIC_DEBUG_CORE
-       mod->dyndbg_info.descs = section_objs(info, "__dyndbg",
-                                             sizeof(*mod->dyndbg_info.descs),
-                                             &mod->dyndbg_info.num_descs);
-       mod->dyndbg_info.classes = section_objs(info, "__dyndbg_classes",
-                                               
sizeof(*mod->dyndbg_info.classes),
-                                               &mod->dyndbg_info.num_classes);
+       mod->dyndbg_info.descs.start = section_objs(info, 
"__dyndbg_descriptors",
+                                                   
sizeof(*mod->dyndbg_info.descs.start),
+                                                   
&mod->dyndbg_info.descs.len);
+       mod->dyndbg_info.maps.start = section_objs(info, "__dyndbg_class_maps",
+                                                  
sizeof(*mod->dyndbg_info.maps.start),
+                                                  &mod->dyndbg_info.maps.len);
 #endif
 
        return 0;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 94f6c8fd787b..663c125006d0 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -39,17 +39,15 @@
 
 #include <rdma/ib_verbs.h>
 
-extern struct _ddebug __start___dyndbg[];
-extern struct _ddebug __stop___dyndbg[];
-extern struct ddebug_class_map __start___dyndbg_classes[];
-extern struct ddebug_class_map __stop___dyndbg_classes[];
+extern struct _ddebug __start___dyndbg_descs[];
+extern struct _ddebug __stop___dyndbg_descs[];
+extern struct ddebug_class_map __start___dyndbg_class_maps[];
+extern struct ddebug_class_map __stop___dyndbg_class_maps[];
 
 struct ddebug_table {
        struct list_head link;
        const char *mod_name;
-       struct _ddebug *ddebugs;
-       struct ddebug_class_map *classes;
-       unsigned int num_ddebugs, num_classes;
+       struct _ddebug_info info;
 };
 
 struct ddebug_query {
@@ -128,7 +126,6 @@ do {                                                        
        \
 #define v3pr_info(fmt, ...)    vnpr_info(3, fmt, ##__VA_ARGS__)
 #define v4pr_info(fmt, ...)    vnpr_info(4, fmt, ##__VA_ARGS__)
 
-
 /*
  * 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
@@ -139,8 +136,8 @@ do {                                                        
        \
  * @_vec: name of a sub-struct member in _box, with array-ref and length
  */
 #define for_subvec(_i, _sp, _box, _vec)                                       \
-       for ((_i) = 0, (_sp) = (_box)->_vec;                           \
-            (_i) < (_box)->num_##_vec;                                \
+       for ((_i) = 0, (_sp) = (_box)->_vec.start;                     \
+            (_i) < (_box)->_vec.len;                                  \
             (_i)++, (_sp)++)
 
 static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
@@ -163,6 +160,13 @@ static void vpr_info_dq(const struct ddebug_query *query, 
const char *msg)
                  query->first_lineno, query->last_lineno, query->class_string);
 }
 
+#define vpr_dt_info(dt_p, msg_p, ...) ({                               \
+       struct ddebug_table const *_dt = dt_p;                          \
+       v2pr_info(msg_p " module:%s nd:%d nc:%d nu:%d\n", ##__VA_ARGS__, \
+                 _dt->mod_name, _dt->info.descs.len, _dt->info.maps.len, \
+                 _dt->info.users.len);                                 \
+       })
+
 #define __outvar /* filled by callee */
 static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table 
const *dt,
                                                        const char 
*class_string,
@@ -171,7 +175,7 @@ static struct ddebug_class_map 
*ddebug_find_valid_class(struct ddebug_table cons
        struct ddebug_class_map *map;
        int i, idx;
 
-       for_subvec(i, map, dt, classes) {
+       for_subvec(i, map, &dt->info, maps) {
                idx = match_string(map->class_names, map->length, class_string);
                if (idx >= 0) {
                        *class_id = idx + map->base;
@@ -217,8 +221,8 @@ static int ddebug_change(const struct ddebug_query *query,
                        valid_class = _DPRINTK_CLASS_DFLT;
                }
 
-               for (i = 0; i < dt->num_ddebugs; i++) {
-                       struct _ddebug *dp = &dt->ddebugs[i];
+               for (i = 0; i < dt->info.descs.len; i++) {
+                       struct _ddebug *dp = &dt->info.descs.start[i];
 
                        /* match site against query-class */
                        if (dp->class_id != valid_class)
@@ -1065,8 +1069,8 @@ static struct _ddebug *ddebug_iter_first(struct 
ddebug_iter *iter)
        }
        iter->table = list_entry(ddebug_tables.next,
                                 struct ddebug_table, link);
-       iter->idx = iter->table->num_ddebugs;
-       return &iter->table->ddebugs[--iter->idx];
+       iter->idx = iter->table->info.descs.len;
+       return &iter->table->info.descs.start[--iter->idx];
 }
 
 /*
@@ -1087,10 +1091,10 @@ static struct _ddebug *ddebug_iter_next(struct 
ddebug_iter *iter)
                }
                iter->table = list_entry(iter->table->link.next,
                                         struct ddebug_table, link);
-               iter->idx = iter->table->num_ddebugs;
+               iter->idx = iter->table->info.descs.len;
                --iter->idx;
        }
-       return &iter->table->ddebugs[iter->idx];
+       return &iter->table->info.descs.start[iter->idx];
 }
 
 /*
@@ -1137,12 +1141,12 @@ static void *ddebug_proc_next(struct seq_file *m, void 
*p, loff_t *pos)
 #define class_in_range(class_id, map)                                  \
        (class_id >= map->base && class_id < map->base + map->length)
 
-static const char *ddebug_class_name(struct ddebug_iter *iter, struct _ddebug 
*dp)
+static const char *ddebug_class_name(struct ddebug_table *dt, struct _ddebug 
*dp)
 {
-       struct ddebug_class_map *map = iter->table->classes;
-       int i, nc = iter->table->num_classes;
+       struct ddebug_class_map *map;
+       int i;
 
-       for (i = 0; i < nc; i++, map++)
+       for_subvec(i, map, &dt->info, maps)
                if (class_in_range(dp->class_id, map))
                        return map->class_names[dp->class_id - map->base];
 
@@ -1176,7 +1180,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
        seq_putc(m, '"');
 
        if (dp->class_id != _DPRINTK_CLASS_DFLT) {
-               class = ddebug_class_name(iter, dp);
+               class = ddebug_class_name(iter->table, dp);
                if (class)
                        seq_printf(m, " class:%s", class);
                else
@@ -1236,18 +1240,18 @@ static void ddebug_attach_module_classes(struct 
ddebug_table *dt, struct _ddebug
         * the builtin/modular classmap vector/section.  Save the start
         * and length of the subrange at its edges.
         */
-       for_subvec(i, cm, di, classes) {
+       for_subvec(i, cm, di, maps) {
                if (!strcmp(cm->mod_name, dt->mod_name)) {
                        if (!nc) {
                                v2pr_info("start subrange, class[%d]: module:%s 
base:%d len:%d ty:%d\n",
                                          i, cm->mod_name, cm->base, 
cm->length, cm->map_type);
-                               dt->classes = cm;
+                               dt->info.maps.start = cm;
                        }
                        nc++;
                }
        }
        if (nc) {
-               dt->num_classes = nc;
+               dt->info.maps.len = nc;
                vpr_info("module:%s attached %d classes\n", dt->mod_name, nc);
        }
 }
@@ -1260,10 +1264,10 @@ static int ddebug_add_module(struct _ddebug_info *di, 
const char *modname)
 {
        struct ddebug_table *dt;
 
-       if (!di->num_descs)
+       if (!di->descs.len)
                return 0;
 
-       v3pr_info("add-module: %s %d sites\n", modname, di->num_descs);
+       v3pr_info("add-module: %s %d sites\n", modname, di->descs.len);
 
        dt = kzalloc(sizeof(*dt), GFP_KERNEL);
        if (dt == NULL) {
@@ -1277,19 +1281,18 @@ static int ddebug_add_module(struct _ddebug_info *di, 
const char *modname)
         * this struct ddebug_table.
         */
        dt->mod_name = modname;
-       dt->ddebugs = di->descs;
-       dt->num_ddebugs = di->num_descs;
+       dt->info = *di;
 
        INIT_LIST_HEAD(&dt->link);
 
-       if (di->classes && di->num_classes)
+       if (di->maps.len)
                ddebug_attach_module_classes(dt, di);
 
        mutex_lock(&ddebug_lock);
        list_add_tail(&dt->link, &ddebug_tables);
        mutex_unlock(&ddebug_lock);
 
-       vpr_info("%3u debug prints in module %s\n", di->num_descs, modname);
+       vpr_info("%3u debug prints in module %s\n", di->descs.len, modname);
        return 0;
 }
 
@@ -1436,10 +1439,10 @@ static int __init dynamic_debug_init(void)
        char *cmdline;
 
        struct _ddebug_info di = {
-               .descs = __start___dyndbg,
-               .classes = __start___dyndbg_classes,
-               .num_descs = __stop___dyndbg - __start___dyndbg,
-               .num_classes = __stop___dyndbg_classes - 
__start___dyndbg_classes,
+               .descs.start = __start___dyndbg_descs,
+               .maps.start  = __start___dyndbg_class_maps,
+               .descs.len = __stop___dyndbg_descs - __start___dyndbg_descs,
+               .maps.len  = __stop___dyndbg_class_maps - 
__start___dyndbg_class_maps,
        };
 
 #ifdef CONFIG_MODULES
@@ -1450,7 +1453,7 @@ static int __init dynamic_debug_init(void)
        }
 #endif /* CONFIG_MODULES */
 
-       if (&__start___dyndbg == &__stop___dyndbg) {
+       if (&__start___dyndbg_descs == &__stop___dyndbg_descs) {
                if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
                        pr_warn("_ddebug table is empty in a 
CONFIG_DYNAMIC_DEBUG build\n");
                        return 1;
@@ -1460,16 +1463,16 @@ static int __init dynamic_debug_init(void)
                return 0;
        }
 
-       iter = iter_mod_start = __start___dyndbg;
+       iter = iter_mod_start = __start___dyndbg_descs;
        modname = iter->modname;
        i = mod_sites = mod_ct = 0;
 
-       for (; iter < __stop___dyndbg; iter++, i++, mod_sites++) {
+       for (; iter < __stop___dyndbg_descs; iter++, i++, mod_sites++) {
 
                if (strcmp(modname, iter->modname)) {
                        mod_ct++;
-                       di.num_descs = mod_sites;
-                       di.descs = iter_mod_start;
+                       di.descs.len = mod_sites;
+                       di.descs.start = iter_mod_start;
                        ret = ddebug_add_module(&di, modname);
                        if (ret)
                                goto out_err;
@@ -1479,8 +1482,8 @@ static int __init dynamic_debug_init(void)
                        iter_mod_start = iter;
                }
        }
-       di.num_descs = mod_sites;
-       di.descs = iter_mod_start;
+       di.descs.len = mod_sites;
+       di.descs.start = iter_mod_start;
        ret = ddebug_add_module(&di, modname);
        if (ret)
                goto out_err;
@@ -1490,8 +1493,8 @@ static int __init dynamic_debug_init(void)
                 i, mod_ct, (int)((mod_ct * sizeof(struct ddebug_table)) >> 10),
                 (int)((i * sizeof(struct _ddebug)) >> 10));
 
-       if (di.num_classes)
-               v2pr_info("  %d builtin ddebug class-maps\n", di.num_classes);
+       if (di.maps.len)
+               v2pr_info("  %d builtin ddebug class-maps\n", di.maps.len);
 
        /* now that ddebug tables are loaded, process all boot args
         * again to find and activate queries given in dyndbg params.
-- 
2.49.0

Reply via email to