From a15d49fd3094cff90e5410ca454a870e0a722fe1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 16 Apr 2012 15:06:25 +0200 Subject: driver core: check start node in klist_iter_init_node klist_iter_init_node() takes a node as a start argument. However, this node might not be valid anymore. This patch updates the klist_iter_init_node() and dependent functions to return an error if so. All calling functions have been audited to check for a return code here. Signed-off-by: Hannes Reinecke Cc: Greg Kroah-Hartmann Cc: Kay Sievers Cc: Stable Kernel Cc: Linux Kernel Signed-off-by: Greg Kroah-Hartman --- lib/klist.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/klist.c b/lib/klist.c index 0874e41..a2741a7 100644 --- a/lib/klist.c +++ b/lib/klist.c @@ -278,13 +278,19 @@ EXPORT_SYMBOL_GPL(klist_node_attached); * Similar to klist_iter_init(), but starts the action off with @n, * instead of with the list head. */ -void klist_iter_init_node(struct klist *k, struct klist_iter *i, - struct klist_node *n) +int klist_iter_init_node(struct klist *k, struct klist_iter *i, + struct klist_node *n) { + if (n) { + kref_get(&n->n_ref); + if (!n->n_klist) { + kref_put(&n->n_ref); + return -ENODEV; + } + } i->i_klist = k; i->i_cur = n; - if (n) - kref_get(&n->n_ref); + return 0; } EXPORT_SYMBOL_GPL(klist_iter_init_node); -- cgit v1.1 From 7cd9c9bb57476167e83b7780dbc06d1dd601789d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 19 Apr 2012 19:17:30 -0700 Subject: Revert "driver core: check start node in klist_iter_init_node" This reverts commit a15d49fd3094cff90e5410ca454a870e0a722fe1 as that patch broke the build. Cc: Hannes Reinecke Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- lib/klist.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/klist.c b/lib/klist.c index a2741a7..0874e41 100644 --- a/lib/klist.c +++ b/lib/klist.c @@ -278,19 +278,13 @@ EXPORT_SYMBOL_GPL(klist_node_attached); * Similar to klist_iter_init(), but starts the action off with @n, * instead of with the list head. */ -int klist_iter_init_node(struct klist *k, struct klist_iter *i, - struct klist_node *n) +void klist_iter_init_node(struct klist *k, struct klist_iter *i, + struct klist_node *n) { - if (n) { - kref_get(&n->n_ref); - if (!n->n_klist) { - kref_put(&n->n_ref); - return -ENODEV; - } - } i->i_klist = k; i->i_cur = n; - return 0; + if (n) + kref_get(&n->n_ref); } EXPORT_SYMBOL_GPL(klist_iter_init_node); -- cgit v1.1 From 6b9606106ba58d2bd80610f97e06fea58206b47c Mon Sep 17 00:00:00 2001 From: yan Date: Fri, 20 Apr 2012 21:25:53 +0800 Subject: lib/kobject.c : Remove redundant check in create_dir create_dir is a static function used only in kobject_add_internal. There's no need to do check here, for kobject_add_internal will reject kobject with invalid name. Signed-off-by: Yan Hong Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index 21dee7c..bbffa21 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -47,13 +47,11 @@ static int populate_dir(struct kobject *kobj) static int create_dir(struct kobject *kobj) { int error = 0; - if (kobject_name(kobj)) { - error = sysfs_create_dir(kobj); - if (!error) { - error = populate_dir(kobj); - if (error) - sysfs_remove_dir(kobj); - } + error = sysfs_create_dir(kobj); + if (!error) { + error = populate_dir(kobj); + if (error) + sysfs_remove_dir(kobj); } return error; } -- cgit v1.1 From b8ccd5dee776d85e29cf139c77595b7369e294bc Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:32 -0600 Subject: dynamic_debug: replace if (verbose) pr_info with macro vpr_info Use vpr_info to declutter code, reduce indenting, and change one additional pr_info call in ddebug_exec_queries. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 81 +++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 46 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 310c753..8675717 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -107,20 +107,22 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, return buf; } -#define vpr_info_dq(q, msg) \ -do { \ - if (verbose) \ - /* trim last char off format print */ \ - pr_info("%s: func=\"%s\" file=\"%s\" " \ - "module=\"%s\" format=\"%.*s\" " \ - "lineno=%u-%u", \ - msg, \ - q->function ? q->function : "", \ - q->filename ? q->filename : "", \ - q->module ? q->module : "", \ - (int)(q->format ? strlen(q->format) - 1 : 0), \ - q->format ? q->format : "", \ - q->first_lineno, q->last_lineno); \ +#define vpr_info(fmt, ...) \ + if (verbose) do { pr_info(fmt, ##__VA_ARGS__); } while (0) + +#define vpr_info_dq(q, msg) \ +do { \ + /* trim last char off format print */ \ + vpr_info("%s: func=\"%s\" file=\"%s\" " \ + "module=\"%s\" format=\"%.*s\" " \ + "lineno=%u-%u", \ + msg, \ + q->function ? q->function : "", \ + q->filename ? q->filename : "", \ + q->module ? q->module : "", \ + (int)(q->format ? strlen(q->format) - 1 : 0), \ + q->format ? q->format : "", \ + q->first_lineno, q->last_lineno); \ } while (0) /* @@ -180,12 +182,11 @@ static int ddebug_change(const struct ddebug_query *query, if (newflags == dp->flags) continue; dp->flags = newflags; - if (verbose) - pr_info("changed %s:%d [%s]%s =%s\n", - trim_prefix(dp->filename), dp->lineno, - dt->mod_name, dp->function, - ddebug_describe_flags(dp, flagbuf, - sizeof(flagbuf))); + vpr_info("changed %s:%d [%s]%s =%s\n", + trim_prefix(dp->filename), dp->lineno, + dt->mod_name, dp->function, + ddebug_describe_flags(dp, flagbuf, + sizeof(flagbuf))); } } mutex_unlock(&ddebug_lock); @@ -410,8 +411,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, default: return -EINVAL; } - if (verbose) - pr_info("op='%c'\n", op); + vpr_info("op='%c'\n", op); for ( ; *str ; ++str) { for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { @@ -423,8 +423,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, if (i < 0) return -EINVAL; } - if (verbose) - pr_info("flags=0x%x\n", flags); + vpr_info("flags=0x%x\n", flags); /* calculate final *flagsp, *maskp according to mask and op */ switch (op) { @@ -441,8 +440,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, *flagsp = 0; break; } - if (verbose) - pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp); + vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp); return 0; } @@ -487,8 +485,7 @@ static int ddebug_exec_queries(char *query) if (!query || !*query || *query == '#') continue; - if (verbose) - pr_info("query %d: \"%s\"\n", i, query); + vpr_info("query %d: \"%s\"\n", i, query); rc = ddebug_exec_query(query); if (rc < 0) { @@ -498,7 +495,7 @@ static int ddebug_exec_queries(char *query) nfound += rc; i++; } - pr_info("processed %d queries, with %d matches, %d errs\n", + vpr_info("processed %d queries, with %d matches, %d errs\n", i, nfound, errs); if (exitcode) @@ -653,8 +650,7 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, return -EFAULT; } tmpbuf[len] = '\0'; - if (verbose) - pr_info("read %d bytes from userspace\n", (int)len); + vpr_info("read %d bytes from userspace\n", (int)len); ret = ddebug_exec_queries(tmpbuf); kfree(tmpbuf); @@ -717,8 +713,7 @@ static void *ddebug_proc_start(struct seq_file *m, loff_t *pos) struct _ddebug *dp; int n = *pos; - if (verbose) - pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos); + vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos); mutex_lock(&ddebug_lock); @@ -742,9 +737,8 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) struct ddebug_iter *iter = m->private; struct _ddebug *dp; - if (verbose) - pr_info("called m=%p p=%p *pos=%lld\n", - m, p, (unsigned long long)*pos); + vpr_info("called m=%p p=%p *pos=%lld\n", + m, p, (unsigned long long)*pos); if (p == SEQ_START_TOKEN) dp = ddebug_iter_first(iter); @@ -766,8 +760,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) struct _ddebug *dp = p; char flagsbuf[10]; - if (verbose) - pr_info("called m=%p p=%p\n", m, p); + vpr_info("called m=%p p=%p\n", m, p); if (p == SEQ_START_TOKEN) { seq_puts(m, @@ -791,8 +784,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) */ static void ddebug_proc_stop(struct seq_file *m, void *p) { - if (verbose) - pr_info("called m=%p p=%p\n", m, p); + vpr_info("called m=%p p=%p\n", m, p); mutex_unlock(&ddebug_lock); } @@ -815,8 +807,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file) struct ddebug_iter *iter; int err; - if (verbose) - pr_info("called\n"); + vpr_info("called\n"); iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (iter == NULL) @@ -866,8 +857,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, list_add_tail(&dt->link, &ddebug_tables); mutex_unlock(&ddebug_lock); - if (verbose) - pr_info("%u debug prints in module %s\n", n, dt->mod_name); + vpr_info("%u debug prints in module %s\n", n, dt->mod_name); return 0; } EXPORT_SYMBOL_GPL(ddebug_add_module); @@ -888,8 +878,7 @@ int ddebug_remove_module(const char *mod_name) struct ddebug_table *dt, *nextdt; int ret = -ENOENT; - if (verbose) - pr_info("removing module \"%s\"\n", mod_name); + vpr_info("removing module \"%s\"\n", mod_name); mutex_lock(&ddebug_lock); list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { -- cgit v1.1 From b48420c1d3019ce8d84fb8e58f4ca86b8e3655b8 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:35 -0600 Subject: 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 CC: Thomas Renninger CC: Rusty Russell Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 8675717..8fba401 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")); + + 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; @@ -967,6 +1003,18 @@ static int __init dynamic_debug_init(void) /* keep tables even on ddebug_query parse error */ ret = 0; } + /* now that ddebug tables are loaded, process all boot args + * again to find and activate queries given in dyndbg params. + * While this has already been done for known boot params, it + * ignored the unknown ones (dyndbg in particular). Reusing + * parse_args avoids ad-hoc parsing. This will also attempt + * to activate queries for not-yet-loaded modules, which is + * slightly noisy if verbose, but harmless. + */ + 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 +1025,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); -- cgit v1.1 From f0b919d967284313be4a767ba92ab5a88cb27410 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:36 -0600 Subject: dynamic_debug: deprecate ddebug_query, suggest dyndbg instead With ddebug_dyndbg_boot_params_cb() handling bare dyndbg params, we dont need ddebug_query param anymore. Add a warning when processing ddebug_query= param that it is deprecated, and to change it to dyndbg= Add a deprecation notice for v3.8 to feature-removal-schedule.txt, and add a suggested deprecation period of 3 releases to the header. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 8fba401..09f2cda 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -993,6 +993,8 @@ static int __init dynamic_debug_init(void) /* ddebug_query boot param got passed -> set it up */ if (ddebug_setup_string[0] != '\0') { + pr_warn("ddebug_query param name is deprecated," + " change it to dyndbg\n"); ret = ddebug_exec_queries(ddebug_setup_string); if (ret < 0) pr_warn("Invalid ddebug boot param %s", -- cgit v1.1 From 6ab676e96422f33a873006096f928feeded7ce3b Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:37 -0600 Subject: dynamic_debug: combine parse_args callbacks together Refactor ddebug_dyndbg_boot_param_cb and ddebug_dyndbg_module_param_cb into a common helper function, and call it from both. The handling of foo.dyndbg is unneeded by the latter, but harmless. The 2 callers differ only by pr_info and the return code they pass to the helper for when an unknown param is handled. I could slightly reduce dmesg clutter by putting the vpr_info in the common helper, after the return on_err, but that loses __func__ context, is overly silent on module_cb unknown param errors, and the clutter is only when dynamic_debug.verbose=1 anyway. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 09f2cda..3b06f92 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -862,39 +862,43 @@ 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) +/* helper for ddebug_dyndbg_(boot|module)_param_cb */ +static int ddebug_dyndbg_param_cb(char *param, char *val, + const char *modname, int on_err) { - const char *modname = NULL; char *sep; sep = strchr(param, '.'); if (sep) { + /* needed only for ddebug_dyndbg_boot_param_cb */ *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); + return on_err; /* determined by caller */ 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) +/* handle both dyndbg and $module.dyndbg params at boot */ +static int ddebug_dyndbg_boot_param_cb(char *param, char *val, + const char *unused) { - if (strcmp(param, "dyndbg")) - return -ENOENT; - - vpr_info("module: %s %s=\"%s\"\n", doing, param, val); - - ddebug_exec_queries((val ? val : "+p")); + vpr_info("%s=\"%s\"\n", param, val); + return ddebug_dyndbg_param_cb(param, val, NULL, 0); +} - return 0; /* query failure shouldnt stop module load */ +/* + * modprobe foo finds foo.params in boot-args, strips "foo.", and + * passes them to load_module(). This callback gets unknown params, + * processes dyndbg params, rejects others. + */ +int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module) +{ + vpr_info("module: %s %s=\"%s\"\n", module, param, val); + return ddebug_dyndbg_param_cb(param, val, module, -ENOENT); } static void ddebug_table_free(struct ddebug_table *dt) -- cgit v1.1 From af442399fcf378a21ffe924b182f6d9ee70001ca Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:38 -0600 Subject: dynamic_debug: simplify dynamic_debug_init error exit We dont want errors while parsing ddebug_query to unload ddebug tables, so set success after tables are loaded, and return 0 after query parsing is done. Simplify error handling code since its no longer used for success, and change goto label to out_err to clarify this. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 3b06f92..66e0ec4 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -984,7 +984,7 @@ static int __init dynamic_debug_init(void) if (strcmp(modname, iter->modname)) { ret = ddebug_add_module(iter_start, n, modname); if (ret) - goto out_free; + goto out_err; n = 0; modname = iter->modname; iter_start = iter; @@ -993,9 +993,11 @@ static int __init dynamic_debug_init(void) } ret = ddebug_add_module(iter_start, n, modname); if (ret) - goto out_free; + goto out_err; - /* ddebug_query boot param got passed -> set it up */ + ddebug_init_success = 1; + + /* apply ddebug_query boot param, dont unload tables on err */ if (ddebug_setup_string[0] != '\0') { pr_warn("ddebug_query param name is deprecated," " change it to dyndbg\n"); @@ -1005,9 +1007,6 @@ static int __init dynamic_debug_init(void) ddebug_setup_string); else pr_info("%d changes by ddebug_query\n", ret); - - /* keep tables even on ddebug_query parse error */ - ret = 0; } /* now that ddebug tables are loaded, process all boot args * again to find and activate queries given in dyndbg params. @@ -1021,12 +1020,10 @@ static int __init dynamic_debug_init(void) parse_args("dyndbg params", cmdline, NULL, 0, 0, 0, &ddebug_dyndbg_boot_param_cb); kfree(cmdline); + return 0; -out_free: - if (ret) - ddebug_remove_all_tables(); - else - ddebug_init_success = 1; +out_err: + ddebug_remove_all_tables(); return 0; } /* Allow early initialization for boot messages via boot param */ -- cgit v1.1 From 4107692760db8160a65347f7bb2fa7fa7bf9b0d1 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:39 -0600 Subject: dynamic_debug: print ram usage by ddebug tables if verbose Print ram usage of dynamic-debug tables and verbose section so user knows cost of enabling CONFIG_DYNAMIC_DEBUG. This only counts the size of the _ddebug tables for builtins and the __verbose section that they refer to, not those used in loadable modules. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 66e0ec4..76da6aa 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -970,7 +970,8 @@ static int __init dynamic_debug_init(void) const char *modname = NULL; char *cmdline; int ret = 0; - int n = 0; + int n = 0, entries = 0, modct = 0; + int verbose_bytes = 0; if (__start___verbose == __stop___verbose) { pr_warn("_ddebug table is empty in a " @@ -981,7 +982,12 @@ static int __init dynamic_debug_init(void) modname = iter->modname; iter_start = iter; for (; iter < __stop___verbose; iter++) { + entries++; + verbose_bytes += strlen(iter->modname) + strlen(iter->function) + + strlen(iter->filename) + strlen(iter->format); + if (strcmp(modname, iter->modname)) { + modct++; ret = ddebug_add_module(iter_start, n, modname); if (ret) goto out_err; @@ -996,6 +1002,10 @@ static int __init dynamic_debug_init(void) goto out_err; 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)); /* apply ddebug_query boot param, dont unload tables on err */ if (ddebug_setup_string[0] != '\0') { -- cgit v1.1 From 8e59b5cfb9a6f43753236b554d785e8efca62db7 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:40 -0600 Subject: dynamic_debug: add modname arg to exec_query callchain Pass module name into ddebug_exec_queries(), ddebug_exec_query(), and ddebug_parse_query() as separate parameter. In ddebug_parse_query(), the module name is added into the query struct before the query-string is parsed. This allows the query-string to be shorter: instead of: $modname.dyndbg="module $modname +fp" do this: $modname.dyndbg="+fp" Omitting "module $modname" from the query string is actually required for $modname.dyndbg rules; the set-only-once check added in a previous patch will throw an error if its added again. ddebug_query="..." has no $modname associated with it, so the query string may include it. This also fixes redundant "module $modname" otherwise needed to handle multiple queries per string: $modname.dyndbg="func foo +fp; func bar +fp" Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 76da6aa..cfd84638 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -338,7 +338,7 @@ static int check_set(const char **dest, char *src, char *name) * Returns 0 on success, <0 on error. */ static int ddebug_parse_query(char *words[], int nwords, - struct ddebug_query *query) + struct ddebug_query *query, const char *modname) { unsigned int i; int rc; @@ -348,6 +348,10 @@ static int ddebug_parse_query(char *words[], int nwords, return -EINVAL; memset(query, 0, sizeof(*query)); + if (modname) + /* support $modname.dyndbg= */ + query->module = modname; + for (i = 0 ; i < nwords ; i += 2) { if (!strcmp(words[i], "func")) rc = check_set(&query->function, words[i+1], "func"); @@ -444,7 +448,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, return 0; } -static int ddebug_exec_query(char *query_string) +static int ddebug_exec_query(char *query_string, const char *modname) { unsigned int flags = 0, mask = 0; struct ddebug_query query; @@ -455,7 +459,7 @@ static int ddebug_exec_query(char *query_string) nwords = ddebug_tokenize(query_string, words, MAXWORDS); if (nwords <= 0) return -EINVAL; - if (ddebug_parse_query(words, nwords-1, &query)) + if (ddebug_parse_query(words, nwords-1, &query, modname)) return -EINVAL; if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) return -EINVAL; @@ -471,7 +475,7 @@ static int ddebug_exec_query(char *query_string) last error or number of matching callsites. Module name is either in param (for boot arg) or perhaps in query string. */ -static int ddebug_exec_queries(char *query) +static int ddebug_exec_queries(char *query, const char *modname) { char *split; int i, errs = 0, exitcode = 0, rc, nfound = 0; @@ -487,7 +491,7 @@ static int ddebug_exec_queries(char *query) vpr_info("query %d: \"%s\"\n", i, query); - rc = ddebug_exec_query(query); + rc = ddebug_exec_query(query, modname); if (rc < 0) { errs++; exitcode = rc; @@ -652,7 +656,7 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, tmpbuf[len] = '\0'; vpr_info("read %d bytes from userspace\n", (int)len); - ret = ddebug_exec_queries(tmpbuf); + ret = ddebug_exec_queries(tmpbuf, NULL); kfree(tmpbuf); if (ret < 0) return ret; @@ -878,7 +882,8 @@ static int ddebug_dyndbg_param_cb(char *param, char *val, if (strcmp(param, "dyndbg")) return on_err; /* determined by caller */ - ddebug_exec_queries(val ? val : "+p"); + ddebug_exec_queries((val ? val : "+p"), modname); + return 0; /* query failure shouldnt stop module load */ } @@ -1011,7 +1016,7 @@ static int __init dynamic_debug_init(void) if (ddebug_setup_string[0] != '\0') { pr_warn("ddebug_query param name is deprecated," " change it to dyndbg\n"); - ret = ddebug_exec_queries(ddebug_setup_string); + ret = ddebug_exec_queries(ddebug_setup_string, NULL); if (ret < 0) pr_warn("Invalid ddebug boot param %s", ddebug_setup_string); -- cgit v1.1 From 29e36c9ffb696ed8d73e1aee713d483ec74a9a43 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:41 -0600 Subject: dynamic_debug: update Documentation/*, Kconfig.debug In dynamic-debug-howto.txt: - add section: Debug Messages at Module Initialization Time - update flags indicators in example outputs to include '=' - make flags descriptions tabular - add item on '_' flag-char - add dyndbg, boot-args examples - rewrap some paragraphs with long lines In Kconfig.debug, note that compiling with -DDEBUG enables all pr_debug()s in that code. In kernel-parameters.txt, add dyndbg and module.dyndbg items, and deprecate ddebug_query. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig.debug | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 6777153..ef8192b 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1205,8 +1205,13 @@ config DYNAMIC_DEBUG otherwise be available at runtime. These messages can then be enabled/disabled based on various levels of scope - per source file, function, module, format string, and line number. This mechanism - implicitly enables all pr_debug() and dev_dbg() calls. The impact of - this compile option is a larger kernel text size of about 2%. + implicitly compiles in all pr_debug() and dev_dbg() calls, which + enlarges the kernel text size by about 2%. + + If a source file is compiled with DEBUG flag set, any + pr_debug() calls in it are enabled by default, but can be + disabled at runtime as below. Note that DEBUG flag is + turned on by many CONFIG_*DEBUG* options. Usage: @@ -1223,16 +1228,16 @@ config DYNAMIC_DEBUG lineno : line number of the debug statement module : module that contains the debug statement function : function that contains the debug statement - flags : 'p' means the line is turned 'on' for printing + flags : '=p' means the line is turned 'on' for printing format : the format used for the debug statement From a live system: nullarbor:~ # cat /dynamic_debug/control # filename:lineno [module]function flags format - fs/aio.c:222 [aio]__put_ioctx - "__put_ioctx:\040freeing\040%p\012" - fs/aio.c:248 [aio]ioctx_alloc - "ENOMEM:\040nr_events\040too\040high\012" - fs/aio.c:1770 [aio]sys_io_cancel - "calling\040cancel\012" + fs/aio.c:222 [aio]__put_ioctx =_ "__put_ioctx:\040freeing\040%p\012" + fs/aio.c:248 [aio]ioctx_alloc =_ "ENOMEM:\040nr_events\040too\040high\012" + fs/aio.c:1770 [aio]sys_io_cancel =_ "calling\040cancel\012" Example usage: -- cgit v1.1 From 3ec5652ab70f6e9a888d9e5f67c858af354323b3 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 27 Apr 2012 14:30:42 -0600 Subject: dynamic_debug: init with early_initcall, not arch_initcall 1- Call dynamic_debug_init() from early_initcall, not arch_initcall. 2- Call dynamic_debug_init_debugfs() from fs_initcall, not module_init. RFC: This works for me on a 64 bit desktop and a i586 SBC, but is untested on other arches. I presume there is or was a reason original code used arch_initcall, maybe the constraints have changed. This makes facility available as soon as possible. 2nd change has a downside when dynamic_debug.verbose=1; all the vpr_info()s called in the proc-fs code are activated, causing voluminous output from dmesg. TBD: Im unsure of this explanation, but the output is there. This could be fixed by changing those callsites to v2pr_info(if verbose > 1). 1st change is still not early enough to enable pr_debugs in kernel/params, so parsing of boot-args isnt logged. The reparse of those args is however visible after params.dyndbg="+p" is processed. Signed-off-by: Jim Cromie Acked-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index cfd84638..7ca29a0 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -1042,7 +1042,7 @@ out_err: return 0; } /* Allow early initialization for boot messages via boot param */ -arch_initcall(dynamic_debug_init); +early_initcall(dynamic_debug_init); /* Debugfs setup must be done later */ -module_init(dynamic_debug_init_debugfs); +fs_initcall(dynamic_debug_init_debugfs); -- cgit v1.1 From 9c1c21a0533aa37a475e8e8cce7ee064ed771881 Mon Sep 17 00:00:00 2001 From: Aneesh V Date: Fri, 27 Apr 2012 17:54:03 +0530 Subject: ddr: add LPDDR2 data from JESD209-2 add LPDDR2 data from the JEDEC spec JESD209-2. The data includes: 1. Addressing information for LPDDR2 memories of different densities and types(S2/S4) 2. AC timing data. This data will useful for memory controller device drivers. Right now this is used by the TI EMIF SDRAM controller driver. Signed-off-by: Aneesh V Reviewed-by: Santosh Shilimkar Reviewed-by: Benoit Cousson [santosh.shilimkar@ti.com: Moved to drivers/memory from drivers/misc] Signed-off-by: Santosh Shilimkar Tested-by: Lokesh Vutla Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig | 8 +++ lib/Makefile | 2 + lib/jedec_ddr_data.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 lib/jedec_ddr_data.c (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 4a8aba2..0e25c03 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -353,6 +353,14 @@ config CORDIC This option provides an implementation of the CORDIC algorithm; calculations are in fixed point. Module will be called cordic. +config DDR + bool "JEDEC DDR data" + help + Data from JEDEC specs for DDR SDRAM memories, + particularly the AC timing parameters and addressing + information. This data is useful for drivers handling + DDR SDRAM controllers. + config MPILIB tristate select CLZ_TAB diff --git a/lib/Makefile b/lib/Makefile index 18515f0..74290c9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -123,6 +123,8 @@ obj-$(CONFIG_SIGNATURE) += digsig.o obj-$(CONFIG_CLZ_TAB) += clz_tab.o +obj-$(CONFIG_DDR) += jedec_ddr_data.o + hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/lib/jedec_ddr_data.c b/lib/jedec_ddr_data.c new file mode 100644 index 0000000..6d2cbf1 --- /dev/null +++ b/lib/jedec_ddr_data.c @@ -0,0 +1,135 @@ +/* + * DDR addressing details and AC timing parameters from JEDEC specs + * + * Copyright (C) 2012 Texas Instruments, Inc. + * + * Aneesh V + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +/* LPDDR2 addressing details from JESD209-2 section 2.4 */ +const struct lpddr2_addressing + lpddr2_jedec_addressing_table[NUM_DDR_ADDR_TABLE_ENTRIES] = { + {B4, T_REFI_15_6, T_RFC_90}, /* 64M */ + {B4, T_REFI_15_6, T_RFC_90}, /* 128M */ + {B4, T_REFI_7_8, T_RFC_90}, /* 256M */ + {B4, T_REFI_7_8, T_RFC_90}, /* 512M */ + {B8, T_REFI_7_8, T_RFC_130}, /* 1GS4 */ + {B8, T_REFI_3_9, T_RFC_130}, /* 2GS4 */ + {B8, T_REFI_3_9, T_RFC_130}, /* 4G */ + {B8, T_REFI_3_9, T_RFC_210}, /* 8G */ + {B4, T_REFI_7_8, T_RFC_130}, /* 1GS2 */ + {B4, T_REFI_3_9, T_RFC_130}, /* 2GS2 */ +}; +EXPORT_SYMBOL_GPL(lpddr2_jedec_addressing_table); + +/* LPDDR2 AC timing parameters from JESD209-2 section 12 */ +const struct lpddr2_timings + lpddr2_jedec_timings[NUM_DDR_TIMING_TABLE_ENTRIES] = { + /* Speed bin 400(200 MHz) */ + [0] = { + .max_freq = 200000000, + .min_freq = 10000000, + .tRPab = 21000, + .tRCD = 18000, + .tWR = 15000, + .tRAS_min = 42000, + .tRRD = 10000, + .tWTR = 10000, + .tXP = 7500, + .tRTP = 7500, + .tCKESR = 15000, + .tDQSCK_max = 5500, + .tFAW = 50000, + .tZQCS = 90000, + .tZQCL = 360000, + .tZQinit = 1000000, + .tRAS_max_ns = 70000, + .tDQSCK_max_derated = 6000, + }, + /* Speed bin 533(266 MHz) */ + [1] = { + .max_freq = 266666666, + .min_freq = 10000000, + .tRPab = 21000, + .tRCD = 18000, + .tWR = 15000, + .tRAS_min = 42000, + .tRRD = 10000, + .tWTR = 7500, + .tXP = 7500, + .tRTP = 7500, + .tCKESR = 15000, + .tDQSCK_max = 5500, + .tFAW = 50000, + .tZQCS = 90000, + .tZQCL = 360000, + .tZQinit = 1000000, + .tRAS_max_ns = 70000, + .tDQSCK_max_derated = 6000, + }, + /* Speed bin 800(400 MHz) */ + [2] = { + .max_freq = 400000000, + .min_freq = 10000000, + .tRPab = 21000, + .tRCD = 18000, + .tWR = 15000, + .tRAS_min = 42000, + .tRRD = 10000, + .tWTR = 7500, + .tXP = 7500, + .tRTP = 7500, + .tCKESR = 15000, + .tDQSCK_max = 5500, + .tFAW = 50000, + .tZQCS = 90000, + .tZQCL = 360000, + .tZQinit = 1000000, + .tRAS_max_ns = 70000, + .tDQSCK_max_derated = 6000, + }, + /* Speed bin 1066(533 MHz) */ + [3] = { + .max_freq = 533333333, + .min_freq = 10000000, + .tRPab = 21000, + .tRCD = 18000, + .tWR = 15000, + .tRAS_min = 42000, + .tRRD = 10000, + .tWTR = 7500, + .tXP = 7500, + .tRTP = 7500, + .tCKESR = 15000, + .tDQSCK_max = 5500, + .tFAW = 50000, + .tZQCS = 90000, + .tZQCL = 360000, + .tZQinit = 1000000, + .tRAS_max_ns = 70000, + .tDQSCK_max_derated = 5620, + }, +}; +EXPORT_SYMBOL_GPL(lpddr2_jedec_timings); + +const struct lpddr2_min_tck lpddr2_jedec_min_tck = { + .tRPab = 3, + .tRCD = 3, + .tWR = 3, + .tRASmin = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; +EXPORT_SYMBOL_GPL(lpddr2_jedec_min_tck); -- cgit v1.1 From 04db6e5fddca55186b6a74339a62c800150648bc Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Thu, 3 May 2012 11:57:39 -0600 Subject: dynamic_debug: remove unneeded includes These arent currently needed, so drop them. Some will probably get re-added when static-branches are added, but include loops prevent that at present. Signed-off-by: Jim Cromie Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 7ca29a0..fc5d270 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -14,24 +14,14 @@ #include #include -#include -#include -#include #include -#include #include -#include -#include #include -#include -#include #include #include #include -#include #include #include -#include #include extern struct _ddebug __start___verbose[]; -- cgit v1.1 From fef15d2f3d97c9858694f234af94a4ef40d86679 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 May 2012 16:47:32 -0700 Subject: Revert "dynamic_debug: remove unneeded includes" This reverts commit 04db6e5fddca55186b6a74339a62c800150648bc. Odds are, we really don't want to revert all of these, and need to be more careful in the future to make sure we don't break the build of other arches. Reported-by: Stephen Rothwell Cc: Jim Cromie Signed-off-by: Greg Kroah-Hartman --- lib/dynamic_debug.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib') diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index fc5d270..7ca29a0 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -14,14 +14,24 @@ #include #include +#include +#include +#include #include +#include #include +#include +#include #include +#include +#include #include #include #include +#include #include #include +#include #include extern struct _ddebug __start___verbose[]; -- cgit v1.1 From 9ff1f838e9c019b16b720dca9b04565f1a6e0316 Mon Sep 17 00:00:00 2001 From: Zhi Yong Wu Date: Mon, 7 May 2012 10:48:25 +0800 Subject: kobject: fix the uncorrect comment Signed-off-by: Zhi Yong Wu Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/kobject.c b/lib/kobject.c index 38fcc60..e07ee1f 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -632,7 +632,7 @@ struct kobject *kobject_create(void) /** * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs * - * @name: the name for the kset + * @name: the name for the kobject * @parent: the parent kobject of this kobject, if any. * * This function creates a kobject structure dynamically and registers it -- cgit v1.1 From 649e6ee33f73ba1c4f2492c6de9aff2254b540cb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 May 2012 04:30:45 +0200 Subject: printk() - restore timestamp printing at console output The output of the timestamps got lost with the conversion of the kmsg buffer to records; restore the old behavior. Document, that CONFIG_PRINTK_TIME now only controls the output of the timestamps in the syslog() system call and on the console, and not the recording of the timestamps. Cc: Joe Perches Cc: Linus Torvalds Cc: Sasha Levin Cc: Ingo Molnar Reported-by: Yinghai Lu Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/Kconfig.debug | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ef8192b..e119341 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3,12 +3,16 @@ config PRINTK_TIME bool "Show timing information on printks" depends on PRINTK help - Selecting this option causes timing information to be - included in printk output. This allows you to measure - the interval between kernel operations, including bootup - operations. This is useful for identifying long delays - in kernel startup. Or add printk.time=1 at boot-time. - See Documentation/kernel-parameters.txt + Selecting this option causes time stamps of the printk() + messages to be added to the output of the syslog() system + call and at the console. + + The timestamp is always recorded internally, and exported + to /dev/kmsg. This flag just specifies if the timestamp should + be included, not that the timestamp is recorded. + + The behavior is also controlled by the kernel command line + parameter printk.time=1. See Documentation/kernel-parameters.txt config DEFAULT_MESSAGE_LOGLEVEL int "Default message log level (1-7)" -- cgit v1.1