aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dynamic_debug.c
diff options
context:
space:
mode:
authorJim Cromie <jim.cromie@gmail.com>2012-04-27 16:30:35 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-30 14:31:46 -0400
commitb48420c1d3019ce8d84fb8e58f4ca86b8e3655b8 (patch)
treefeeeb1008ff2433bba3107c3584ec8b4a403cec5 /lib/dynamic_debug.c
parent9fb48c744ba6a4bf58b666f4e6fdac3008ea1bd4 (diff)
dynamic_debug: make dynamic-debug work for module initialization
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 callbacks invoked from parse_args. For builtin modules, dynamic_debug_init() now directly calls parse_args(..., &ddebug_dyndbg_boot_params_cb), to process the params undeclared in the modules, just after the ddebug tables are processed. While its slightly weird to reprocess the boot params, parse_args() is already called repeatedly by do_initcall_levels(). More importantly, the dyndbg queries (given in ddebug_query or dyndbg params) cannot be activated until after the ddebug tables are ready, and reusing parse_args is cleaner than doing an ad-hoc parse. This reparse would break options like inc_verbosity, but they probably should be params, like verbosity=3. ddebug_dyndbg_boot_params_cb() handles both bare dyndbg (aka: ddebug_query) and module-prefixed dyndbg params, 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 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. Note that modprobe reads /proc/cmdline, so "modprobe foo" grabs all foo.params, strips the "foo.", and passes these to the kernel. ddebug_dyndbg_module_params_cb() is again called for the unknown params; it handles dyndbg, and errors on others. The "doing" arg added previously contains the module name. 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. Also change pr_info in ddebug_exec_queries to vpr_info, no need to see it all the time. Signed-off-by: Jim Cromie <jim.cromie@gmail.com> CC: Thomas Renninger <trenn@suse.de> CC: Rusty Russell <rusty@rustcorp.com.au> Acked-by: Jason Baron <jbaron@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'lib/dynamic_debug.c')
-rw-r--r--lib/dynamic_debug.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 8675717c0f16..8fba40179305 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,
862} 862}
863EXPORT_SYMBOL_GPL(ddebug_add_module); 863EXPORT_SYMBOL_GPL(ddebug_add_module);
864 864
865/* handle both dyndbg=".." and $module.dyndbg=".." params at boot */
866static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
867 const char *unused)
868{
869 const char *modname = NULL;
870 char *sep;
871
872 sep = strchr(param, '.');
873 if (sep) {
874 *sep = '\0';
875 modname = param;
876 param = sep + 1;
877 }
878 if (strcmp(param, "dyndbg"))
879 return 0; /* skip all other params w/o error */
880
881 vpr_info("module: %s %s=\"%s\"\n", modname, param, val);
882
883 ddebug_exec_queries(val ? val : "+p");
884 return 0; /* query failure shouldnt stop module load */
885}
886
887/* handle dyndbg args to modprobe */
888int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *doing)
889{
890 if (strcmp(param, "dyndbg"))
891 return -ENOENT;
892
893 vpr_info("module: %s %s=\"%s\"\n", doing, param, val);
894
895 ddebug_exec_queries((val ? val : "+p"));
896
897 return 0; /* query failure shouldnt stop module load */
898}
899
865static void ddebug_table_free(struct ddebug_table *dt) 900static void ddebug_table_free(struct ddebug_table *dt)
866{ 901{
867 list_del_init(&dt->link); 902 list_del_init(&dt->link);
@@ -929,6 +964,7 @@ static int __init dynamic_debug_init(void)
929{ 964{
930 struct _ddebug *iter, *iter_start; 965 struct _ddebug *iter, *iter_start;
931 const char *modname = NULL; 966 const char *modname = NULL;
967 char *cmdline;
932 int ret = 0; 968 int ret = 0;
933 int n = 0; 969 int n = 0;
934 970
@@ -967,6 +1003,18 @@ static int __init dynamic_debug_init(void)
967 /* keep tables even on ddebug_query parse error */ 1003 /* keep tables even on ddebug_query parse error */
968 ret = 0; 1004 ret = 0;
969 } 1005 }
1006 /* now that ddebug tables are loaded, process all boot args
1007 * again to find and activate queries given in dyndbg params.
1008 * While this has already been done for known boot params, it
1009 * ignored the unknown ones (dyndbg in particular). Reusing
1010 * parse_args avoids ad-hoc parsing. This will also attempt
1011 * to activate queries for not-yet-loaded modules, which is
1012 * slightly noisy if verbose, but harmless.
1013 */
1014 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1015 parse_args("dyndbg params", cmdline, NULL,
1016 0, 0, 0, &ddebug_dyndbg_boot_param_cb);
1017 kfree(cmdline);
970 1018
971out_free: 1019out_free:
972 if (ret) 1020 if (ret)
@@ -977,5 +1025,6 @@ out_free:
977} 1025}
978/* Allow early initialization for boot messages via boot param */ 1026/* Allow early initialization for boot messages via boot param */
979arch_initcall(dynamic_debug_init); 1027arch_initcall(dynamic_debug_init);
1028
980/* Debugfs setup must be done later */ 1029/* Debugfs setup must be done later */
981module_init(dynamic_debug_init_debugfs); 1030module_init(dynamic_debug_init_debugfs);