blob: 1db1fc66053875babfb933f93399899e48d8c730 [file] [log] [blame]
Jason Barone9d376f2009-02-05 11:51:38 -05001/*
2 * lib/dynamic_debug.c
3 *
4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their
5 * source module.
6 *
7 * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
8 * By Greg Banks <gnb@melbourne.sgi.com>
9 * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved.
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010010 * Copyright (C) 2011 Bart Van Assche. All Rights Reserved.
Jason Barone9d376f2009-02-05 11:51:38 -050011 */
12
Joe Perches4ad275e2011-08-11 14:36:33 -040013#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
14
Jason Barone9d376f2009-02-05 11:51:38 -050015#include <linux/kernel.h>
16#include <linux/module.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070017#include <linux/moduleparam.h>
18#include <linux/kallsyms.h>
19#include <linux/types.h>
Jason Barone9d376f2009-02-05 11:51:38 -050020#include <linux/mutex.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070021#include <linux/proc_fs.h>
Jason Barone9d376f2009-02-05 11:51:38 -050022#include <linux/seq_file.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070023#include <linux/list.h>
24#include <linux/sysctl.h>
Jason Barone9d376f2009-02-05 11:51:38 -050025#include <linux/ctype.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070026#include <linux/string.h>
27#include <linux/uaccess.h>
Jason Barone9d376f2009-02-05 11:51:38 -050028#include <linux/dynamic_debug.h>
29#include <linux/debugfs.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/slab.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070031#include <linux/jump_label.h>
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010032#include <linux/hardirq.h>
Greg Kroah-Hartmane8d97922011-02-03 15:59:58 -080033#include <linux/sched.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070034#include <linux/device.h>
Jason Baronffa10cb2011-08-11 14:36:48 -040035#include <linux/netdevice.h>
Jason Barone9d376f2009-02-05 11:51:38 -050036
37extern struct _ddebug __start___verbose[];
38extern struct _ddebug __stop___verbose[];
39
Jason Barone9d376f2009-02-05 11:51:38 -050040struct ddebug_table {
41 struct list_head link;
42 char *mod_name;
43 unsigned int num_ddebugs;
Jason Barone9d376f2009-02-05 11:51:38 -050044 struct _ddebug *ddebugs;
45};
46
47struct ddebug_query {
48 const char *filename;
49 const char *module;
50 const char *function;
51 const char *format;
52 unsigned int first_lineno, last_lineno;
53};
54
55struct ddebug_iter {
56 struct ddebug_table *table;
57 unsigned int idx;
58};
59
60static DEFINE_MUTEX(ddebug_lock);
61static LIST_HEAD(ddebug_tables);
62static int verbose = 0;
Jim Cromie74df1382011-12-19 17:12:24 -050063module_param(verbose, int, 0644);
Jason Barone9d376f2009-02-05 11:51:38 -050064
Jim Cromie2b678312011-12-19 17:13:12 -050065/* Return the path relative to source root */
66static inline const char *trim_prefix(const char *path)
67{
68 int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
69
70 if (strncmp(path, __FILE__, skip))
71 skip = 0; /* prefix mismatch, don't skip */
72
73 return path + skip;
74}
75
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010076static struct { unsigned flag:8; char opt_char; } opt_array[] = {
77 { _DPRINTK_FLAGS_PRINT, 'p' },
78 { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
79 { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
80 { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
81 { _DPRINTK_FLAGS_INCL_TID, 't' },
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050082 { _DPRINTK_FLAGS_NONE, '_' },
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010083};
84
Jason Barone9d376f2009-02-05 11:51:38 -050085/* format a string into buf[] which describes the _ddebug's flags */
86static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
87 size_t maxlen)
88{
89 char *p = buf;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010090 int i;
Jason Barone9d376f2009-02-05 11:51:38 -050091
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050092 BUG_ON(maxlen < 6);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010093 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
94 if (dp->flags & opt_array[i].flag)
95 *p++ = opt_array[i].opt_char;
Jason Barone9d376f2009-02-05 11:51:38 -050096 if (p == buf)
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050097 *p++ = '_';
Jason Barone9d376f2009-02-05 11:51:38 -050098 *p = '\0';
99
100 return buf;
101}
102
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600103#define vpr_info(fmt, ...) \
104 if (verbose) do { pr_info(fmt, ##__VA_ARGS__); } while (0)
105
106#define vpr_info_dq(q, msg) \
107do { \
108 /* trim last char off format print */ \
109 vpr_info("%s: func=\"%s\" file=\"%s\" " \
110 "module=\"%s\" format=\"%.*s\" " \
111 "lineno=%u-%u", \
112 msg, \
113 q->function ? q->function : "", \
114 q->filename ? q->filename : "", \
115 q->module ? q->module : "", \
116 (int)(q->format ? strlen(q->format) - 1 : 0), \
117 q->format ? q->format : "", \
118 q->first_lineno, q->last_lineno); \
Jim Cromie574b3722011-12-19 17:13:16 -0500119} while (0)
120
Jason Barone9d376f2009-02-05 11:51:38 -0500121/*
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500122 * Search the tables for _ddebug's which match the given `query' and
123 * apply the `flags' and `mask' to them. Returns number of matching
124 * callsites, normally the same as number of changes. If verbose,
125 * logs the changes. Takes ddebug_lock.
Jason Barone9d376f2009-02-05 11:51:38 -0500126 */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500127static int ddebug_change(const struct ddebug_query *query,
128 unsigned int flags, unsigned int mask)
Jason Barone9d376f2009-02-05 11:51:38 -0500129{
130 int i;
131 struct ddebug_table *dt;
132 unsigned int newflags;
133 unsigned int nfound = 0;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500134 char flagbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500135
136 /* search for matching ddebugs */
137 mutex_lock(&ddebug_lock);
138 list_for_each_entry(dt, &ddebug_tables, link) {
139
140 /* match against the module name */
Jim Cromied6a238d2011-12-19 17:12:39 -0500141 if (query->module && strcmp(query->module, dt->mod_name))
Jason Barone9d376f2009-02-05 11:51:38 -0500142 continue;
143
144 for (i = 0 ; i < dt->num_ddebugs ; i++) {
145 struct _ddebug *dp = &dt->ddebugs[i];
146
147 /* match against the source filename */
Jim Cromied6a238d2011-12-19 17:12:39 -0500148 if (query->filename &&
Jason Barone9d376f2009-02-05 11:51:38 -0500149 strcmp(query->filename, dp->filename) &&
Andy Shevchenko35367ab2012-12-17 16:01:21 -0800150 strcmp(query->filename, kbasename(dp->filename)) &&
Jim Cromie2b678312011-12-19 17:13:12 -0500151 strcmp(query->filename, trim_prefix(dp->filename)))
Jason Barone9d376f2009-02-05 11:51:38 -0500152 continue;
153
154 /* match against the function */
Jim Cromied6a238d2011-12-19 17:12:39 -0500155 if (query->function &&
Jason Barone9d376f2009-02-05 11:51:38 -0500156 strcmp(query->function, dp->function))
157 continue;
158
159 /* match against the format */
Jim Cromied6a238d2011-12-19 17:12:39 -0500160 if (query->format &&
161 !strstr(dp->format, query->format))
Jason Barone9d376f2009-02-05 11:51:38 -0500162 continue;
163
164 /* match against the line number range */
165 if (query->first_lineno &&
166 dp->lineno < query->first_lineno)
167 continue;
168 if (query->last_lineno &&
169 dp->lineno > query->last_lineno)
170 continue;
171
172 nfound++;
173
174 newflags = (dp->flags & mask) | flags;
175 if (newflags == dp->flags)
176 continue;
Jason Barone9d376f2009-02-05 11:51:38 -0500177 dp->flags = newflags;
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600178 vpr_info("changed %s:%d [%s]%s =%s\n",
179 trim_prefix(dp->filename), dp->lineno,
180 dt->mod_name, dp->function,
181 ddebug_describe_flags(dp, flagbuf,
182 sizeof(flagbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500183 }
184 }
185 mutex_unlock(&ddebug_lock);
186
187 if (!nfound && verbose)
Joe Perches4ad275e2011-08-11 14:36:33 -0400188 pr_info("no matches for query\n");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500189
190 return nfound;
Jason Barone9d376f2009-02-05 11:51:38 -0500191}
192
193/*
Jason Barone9d376f2009-02-05 11:51:38 -0500194 * Split the buffer `buf' into space-separated words.
Greg Banks9898abb2009-02-06 12:54:26 +1100195 * Handles simple " and ' quoting, i.e. without nested,
196 * embedded or escaped \". Return the number of words
197 * or <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500198 */
199static int ddebug_tokenize(char *buf, char *words[], int maxwords)
200{
201 int nwords = 0;
202
Greg Banks9898abb2009-02-06 12:54:26 +1100203 while (*buf) {
204 char *end;
205
206 /* Skip leading whitespace */
André Goddard Rosae7d28602009-12-14 18:01:06 -0800207 buf = skip_spaces(buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100208 if (!*buf)
209 break; /* oh, it was trailing whitespace */
Jim Cromie8bd60262011-12-19 17:13:03 -0500210 if (*buf == '#')
211 break; /* token starts comment, skip rest of line */
Greg Banks9898abb2009-02-06 12:54:26 +1100212
Jim Cromie07100be2011-12-19 17:11:09 -0500213 /* find `end' of word, whitespace separated or quoted */
Greg Banks9898abb2009-02-06 12:54:26 +1100214 if (*buf == '"' || *buf == '\'') {
215 int quote = *buf++;
216 for (end = buf ; *end && *end != quote ; end++)
217 ;
218 if (!*end)
219 return -EINVAL; /* unclosed quote */
220 } else {
221 for (end = buf ; *end && !isspace(*end) ; end++)
222 ;
223 BUG_ON(end == buf);
224 }
Greg Banks9898abb2009-02-06 12:54:26 +1100225
Jim Cromie07100be2011-12-19 17:11:09 -0500226 /* `buf' is start of word, `end' is one past its end */
Greg Banks9898abb2009-02-06 12:54:26 +1100227 if (nwords == maxwords)
228 return -EINVAL; /* ran out of words[] before bytes */
229 if (*end)
230 *end++ = '\0'; /* terminate the word */
231 words[nwords++] = buf;
232 buf = end;
233 }
Jason Barone9d376f2009-02-05 11:51:38 -0500234
235 if (verbose) {
236 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400237 pr_info("split into words:");
Jason Barone9d376f2009-02-05 11:51:38 -0500238 for (i = 0 ; i < nwords ; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400239 pr_cont(" \"%s\"", words[i]);
240 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500241 }
242
243 return nwords;
244}
245
246/*
247 * Parse a single line number. Note that the empty string ""
248 * is treated as a special case and converted to zero, which
249 * is later treated as a "don't care" value.
250 */
251static inline int parse_lineno(const char *str, unsigned int *val)
252{
253 char *end = NULL;
254 BUG_ON(str == NULL);
255 if (*str == '\0') {
256 *val = 0;
257 return 0;
258 }
259 *val = simple_strtoul(str, &end, 10);
260 return end == NULL || end == str || *end != '\0' ? -EINVAL : 0;
261}
262
263/*
264 * Undo octal escaping in a string, inplace. This is useful to
265 * allow the user to express a query which matches a format
266 * containing embedded spaces.
267 */
268#define isodigit(c) ((c) >= '0' && (c) <= '7')
269static char *unescape(char *str)
270{
271 char *in = str;
272 char *out = str;
273
274 while (*in) {
275 if (*in == '\\') {
276 if (in[1] == '\\') {
277 *out++ = '\\';
278 in += 2;
279 continue;
280 } else if (in[1] == 't') {
281 *out++ = '\t';
282 in += 2;
283 continue;
284 } else if (in[1] == 'n') {
285 *out++ = '\n';
286 in += 2;
287 continue;
288 } else if (isodigit(in[1]) &&
289 isodigit(in[2]) &&
290 isodigit(in[3])) {
291 *out++ = ((in[1] - '0')<<6) |
292 ((in[2] - '0')<<3) |
293 (in[3] - '0');
294 in += 4;
295 continue;
296 }
297 }
298 *out++ = *in++;
299 }
300 *out = '\0';
301
302 return str;
303}
304
Jim Cromie820874c2011-12-19 17:12:49 -0500305static int check_set(const char **dest, char *src, char *name)
306{
307 int rc = 0;
308
309 if (*dest) {
310 rc = -EINVAL;
311 pr_err("match-spec:%s val:%s overridden by %s",
312 name, *dest, src);
313 }
314 *dest = src;
315 return rc;
316}
317
Jason Barone9d376f2009-02-05 11:51:38 -0500318/*
319 * Parse words[] as a ddebug query specification, which is a series
320 * of (keyword, value) pairs chosen from these possibilities:
321 *
322 * func <function-name>
323 * file <full-pathname>
324 * file <base-filename>
325 * module <module-name>
326 * format <escaped-string-to-find-in-format>
327 * line <lineno>
328 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500329 *
330 * Only 1 of each type is allowed.
331 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500332 */
333static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600334 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500335{
336 unsigned int i;
Jim Cromie820874c2011-12-19 17:12:49 -0500337 int rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500338
339 /* check we have an even number of words */
340 if (nwords % 2 != 0)
341 return -EINVAL;
342 memset(query, 0, sizeof(*query));
343
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600344 if (modname)
345 /* support $modname.dyndbg=<multiple queries> */
346 query->module = modname;
347
Jason Barone9d376f2009-02-05 11:51:38 -0500348 for (i = 0 ; i < nwords ; i += 2) {
349 if (!strcmp(words[i], "func"))
Jim Cromie820874c2011-12-19 17:12:49 -0500350 rc = check_set(&query->function, words[i+1], "func");
Jason Barone9d376f2009-02-05 11:51:38 -0500351 else if (!strcmp(words[i], "file"))
Jim Cromie820874c2011-12-19 17:12:49 -0500352 rc = check_set(&query->filename, words[i+1], "file");
Jason Barone9d376f2009-02-05 11:51:38 -0500353 else if (!strcmp(words[i], "module"))
Jim Cromie820874c2011-12-19 17:12:49 -0500354 rc = check_set(&query->module, words[i+1], "module");
Jason Barone9d376f2009-02-05 11:51:38 -0500355 else if (!strcmp(words[i], "format"))
Jim Cromie820874c2011-12-19 17:12:49 -0500356 rc = check_set(&query->format, unescape(words[i+1]),
357 "format");
Jason Barone9d376f2009-02-05 11:51:38 -0500358 else if (!strcmp(words[i], "line")) {
359 char *first = words[i+1];
360 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500361 if (query->first_lineno || query->last_lineno) {
362 pr_err("match-spec:line given 2 times\n");
363 return -EINVAL;
364 }
Jason Barone9d376f2009-02-05 11:51:38 -0500365 if (last)
366 *last++ = '\0';
367 if (parse_lineno(first, &query->first_lineno) < 0)
368 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500369 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500370 /* range <first>-<last> */
Jim Cromie820874c2011-12-19 17:12:49 -0500371 if (parse_lineno(last, &query->last_lineno)
372 < query->first_lineno) {
373 pr_err("last-line < 1st-line\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500374 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500375 }
Jason Barone9d376f2009-02-05 11:51:38 -0500376 } else {
377 query->last_lineno = query->first_lineno;
378 }
379 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500380 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500381 return -EINVAL;
382 }
Jim Cromie820874c2011-12-19 17:12:49 -0500383 if (rc)
384 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500385 }
Jim Cromie574b3722011-12-19 17:13:16 -0500386 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500387 return 0;
388}
389
390/*
391 * Parse `str' as a flags specification, format [-+=][p]+.
392 * Sets up *maskp and *flagsp to be used when changing the
393 * flags fields of matched _ddebug's. Returns 0 on success
394 * or <0 on error.
395 */
396static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
397 unsigned int *maskp)
398{
399 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100400 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500401
402 switch (*str) {
403 case '+':
404 case '-':
405 case '=':
406 op = *str++;
407 break;
408 default:
409 return -EINVAL;
410 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600411 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500412
413 for ( ; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100414 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
415 if (*str == opt_array[i].opt_char) {
416 flags |= opt_array[i].flag;
417 break;
418 }
Jason Barone9d376f2009-02-05 11:51:38 -0500419 }
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100420 if (i < 0)
421 return -EINVAL;
Jason Barone9d376f2009-02-05 11:51:38 -0500422 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600423 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500424
425 /* calculate final *flagsp, *maskp according to mask and op */
426 switch (op) {
427 case '=':
428 *maskp = 0;
429 *flagsp = flags;
430 break;
431 case '+':
432 *maskp = ~0U;
433 *flagsp = flags;
434 break;
435 case '-':
436 *maskp = ~flags;
437 *flagsp = 0;
438 break;
439 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600440 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500441 return 0;
442}
443
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600444static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200445{
446 unsigned int flags = 0, mask = 0;
447 struct ddebug_query query;
448#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500449 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200450 char *words[MAXWORDS];
451
452 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
453 if (nwords <= 0)
454 return -EINVAL;
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600455 if (ddebug_parse_query(words, nwords-1, &query, modname))
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200456 return -EINVAL;
457 if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
458 return -EINVAL;
459
460 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500461 nfound = ddebug_change(&query, flags, mask);
462 vpr_info_dq((&query), (nfound) ? "applied" : "no-match");
463
464 return nfound;
465}
466
467/* handle multiple queries in query string, continue on error, return
468 last error or number of matching callsites. Module name is either
469 in param (for boot arg) or perhaps in query string.
470*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600471static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500472{
473 char *split;
474 int i, errs = 0, exitcode = 0, rc, nfound = 0;
475
476 for (i = 0; query; query = split) {
477 split = strpbrk(query, ";\n");
478 if (split)
479 *split++ = '\0';
480
481 query = skip_spaces(query);
482 if (!query || !*query || *query == '#')
483 continue;
484
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600485 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500486
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600487 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500488 if (rc < 0) {
489 errs++;
490 exitcode = rc;
491 } else
492 nfound += rc;
493 i++;
494 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600495 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500496 i, nfound, errs);
497
498 if (exitcode)
499 return exitcode;
500 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200501}
502
Jason Baron431625d2011-10-04 14:13:19 -0700503#define PREFIX_SIZE 64
504
505static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100506{
Jason Baron431625d2011-10-04 14:13:19 -0700507 if (PREFIX_SIZE - wrote > 0)
508 return PREFIX_SIZE - wrote;
509 return 0;
510}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100511
Jason Baron431625d2011-10-04 14:13:19 -0700512static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
513{
514 int pos_after_tid;
515 int pos = 0;
516
Joe Perches798efc62012-09-12 20:11:29 -0700517 *buf = '\0';
518
Jason Baron431625d2011-10-04 14:13:19 -0700519 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100520 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700521 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100522 else
Jason Baron431625d2011-10-04 14:13:19 -0700523 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700524 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100525 }
Jason Baron431625d2011-10-04 14:13:19 -0700526 pos_after_tid = pos;
527 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
528 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700529 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700530 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
531 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700532 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700533 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500534 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700535 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700536 if (pos - pos_after_tid)
537 pos += snprintf(buf + pos, remaining(pos), " ");
538 if (pos >= PREFIX_SIZE)
539 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400540
Jason Baron431625d2011-10-04 14:13:19 -0700541 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400542}
543
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100544int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
545{
546 va_list args;
547 int res;
Jason Baron431625d2011-10-04 14:13:19 -0700548 struct va_format vaf;
549 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100550
551 BUG_ON(!descriptor);
552 BUG_ON(!fmt);
553
554 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700555
Jason Baron431625d2011-10-04 14:13:19 -0700556 vaf.fmt = fmt;
557 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700558
559 res = printk(KERN_DEBUG "%s%pV",
560 dynamic_emit_prefix(descriptor, buf), &vaf);
561
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100562 va_end(args);
563
564 return res;
565}
566EXPORT_SYMBOL(__dynamic_pr_debug);
567
Joe Perchescbc46632011-08-11 14:36:21 -0400568int __dynamic_dev_dbg(struct _ddebug *descriptor,
569 const struct device *dev, const char *fmt, ...)
570{
571 struct va_format vaf;
572 va_list args;
573 int res;
574
575 BUG_ON(!descriptor);
576 BUG_ON(!fmt);
577
578 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700579
Joe Perchescbc46632011-08-11 14:36:21 -0400580 vaf.fmt = fmt;
581 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700582
583 if (!dev) {
584 res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
585 } else {
586 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700587
Joe Perches666f3552012-09-12 20:14:11 -0700588 res = dev_printk_emit(7, dev, "%s%s %s: %pV",
589 dynamic_emit_prefix(descriptor, buf),
590 dev_driver_string(dev), dev_name(dev),
591 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700592 }
593
Joe Perchescbc46632011-08-11 14:36:21 -0400594 va_end(args);
595
596 return res;
597}
598EXPORT_SYMBOL(__dynamic_dev_dbg);
599
Jason Baron0feefd92011-10-04 14:13:22 -0700600#ifdef CONFIG_NET
601
Jason Baronffa10cb2011-08-11 14:36:48 -0400602int __dynamic_netdev_dbg(struct _ddebug *descriptor,
Joe Perchesb004ff42012-09-12 20:12:19 -0700603 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400604{
605 struct va_format vaf;
606 va_list args;
607 int res;
608
609 BUG_ON(!descriptor);
610 BUG_ON(!fmt);
611
612 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700613
Jason Baronffa10cb2011-08-11 14:36:48 -0400614 vaf.fmt = fmt;
615 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700616
617 if (dev && dev->dev.parent) {
618 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700619
Joe Perches666f3552012-09-12 20:14:11 -0700620 res = dev_printk_emit(7, dev->dev.parent,
621 "%s%s %s %s: %pV",
622 dynamic_emit_prefix(descriptor, buf),
623 dev_driver_string(dev->dev.parent),
624 dev_name(dev->dev.parent),
625 netdev_name(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700626 } else if (dev) {
627 res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
628 } else {
629 res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
630 }
631
Jason Baronffa10cb2011-08-11 14:36:48 -0400632 va_end(args);
633
634 return res;
635}
636EXPORT_SYMBOL(__dynamic_netdev_dbg);
637
Jason Baron0feefd92011-10-04 14:13:22 -0700638#endif
639
Jim Cromiebc757f62011-12-19 17:12:29 -0500640#define DDEBUG_STRING_SIZE 1024
641static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
642
Thomas Renningera648ec02010-08-06 16:11:02 +0200643static __init int ddebug_setup_query(char *str)
644{
Jim Cromiebc757f62011-12-19 17:12:29 -0500645 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400646 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200647 return 0;
648 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500649 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200650 return 1;
651}
652
653__setup("ddebug_query=", ddebug_setup_query);
654
Jason Barone9d376f2009-02-05 11:51:38 -0500655/*
656 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
657 * command text from userspace, parses and executes it.
658 */
Jim Cromie72814912011-12-19 17:13:07 -0500659#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500660static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
661 size_t len, loff_t *offp)
662{
Jim Cromie72814912011-12-19 17:13:07 -0500663 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200664 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500665
666 if (len == 0)
667 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500668 if (len > USER_BUF_PAGE - 1) {
669 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500670 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500671 }
672 tmpbuf = kmalloc(len + 1, GFP_KERNEL);
673 if (!tmpbuf)
674 return -ENOMEM;
675 if (copy_from_user(tmpbuf, ubuf, len)) {
676 kfree(tmpbuf);
Jason Barone9d376f2009-02-05 11:51:38 -0500677 return -EFAULT;
Jim Cromie72814912011-12-19 17:13:07 -0500678 }
Jason Barone9d376f2009-02-05 11:51:38 -0500679 tmpbuf[len] = '\0';
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600680 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500681
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600682 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500683 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500684 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200685 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500686
687 *offp += len;
688 return len;
689}
690
691/*
692 * Set the iterator to point to the first _ddebug object
693 * and return a pointer to that first object. Returns
694 * NULL if there are no _ddebugs at all.
695 */
696static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
697{
698 if (list_empty(&ddebug_tables)) {
699 iter->table = NULL;
700 iter->idx = 0;
701 return NULL;
702 }
703 iter->table = list_entry(ddebug_tables.next,
704 struct ddebug_table, link);
705 iter->idx = 0;
706 return &iter->table->ddebugs[iter->idx];
707}
708
709/*
710 * Advance the iterator to point to the next _ddebug
711 * object from the one the iterator currently points at,
712 * and returns a pointer to the new _ddebug. Returns
713 * NULL if the iterator has seen all the _ddebugs.
714 */
715static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
716{
717 if (iter->table == NULL)
718 return NULL;
719 if (++iter->idx == iter->table->num_ddebugs) {
720 /* iterate to next table */
721 iter->idx = 0;
722 if (list_is_last(&iter->table->link, &ddebug_tables)) {
723 iter->table = NULL;
724 return NULL;
725 }
726 iter->table = list_entry(iter->table->link.next,
727 struct ddebug_table, link);
728 }
729 return &iter->table->ddebugs[iter->idx];
730}
731
732/*
733 * Seq_ops start method. Called at the start of every
734 * read() call from userspace. Takes the ddebug_lock and
735 * seeks the seq_file's iterator to the given position.
736 */
737static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
738{
739 struct ddebug_iter *iter = m->private;
740 struct _ddebug *dp;
741 int n = *pos;
742
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600743 vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500744
745 mutex_lock(&ddebug_lock);
746
747 if (!n)
748 return SEQ_START_TOKEN;
749 if (n < 0)
750 return NULL;
751 dp = ddebug_iter_first(iter);
752 while (dp != NULL && --n > 0)
753 dp = ddebug_iter_next(iter);
754 return dp;
755}
756
757/*
758 * Seq_ops next method. Called several times within a read()
759 * call from userspace, with ddebug_lock held. Walks to the
760 * next _ddebug object with a special case for the header line.
761 */
762static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
763{
764 struct ddebug_iter *iter = m->private;
765 struct _ddebug *dp;
766
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600767 vpr_info("called m=%p p=%p *pos=%lld\n",
768 m, p, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500769
770 if (p == SEQ_START_TOKEN)
771 dp = ddebug_iter_first(iter);
772 else
773 dp = ddebug_iter_next(iter);
774 ++*pos;
775 return dp;
776}
777
778/*
779 * Seq_ops show method. Called several times within a read()
780 * call from userspace, with ddebug_lock held. Formats the
781 * current _ddebug as a single human-readable line, with a
782 * special case for the header line.
783 */
784static int ddebug_proc_show(struct seq_file *m, void *p)
785{
786 struct ddebug_iter *iter = m->private;
787 struct _ddebug *dp = p;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500788 char flagsbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500789
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600790 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500791
792 if (p == SEQ_START_TOKEN) {
793 seq_puts(m,
794 "# filename:lineno [module]function flags format\n");
795 return 0;
796 }
797
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500798 seq_printf(m, "%s:%u [%s]%s =%s \"",
Jim Cromie2b678312011-12-19 17:13:12 -0500799 trim_prefix(dp->filename), dp->lineno,
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500800 iter->table->mod_name, dp->function,
801 ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500802 seq_escape(m, dp->format, "\t\r\n\"");
803 seq_puts(m, "\"\n");
804
805 return 0;
806}
807
808/*
809 * Seq_ops stop method. Called at the end of each read()
810 * call from userspace. Drops ddebug_lock.
811 */
812static void ddebug_proc_stop(struct seq_file *m, void *p)
813{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600814 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500815 mutex_unlock(&ddebug_lock);
816}
817
818static const struct seq_operations ddebug_proc_seqops = {
819 .start = ddebug_proc_start,
820 .next = ddebug_proc_next,
821 .show = ddebug_proc_show,
822 .stop = ddebug_proc_stop
823};
824
825/*
Jim Cromie07100be2011-12-19 17:11:09 -0500826 * File_ops->open method for <debugfs>/dynamic_debug/control. Does
827 * the seq_file setup dance, and also creates an iterator to walk the
828 * _ddebugs. Note that we create a seq_file always, even for O_WRONLY
829 * files where it's not needed, as doing so simplifies the ->release
830 * method.
Jason Barone9d376f2009-02-05 11:51:38 -0500831 */
832static int ddebug_proc_open(struct inode *inode, struct file *file)
833{
834 struct ddebug_iter *iter;
835 int err;
836
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600837 vpr_info("called\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500838
839 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
840 if (iter == NULL)
841 return -ENOMEM;
842
843 err = seq_open(file, &ddebug_proc_seqops);
844 if (err) {
845 kfree(iter);
846 return err;
847 }
848 ((struct seq_file *) file->private_data)->private = iter;
849 return 0;
850}
851
852static const struct file_operations ddebug_proc_fops = {
853 .owner = THIS_MODULE,
854 .open = ddebug_proc_open,
855 .read = seq_read,
856 .llseek = seq_lseek,
857 .release = seq_release_private,
858 .write = ddebug_proc_write
859};
860
861/*
862 * Allocate a new ddebug_table for the given module
863 * and add it to the global list.
864 */
865int ddebug_add_module(struct _ddebug *tab, unsigned int n,
866 const char *name)
867{
868 struct ddebug_table *dt;
869 char *new_name;
870
871 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
872 if (dt == NULL)
873 return -ENOMEM;
874 new_name = kstrdup(name, GFP_KERNEL);
875 if (new_name == NULL) {
876 kfree(dt);
877 return -ENOMEM;
878 }
879 dt->mod_name = new_name;
880 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500881 dt->ddebugs = tab;
882
883 mutex_lock(&ddebug_lock);
884 list_add_tail(&dt->link, &ddebug_tables);
885 mutex_unlock(&ddebug_lock);
886
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600887 vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500888 return 0;
889}
890EXPORT_SYMBOL_GPL(ddebug_add_module);
891
Jim Cromie6ab676e2012-04-27 14:30:37 -0600892/* helper for ddebug_dyndbg_(boot|module)_param_cb */
893static int ddebug_dyndbg_param_cb(char *param, char *val,
894 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600895{
Jim Cromieb48420c2012-04-27 14:30:35 -0600896 char *sep;
897
898 sep = strchr(param, '.');
899 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600900 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600901 *sep = '\0';
902 modname = param;
903 param = sep + 1;
904 }
905 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600906 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600907
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600908 ddebug_exec_queries((val ? val : "+p"), modname);
909
Jim Cromieb48420c2012-04-27 14:30:35 -0600910 return 0; /* query failure shouldnt stop module load */
911}
912
Jim Cromie6ab676e2012-04-27 14:30:37 -0600913/* handle both dyndbg and $module.dyndbg params at boot */
914static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
915 const char *unused)
Jim Cromieb48420c2012-04-27 14:30:35 -0600916{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600917 vpr_info("%s=\"%s\"\n", param, val);
918 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
919}
Jim Cromieb48420c2012-04-27 14:30:35 -0600920
Jim Cromie6ab676e2012-04-27 14:30:37 -0600921/*
922 * modprobe foo finds foo.params in boot-args, strips "foo.", and
923 * passes them to load_module(). This callback gets unknown params,
924 * processes dyndbg params, rejects others.
925 */
926int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
927{
928 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
929 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600930}
931
Jason Barone9d376f2009-02-05 11:51:38 -0500932static void ddebug_table_free(struct ddebug_table *dt)
933{
934 list_del_init(&dt->link);
935 kfree(dt->mod_name);
936 kfree(dt);
937}
938
939/*
940 * Called in response to a module being unloaded. Removes
941 * any ddebug_table's which point at the module.
942 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000943int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500944{
945 struct ddebug_table *dt, *nextdt;
946 int ret = -ENOENT;
947
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600948 vpr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500949
950 mutex_lock(&ddebug_lock);
951 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
952 if (!strcmp(dt->mod_name, mod_name)) {
953 ddebug_table_free(dt);
954 ret = 0;
955 }
956 }
957 mutex_unlock(&ddebug_lock);
958 return ret;
959}
960EXPORT_SYMBOL_GPL(ddebug_remove_module);
961
962static void ddebug_remove_all_tables(void)
963{
964 mutex_lock(&ddebug_lock);
965 while (!list_empty(&ddebug_tables)) {
966 struct ddebug_table *dt = list_entry(ddebug_tables.next,
967 struct ddebug_table,
968 link);
969 ddebug_table_free(dt);
970 }
971 mutex_unlock(&ddebug_lock);
972}
973
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200974static __initdata int ddebug_init_success;
975
976static int __init dynamic_debug_init_debugfs(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500977{
978 struct dentry *dir, *file;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200979
980 if (!ddebug_init_success)
981 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -0500982
983 dir = debugfs_create_dir("dynamic_debug", NULL);
984 if (!dir)
985 return -ENOMEM;
986 file = debugfs_create_file("control", 0644, dir, NULL,
987 &ddebug_proc_fops);
988 if (!file) {
989 debugfs_remove(dir);
990 return -ENOMEM;
991 }
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200992 return 0;
993}
994
995static int __init dynamic_debug_init(void)
996{
997 struct _ddebug *iter, *iter_start;
998 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -0600999 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001000 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001001 int n = 0, entries = 0, modct = 0;
1002 int verbose_bytes = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001003
Jim Cromieb5b78f82011-12-19 17:12:54 -05001004 if (__start___verbose == __stop___verbose) {
1005 pr_warn("_ddebug table is empty in a "
1006 "CONFIG_DYNAMIC_DEBUG build");
1007 return 1;
Jason Barone9d376f2009-02-05 11:51:38 -05001008 }
Jim Cromieb5b78f82011-12-19 17:12:54 -05001009 iter = __start___verbose;
1010 modname = iter->modname;
1011 iter_start = iter;
1012 for (; iter < __stop___verbose; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001013 entries++;
1014 verbose_bytes += strlen(iter->modname) + strlen(iter->function)
1015 + strlen(iter->filename) + strlen(iter->format);
1016
Jim Cromieb5b78f82011-12-19 17:12:54 -05001017 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001018 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001019 ret = ddebug_add_module(iter_start, n, modname);
1020 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001021 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001022 n = 0;
1023 modname = iter->modname;
1024 iter_start = iter;
1025 }
1026 n++;
1027 }
1028 ret = ddebug_add_module(iter_start, n, modname);
1029 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001030 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001031
Jim Cromieaf442392012-04-27 14:30:38 -06001032 ddebug_init_success = 1;
Jim Cromie41076922012-04-27 14:30:39 -06001033 vpr_info("%d modules, %d entries and %d bytes in ddebug tables,"
1034 " %d bytes in (readonly) verbose section\n",
1035 modct, entries, (int)( modct * sizeof(struct ddebug_table)),
1036 verbose_bytes + (int)(__stop___verbose - __start___verbose));
Jim Cromieaf442392012-04-27 14:30:38 -06001037
1038 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001039 if (ddebug_setup_string[0] != '\0') {
Jim Cromief0b919d2012-04-27 14:30:36 -06001040 pr_warn("ddebug_query param name is deprecated,"
1041 " change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001042 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001043 if (ret < 0)
Joe Perches4ad275e2011-08-11 14:36:33 -04001044 pr_warn("Invalid ddebug boot param %s",
1045 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001046 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001047 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001048 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001049 /* now that ddebug tables are loaded, process all boot args
1050 * again to find and activate queries given in dyndbg params.
1051 * While this has already been done for known boot params, it
1052 * ignored the unknown ones (dyndbg in particular). Reusing
1053 * parse_args avoids ad-hoc parsing. This will also attempt
1054 * to activate queries for not-yet-loaded modules, which is
1055 * slightly noisy if verbose, but harmless.
1056 */
1057 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1058 parse_args("dyndbg params", cmdline, NULL,
1059 0, 0, 0, &ddebug_dyndbg_boot_param_cb);
1060 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001061 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001062
Jim Cromieaf442392012-04-27 14:30:38 -06001063out_err:
1064 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001065 return 0;
1066}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001067/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001068early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001069
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001070/* Debugfs setup must be done later */
Jim Cromie3ec56522012-04-27 14:30:42 -06001071fs_initcall(dynamic_debug_init_debugfs);