mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: jim.cromie@gmail.com
To: jbaron@redhat.com, rusty@rustcorp.com.au
Cc: linux-kernel@vger.kernel.org, Jim Cromie <jim.cromie@gmail.com>,
	Thomas Renninger <trenn@suse.de>
Subject: [PATCH 07/11] dynamic_debug: make dynamic-debug work during module initialization
Date: Wed, 14 Mar 2012 17:02:02 -0600	[thread overview]
Message-ID: <1331766126-11674-8-git-send-email-jim.cromie@gmail.com> (raw)
In-Reply-To: <1331766126-11674-1-git-send-email-jim.cromie@gmail.com>

From: Jim Cromie <jim.cromie@gmail.com>

This introduces a fake module param $module.dyndbg.  Its based upon
Thomas Renninger's $module.ddebug boot-time debugging patch from
https://lkml.org/lkml/2010/9/15/397

The 'fake' module parameter is provided for all modules, whether or
not they need it.  It is not explicitly added to each module, but is
implemented in 2 common callbacks invoked from parse_args.

Now dynamic_debug_init() directly calls parse_args(), which calls
ddebug_dyndbg_boot_params_cb().  This callback handles both bare and
module-prefixed dyndbg params immediately after the ddebug tables are
loaded, and ignores all other parameters. For example, the following
will enable pr_debug()s in 4 builtin modules, in the order given:

  dyndbg="module params +p; module aio +p" module.dyndbg=+p pci.dyndbg

A previous patch changed "ddebug_query" to "dyndbg"; since this new
callback handles it, we can drop the special case "ddebug_query" code.

For loadable modules, parse_args() in load_module() calls
ddebug_dyndbg_module_params_cb().  This handles bare dyndbg params as
passed from modprobe, and errors on other unknown params.

These callbacks need to know the module name, as provided by the
"doing" arg added in the previous patch.

For non CONFIG_DYNAMIC_DEBUG builds, the stub function accepts
and ignores $module.dyndbg params, other unknowns get -ENOENT.

If no param value is given (as in pci.dyndbg example above), "+p" is
assumed, which enables all pr_debug callsites in the module.

The dyndbg fake parameter is not shown in /sys/module/*/parameters,
thus it does not use any resources.  Changes to it are made via the
control file.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
CC: Thomas Renninger <trenn@suse.de>
CC: Rusty Russell <rusty@rustcorp.com.au>
---
 include/linux/dynamic_debug.h |   17 +++++++++++++
 kernel/module.c               |    2 +-
 lib/dynamic_debug.c           |   53 +++++++++++++++++++++++++++++++---------
 3 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index bf1b0fc..4697e4b 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -44,6 +44,9 @@ extern int ddebug_remove_module(const char *mod_name);
 extern __printf(2, 3)
 int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
 
+extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
+					const char *modname);
+
 struct device;
 
 extern __printf(3, 4)
@@ -94,11 +97,25 @@ do {								\
 
 #else
 
+#include <linux/string.h>
+#include <linux/errno.h>
+
 static inline int ddebug_remove_module(const char *mod)
 {
 	return 0;
 }
 
+static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
+						const char *modname)
+{
+	if (strstr(param, "dyndbg")) {
+		pr_warn("dyndbg supported only in "
+			"CONFIG_DYNAMIC_DEBUG builds\n");
+		return 0; /* allow and ignore */
+	}
+	return -EINVAL;
+}
+
 #define dynamic_pr_debug(fmt, ...)					\
 	do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
 #define dynamic_dev_dbg(dev, fmt, ...)					\
diff --git a/kernel/module.c b/kernel/module.c
index 78ac6ec..a4e6097 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2953,7 +2953,7 @@ static struct module *load_module(void __user *umod,
 
 	/* Module is ready to execute: parsing args may do that. */
 	err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
-			 -32768, 32767, NULL);
+			 -32768, 32767, &ddebug_dyndbg_module_param_cb);
 	if (err < 0)
 		goto unlink;
 
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 1435981..662204a 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -862,6 +862,41 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
 }
 EXPORT_SYMBOL_GPL(ddebug_add_module);
 
