[PATCH v6 43/57] dyndbg: add _index,_map to struct _ddebug

Jim Cromie jim.cromie at gmail.com
Sun Sep 4 21:41:20 UTC 2022


We now have 2 vectors of data: (__dyndbg, __dyndbg_sites), known to be
equal-length, with _ddebug.site connecting them, like rungs on a
ladder.  In order to drop _ddebug.site, we need to replace the
absolute ptr with a cheap relative-address computation:

   struct _ddebug_site *site = _ddebug_map_site(desc);

1st step: (done here)

add ._index, ._map fields, and initialize them in __debug_add_module()
to N (and = each other), where N is each element's position in the
builtins (or loaded-module).  Then _ddebug_map_site(desc) can compute
&descs[0], and then use container_of() to go up 1 struct.

RFC: Next steps: (outlined here, not done):

1. UPLINK:

Define 2 new header structs, with _uplink fields, pointing at _ddebug_info:

struct _ddebug_site_hdr {
       union {
       	     struct _ddebug_info _uplink*;
	     struct _ddebug_site __;  // sizeof this
	};
};

struct _ddebug_hdr {
       union {
       	     struct _ddebug_info _uplink*;
	     struct _ddebug __;  // sizeof this
	};
};

the union forces the allocation to be the bigger of the 2, with the
expectation that the pointer will always fit.

2. Reserve a record in front of the __dyndbg* sections.

can be done in {module,vmlinux}.lds.h, something like:

SECTIONS {
__dyndbg_sites : ALIGN(8) { *(.gnu.linkonce.dyndbg_site) *(__dyndbg_sites) }
__dyndbg       : ALIGN(8) { *(.gnu.linkonce.dyndbg)      *(__dyndbg) }
}
KEEP( *(.gnu.linkonce.__dyndbg_site) *(__dyndbg_sites))

3. specialize DYNAMIC_DEBUG_METADATA_CLS as DYNAMIC_DEBUG_TABLE.

This special macro version creates header records, and puts them into
.gnu.linkonce section.  Unusually (uniquely?), it is tacitly invoked
by dynamic_debug.h on behalf of all printk.h includers.  This can
result in multiple "declarations" in the same scope, so macro uses
__weak and/or __unused to suppress linkage & errors.

This created mumble-RELATIVE linkage errors in a few parts of the
kernel, I worked around this by just suppressing the declaration if
cflags includes -DDYNDBG_NO_TABLE.

The up-link is init'd in 2 cases:

The file static struct _ddebug_info builtins is initialized by
dynamic_debug_init(), with the 3 ELF sections addresses+lengths
composing the builtin dyndbg-state.  It will be able to also
initialize the header.UPLINK fields, as long as the storage space is
available.  Then rel_map() can rely upon it to provide the &site ref
for a callsite's desc*, if it is enabled.

Then at runtime (assuming initialization is correct):

 - use _index to get &descs[0]
 - container-of gets .UPLINK to &dyndbg_info
 - info->sites[_index]	- replaces .sites
 - info->sites[_map]	- allows de-duplicated vector position. M<N

But thats all talk; this patch just adds and initializes the index and
map fields.

._index:14 allows ~16k entries, more than enough for ~3k built-in
callsites, or ~4k in amdgpu (with dyn-drm-trc commitset).  It is
initialized in __ddebug_add_module(), a new refactorization.

ddebug_add_module() is called from kernel/module.c, that interface is
preserved.  It just passes 0 to inner fn when loading modules.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/linux/dynamic_debug.h | 3 +++
 lib/dynamic_debug.c           | 8 ++++++++
 2 files changed, 11 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index c05148dab367..268e903b7c4e 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -31,6 +31,8 @@ struct _ddebug {
 	/* format is always needed, lineno shares word with flags */
 	const char *format;
 	const unsigned lineno:16;
+	unsigned _index:14;
+	unsigned _map:14;
 #define CLS_BITS 6
 	unsigned int class_id:CLS_BITS;
 #define _DPRINTK_CLASS_DFLT		((1 << CLS_BITS) - 1)
@@ -60,6 +62,7 @@ struct _ddebug {
 #define _DPRINTK_FLAGS_DEFAULT 0
 #endif
 	unsigned int flags:8;
+
 #ifdef CONFIG_JUMP_LABEL
 	union {
 		struct static_key_true dd_key_true;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index f1f354efed5a..506a7e2e59d6 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -1344,6 +1344,7 @@ static int __ddebug_add_module(struct _ddebug_info *di, unsigned int base,
 			       const char *modname)
 {
 	struct ddebug_table *dt;
+	int i;
 
 	v3pr_info("add-module: %s.%d sites\n", modname, di->num_descs);
 	if (!di->num_descs) {
@@ -1364,6 +1365,7 @@ static int __ddebug_add_module(struct _ddebug_info *di, unsigned int base,
 	 */
 	dt->mod_name = modname;
 	dt->ddebugs = di->descs;
+	dt->sites = di->sites;
 	dt->num_ddebugs = di->num_descs;
 
 	INIT_LIST_HEAD(&dt->link);
@@ -1372,6 +1374,12 @@ static int __ddebug_add_module(struct _ddebug_info *di, unsigned int base,
 	if (di->classes && di->num_classes)
 		ddebug_attach_module_classes(dt, di->classes, di->num_classes);
 
+	for (i = 0; i < di->num_descs; i++) {
+		di->descs[i]._index = base + i;
+		v3pr_info(" %d %d %s.%s.%d\n", i, base, modname,
+			  di->descs[i].site->_function, di->descs[i].lineno);
+	}
+
 	mutex_lock(&ddebug_lock);
 	list_add_tail(&dt->link, &ddebug_tables);
 	mutex_unlock(&ddebug_lock);
-- 
2.37.2



More information about the amd-gfx mailing list