dynamic_debug: port to use linker tables
This removes the custom vmlinux.lds.h hacks and uses
the generalized solution for .data (SECTION_DATA)
entries.
This is much more potential for further fine tuning here
though in the future. For instance, linker tables enable
an extra postfix for order level annotations, this could
easily be used as the KBUILD_MODNAME and with a bit of
linker table changes we may be able to get a direct O(1)
count of the entries for that KBUILD_MODNAME: it would
just be a count on the number of entries for the given
order level. This should help make dynamic_debug_init()
cleaner and also reduce the amount of time it takes at
boot time. Instead of iterating over each print until we
have all for a KBUILD_MODNAME, we'd instead directly
operate on each KBUILD_MODNAME directly.
Tested dynamic debug with dyndbg query ana debugfs control
and it works as expected.
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6dec4ac1..1d685b3 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -209,11 +209,6 @@
*(.data.unlikely) \
STRUCT_ALIGN(); \
*(__tracepoints) \
- /* implement dynamic printk debug */ \
- . = ALIGN(8); \
- VMLINUX_SYMBOL(__start___verbose) = .; \
- *(__verbose) \
- VMLINUX_SYMBOL(__stop___verbose) = .; \
LIKELY_PROFILE() \
BRANCH_PROFILE() \
TRACE_PRINTKS() \
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 546d680..a52618a 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -4,6 +4,7 @@
#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
#include <linux/jump_label.h>
#endif
+#include <linux/tables.h>
/*
* An instance of this structure is created in a special
@@ -50,6 +51,7 @@
const char *modname);
#if defined(CONFIG_DYNAMIC_DEBUG)
+DECLARE_LINKTABLE(struct _ddebug, __verbose);
extern int ddebug_remove_module(const char *mod_name);
extern __printf(2, 3)
void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
@@ -71,8 +73,7 @@
const char *fmt, ...);
#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \
- static struct _ddebug __aligned(8) \
- __attribute__((section("__verbose"))) name = { \
+ static LINKTABLE(__verbose, SECTION_ORDER_ANY) name = { \
.modname = KBUILD_MODNAME, \
.function = __func__, \
.filename = __FILE__, \
diff --git a/kernel/module.c b/kernel/module.c
index 68ed7c7..3541910 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3031,7 +3031,7 @@
if (section_addr(info, "__obsparm"))
pr_warn("%s: Ignoring obsolete parameters\n", mod->name);
- info->debug = section_objs(info, "__verbose",
+ info->debug = section_objs(info, SECTION_TBL(SECTION_DATA, __verbose,),
sizeof(*info->debug), &info->num_debug);
return 0;
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index da796e2..f0060c8 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -37,8 +37,7 @@
#include <linux/device.h>
#include <linux/netdevice.h>
-extern struct _ddebug __start___verbose[];
-extern struct _ddebug __stop___verbose[];
+DEFINE_LINKTABLE(struct _ddebug, __verbose);
struct ddebug_table {
struct list_head link;
@@ -978,14 +977,14 @@
int n = 0, entries = 0, modct = 0;
int verbose_bytes = 0;
- if (__start___verbose == __stop___verbose) {
- pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
+ if (LINUX_SECTION_EMPTY(__verbose)) {
+ pr_warn("dynamic debug linker table empty on CONFIG_DYNAMIC_DEBUG build\n");
return 1;
}
- iter = __start___verbose;
+ iter = LINUX_SECTION_START(__verbose);
modname = iter->modname;
iter_start = iter;
- for (; iter < __stop___verbose; iter++) {
+ LINKTABLE_FOR_EACH(iter, __verbose) {
entries++;
verbose_bytes += strlen(iter->modname) + strlen(iter->function)
+ strlen(iter->filename) + strlen(iter->format);
@@ -1008,7 +1007,7 @@
ddebug_init_success = 1;
vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
modct, entries, (int)(modct * sizeof(struct ddebug_table)),
- verbose_bytes + (int)(__stop___verbose - __start___verbose));
+ verbose_bytes + (int)(LINUX_SECTION_SIZE(__verbose)));
/* apply ddebug_query boot param, dont unload tables on err */
if (ddebug_setup_string[0] != '\0') {