+/* handle both dyndbg=".." and $module.dyndbg=".." params at boot */
+static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
+				const char *unused)
+{
+	const char *modname = NULL;
+	char *sep;
+
+	sep = strchr(param, '.');
+	if (sep) {
+		*sep = '\0';
+		modname = param;
+		param = sep + 1;
+	}
+	if (strcmp(param, "dyndbg"))
+		return 0; /* skip all other params w/o error */
+
+	vpr_info("module: %s %s=\"%s\"\n", modname, param, val);
+
+	ddebug_exec_queries(val ? val : "+p");
+	return 0; /* query failure shouldnt stop module load */
+}
+
+/* handle dyndbg args to modprobe */
+int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *doing)
+{
+	if (strcmp(param, "dyndbg"))
+		return -ENOENT;
+
+	vpr_info("module: %s %s=\"%s\"\n", doing, param, val);
+
+	ddebug_exec_queries((val ? val : "+p"), doing);
+
+	return 0; /* query failure shouldnt stop module load */
+}
+
 static void ddebug_table_free(struct ddebug_table *dt)
 {
 	list_del_init(&dt->link);
@@ -929,6 +964,7 @@ static int __init dynamic_debug_init(void)
 {
 	struct _ddebug *iter, *iter_start;
 	const char *modname = NULL;
+	char *cmdline;
 	int ret = 0;
 	int n = 0;
 
@@ -955,18 +991,10 @@ static int __init dynamic_debug_init(void)
 	if (ret)
 		goto out_free;
 
-	/* ddebug_query boot param got passed -> set it up */
-	if (ddebug_setup_string[0] != '\0') {
-		ret = ddebug_exec_queries(ddebug_setup_string);
-		if (ret < 0)
-			pr_warn("Invalid ddebug boot param %s",
-				ddebug_setup_string);
-		else
-			pr_info("%d changes by ddebug_query\n", ret);
-
-		/* keep tables even on ddebug_query parse error */
-		ret = 0;
-	}
+	cmdline = kstrdup(saved_command_line, GFP_KERNEL);
+	parse_args("dyndbg params", cmdline, NULL,
+		   0, 0, 0, &ddebug_dyndbg_boot_param_cb);
+	kfree(cmdline);
 
 out_free:
 	if (ret)
@@ -977,5 +1005,6 @@ out_free:
 }
 /* Allow early initialization for boot messages via boot param */
 arch_initcall(dynamic_debug_init);
+
 /* Debugfs setup must be done later */
 module_init(dynamic_debug_init_debugfs);
-- 
1.7.7.6


  parent reply	other threads:[~2012-03-14 23:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-14 23:01 [00/11] pr_debug " jim.cromie
2012-03-14 23:01 ` [PATCH 01/11] init: trivial tweaks to initcall_levels jim.cromie
2012-03-14 23:01 ` [PATCH 02/11] dynamic_debug: fix leading spaces jim.cromie
2012-03-14 23:01 ` [PATCH 03/11] dynamic_debug: replace if (verbose) pr_info with macro vpr_info jim.cromie
2012-03-14 23:01 ` [PATCH 04/11] dynamic_debug: change ddebug_query core param to dyndbg jim.cromie
2012-03-14 23:02 ` [PATCH 05/11] params: add param-name to parse_one's pr_debug() jim.cromie
2012-03-14 23:02 ` [PATCH 06/11] params: add 3rd arg to option handler callback signature jim.cromie
2012-03-14 23:02 ` jim.cromie [this message]
2012-03-14 23:02 ` [PATCH 08/11] pnp: if CONFIG_DYNAMIC_DEBUG, use pnp.dyndbg instead of pnp.debug jim.cromie
2012-03-14 23:02 ` [PATCH 09/11] dynamic_debug: add modname arg to exec_query callchain jim.cromie
2012-03-14 23:02 ` [PATCH 10/11] dynamic_debug: update Documentation/*, Kconfig.debug jim.cromie
2012-03-14 23:02 ` [PATCH 11/11] dynamic_debug: init with core_initcall, not arch_initcall jim.cromie
2012-03-19  2:04 ` [00/11] pr_debug during module initialization Rusty Russell
2012-03-19  6:17   ` Jim Cromie
2012-03-19 23:27     ` Rusty Russell
2012-03-23 20:27 ` Jason Baron
2012-03-24  0:12   ` Jim Cromie
2012-03-26  0:24     ` Rusty Russell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1331766126-11674-8-git-send-email-jim.cromie@gmail.com \
    --to=jim.cromie@gmail.com \
    --cc=jbaron@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    --cc=trenn@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®