diff mbox series

[RFC,02/10] dyndbg: split __dyndbg_sites section out from __dyndbg

Message ID 20231012194711.3288031-3-jim.cromie@gmail.com (mailing list archive)
State New
Headers show
Series how to reclaim unneeded vmlinux memory ? | expand

Commit Message

Jim Cromie Oct. 12, 2023, 7:47 p.m. UTC
split struct _ddebug_site out from struct _ddebug (adding a site ptr),
and add new __dyndbg_sites section placement to vmlinux.lds.h

This is an implementation detail to isolate the redundant columns into
a separate section, so it specifically excludes lineno.

This allows (later) to copy and compress the info into a better (more
compact) representation thats still fast enough.  Then we can just
reclaim the whole __dyndbg_sites section.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
---
 include/asm-generic/vmlinux.lds.h |  1 +
 include/linux/dynamic_debug.h     | 40 ++++++++++++++++++-------------
 kernel/module/main.c              |  3 +++
 lib/dynamic_debug.c               |  6 +++++
 4 files changed, 33 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5451f926a753..1d128259e373 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -368,6 +368,7 @@ 
 	BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)		\
 	BOUNDED_SECTION_BY(__dyndbg_class_users, ___dyndbg_class_users)	\
 	BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)				\
+	BOUNDED_SECTION_BY(__dyndbg_sites, ___dyndbg_sites)		\
 	LIKELY_PROFILE()		       				\
 	BRANCH_PROFILE()						\
 	TRACE_PRINTKS()							\
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index aacfafc466c0..5206a2cfdb37 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -9,21 +9,25 @@ 
 #include <linux/build_bug.h>
 
 /*
- * An instance of this structure is created in a special
- * ELF section at every dynamic debug callsite.  At runtime,
- * the special section is treated as an array of these.
+ * A pair of these structs are created into 2 special ELF sections for
+ * each pr_debug callsite.  At runtime, the special sections are
+ * treated as arrays.
  */
-
-struct _ddebug {
+struct _ddebug;
+struct _ddebug_site {
 	/*
-	 * These fields are used to drive the user interface
-	 * for selecting and displaying debug callsites.
+	 * These fields are used to:
+	 * - display callsites in the control file
+	 * - query/select callsites by the code's organization
+	 * - prefix/decorate pr_debug messages per user choices
 	 */
-	struct /* _ddebug_site */ {
-		const char *_modname;
-		const char *_function;
-		const char *_filename;
-	};
+	const char *_modname;
+	const char *_function;
+	const char *_filename;
+};
+
+struct _ddebug {
+	struct _ddebug_site *site;
 	const char *format;
 	unsigned int lineno:18;
 #define CLS_BITS 6
@@ -64,10 +68,6 @@  struct _ddebug {
 #endif
 } __attribute__((aligned(8)));
 
-#define desc_modname(d)		(d)->modname
-#define desc_filename(d)	(d)->filename
-#define desc_function(d)	(d)->function
-
 enum ddebug_class_map_type {
 	DD_CLASS_TYPE_DISJOINT_BITS,
 	/**
@@ -139,9 +139,11 @@  struct ddebug_class_user {
 /* encapsulate linker provided built-in (or module) dyndbg data */
 struct _ddebug_info {
 	struct _ddebug *descs;
+	struct _ddebug_site *sites;
 	struct ddebug_class_map *classes;
 	struct ddebug_class_user *class_users;
 	unsigned int num_descs;
+	unsigned int num_sites;
 	unsigned int num_classes;
 	unsigned int num_class_users;
 };
@@ -226,9 +228,13 @@  void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 	._filename = __FILE__
 
 #define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt)	\
+	static struct _ddebug_site  __aligned(8)		\
+	__section("__dyndbg_sites") name ##_site = {		\
+		DYNAMIC_DEBUG_SITE_INIT(),			\
+	};							\
 	static struct _ddebug  __aligned(8)			\
 	__section("__dyndbg") name = {				\
-		DYNAMIC_DEBUG_SITE_INIT(),			\
+		.site = &(name ##_site),			\
 		.format = (fmt),				\
 		.lineno = __LINE__,				\
 		.flags = _DPRINTK_FLAGS_DEFAULT,		\
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 6b0b0d82b5ab..43458184744d 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2211,6 +2211,9 @@  static int find_module_sections(struct module *mod, struct load_info *info)
 	mod->dyndbg_info.descs = section_objs(info, "__dyndbg",
 					      sizeof(*mod->dyndbg_info.descs),
 					      &mod->dyndbg_info.num_descs);
+	mod->dyndbg_info.sites = section_objs(info, "__dyndbg_sites",
+					      sizeof(*mod->dyndbg_info.sites),
+					      &mod->dyndbg_info.num_sites);
 	mod->dyndbg_info.classes = section_objs(info, "__dyndbg_classes",
 						sizeof(*mod->dyndbg_info.classes),
 						&mod->dyndbg_info.num_classes);
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index c0e595483cb9..0ad9f1bc00f0 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -41,6 +41,8 @@ 
 
 extern struct _ddebug __start___dyndbg[];
 extern struct _ddebug __stop___dyndbg[];
+extern struct _ddebug_site __start___dyndbg_sites[];
+extern struct _ddebug_site __stop___dyndbg_sites[];
 extern struct ddebug_class_map __start___dyndbg_classes[];
 extern struct ddebug_class_map __stop___dyndbg_classes[];
 extern struct ddebug_class_user __start___dyndbg_class_users[];
@@ -191,6 +193,10 @@  static struct ddebug_class_map *ddebug_find_valid_class(struct ddebug_table cons
 	return NULL;
 }
 
+#define desc_modname(d)		(d)->site->_modname
+#define desc_filename(d)	(d)->site->_filename
+#define desc_function(d)	(d)->site->_function
+
 /*
  * Search the tables for _ddebug's which match the given `query' and
  * apply the `flags' and `mask' to them.  Returns number of matching