blob: ac7d27737e4292e23c44ea3d9892e7225221ba77 [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);
Joe Perchesf657fd22012-12-05 16:48:26 -050062static int verbose;
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
Joe Perchesf657fd22012-12-05 16:48:26 -0500103#define vpr_info(fmt, ...) \
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600104do { \
Joe Perchesf657fd22012-12-05 16:48:26 -0500105 if (verbose) \
106 pr_info(fmt, ##__VA_ARGS__); \
Jim Cromie574b3722011-12-19 17:13:16 -0500107} while (0)
108
Joe Perchesf657fd22012-12-05 16:48:26 -0500109static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
110{
111 /* trim any trailing newlines */
112 int fmtlen = 0;
113
114 if (query->format) {
115 fmtlen = strlen(query->format);
116 while (fmtlen && query->format[fmtlen - 1] == '\n')
117 fmtlen--;
118 }
119
120 vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
121 msg,
122 query->function ? query->function : "",
123 query->filename ? query->filename : "",
124 query->module ? query->module : "",
125 fmtlen, query->format ? query->format : "",
126 query->first_lineno, query->last_lineno);
127}
128
Jason Barone9d376f2009-02-05 11:51:38 -0500129/*
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500130 * Search the tables for _ddebug's which match the given `query' and
131 * apply the `flags' and `mask' to them. Returns number of matching
132 * callsites, normally the same as number of changes. If verbose,
133 * logs the changes. Takes ddebug_lock.
Jason Barone9d376f2009-02-05 11:51:38 -0500134 */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500135static int ddebug_change(const struct ddebug_query *query,
136 unsigned int flags, unsigned int mask)
Jason Barone9d376f2009-02-05 11:51:38 -0500137{
138 int i;
139 struct ddebug_table *dt;
140 unsigned int newflags;
141 unsigned int nfound = 0;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500142 char flagbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500143
144 /* search for matching ddebugs */
145 mutex_lock(&ddebug_lock);
146 list_for_each_entry(dt, &ddebug_tables, link) {
147
148 /* match against the module name */
Jim Cromied6a238d2011-12-19 17:12:39 -0500149 if (query->module && strcmp(query->module, dt->mod_name))
Jason Barone9d376f2009-02-05 11:51:38 -0500150 continue;
151
Joe Perchesf657fd22012-12-05 16:48:26 -0500152 for (i = 0; i < dt->num_ddebugs; i++) {
Jason Barone9d376f2009-02-05 11:51:38 -0500153 struct _ddebug *dp = &dt->ddebugs[i];
154
155 /* match against the source filename */
Jim Cromied6a238d2011-12-19 17:12:39 -0500156 if (query->filename &&
Jason Barone9d376f2009-02-05 11:51:38 -0500157 strcmp(query->filename, dp->filename) &&
Andy Shevchenko35367ab2012-12-17 16:01:21 -0800158 strcmp(query->filename, kbasename(dp->filename)) &&
Jim Cromie2b678312011-12-19 17:13:12 -0500159 strcmp(query->filename, trim_prefix(dp->filename)))
Jason Barone9d376f2009-02-05 11:51:38 -0500160 continue;
161
162 /* match against the function */
Jim Cromied6a238d2011-12-19 17:12:39 -0500163 if (query->function &&
Jason Barone9d376f2009-02-05 11:51:38 -0500164 strcmp(query->function, dp->function))
165 continue;
166
167 /* match against the format */
Jim Cromied6a238d2011-12-19 17:12:39 -0500168 if (query->format &&
169 !strstr(dp->format, query->format))
Jason Barone9d376f2009-02-05 11:51:38 -0500170 continue;
171
172 /* match against the line number range */
173 if (query->first_lineno &&
174 dp->lineno < query->first_lineno)
175 continue;
176 if (query->last_lineno &&
177 dp->lineno > query->last_lineno)
178 continue;
179
180 nfound++;
181
182 newflags = (dp->flags & mask) | flags;
183 if (newflags == dp->flags)
184 continue;
Jason Barone9d376f2009-02-05 11:51:38 -0500185 dp->flags = newflags;
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600186 vpr_info("changed %s:%d [%s]%s =%s\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500187 trim_prefix(dp->filename), dp->lineno,
188 dt->mod_name, dp->function,
189 ddebug_describe_flags(dp, flagbuf,
190 sizeof(flagbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500191 }
192 }
193 mutex_unlock(&ddebug_lock);
194
195 if (!nfound && verbose)
Joe Perches4ad275e2011-08-11 14:36:33 -0400196 pr_info("no matches for query\n");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500197
198 return nfound;
Jason Barone9d376f2009-02-05 11:51:38 -0500199}
200
201/*
Jason Barone9d376f2009-02-05 11:51:38 -0500202 * Split the buffer `buf' into space-separated words.
Greg Banks9898abb2009-02-06 12:54:26 +1100203 * Handles simple " and ' quoting, i.e. without nested,
204 * embedded or escaped \". Return the number of words
205 * or <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500206 */
207static int ddebug_tokenize(char *buf, char *words[], int maxwords)
208{
209 int nwords = 0;
210
Greg Banks9898abb2009-02-06 12:54:26 +1100211 while (*buf) {
212 char *end;
213
214 /* Skip leading whitespace */
André Goddard Rosae7d28602009-12-14 18:01:06 -0800215 buf = skip_spaces(buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100216 if (!*buf)
217 break; /* oh, it was trailing whitespace */
Jim Cromie8bd60262011-12-19 17:13:03 -0500218 if (*buf == '#')
219 break; /* token starts comment, skip rest of line */
Greg Banks9898abb2009-02-06 12:54:26 +1100220
Jim Cromie07100be2011-12-19 17:11:09 -0500221 /* find `end' of word, whitespace separated or quoted */
Greg Banks9898abb2009-02-06 12:54:26 +1100222 if (*buf == '"' || *buf == '\'') {
223 int quote = *buf++;
Joe Perchesf657fd22012-12-05 16:48:26 -0500224 for (end = buf; *end && *end != quote; end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100225 ;
226 if (!*end)
227 return -EINVAL; /* unclosed quote */
228 } else {
Joe Perchesf657fd22012-12-05 16:48:26 -0500229 for (end = buf; *end && !isspace(*end); end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100230 ;
231 BUG_ON(end == buf);
232 }
Greg Banks9898abb2009-02-06 12:54:26 +1100233
Jim Cromie07100be2011-12-19 17:11:09 -0500234 /* `buf' is start of word, `end' is one past its end */
Greg Banks9898abb2009-02-06 12:54:26 +1100235 if (nwords == maxwords)
236 return -EINVAL; /* ran out of words[] before bytes */
237 if (*end)
238 *end++ = '\0'; /* terminate the word */
239 words[nwords++] = buf;
240 buf = end;
241 }
Jason Barone9d376f2009-02-05 11:51:38 -0500242
243 if (verbose) {
244 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400245 pr_info("split into words:");
Joe Perchesf657fd22012-12-05 16:48:26 -0500246 for (i = 0; i < nwords; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400247 pr_cont(" \"%s\"", words[i]);
248 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500249 }
250
251 return nwords;
252}
253
254/*
255 * Parse a single line number. Note that the empty string ""
256 * is treated as a special case and converted to zero, which
257 * is later treated as a "don't care" value.
258 */
259static inline int parse_lineno(const char *str, unsigned int *val)
260{
261 char *end = NULL;
262 BUG_ON(str == NULL);
263 if (*str == '\0') {
264 *val = 0;
265 return 0;
266 }
267 *val = simple_strtoul(str, &end, 10);
268 return end == NULL || end == str || *end != '\0' ? -EINVAL : 0;
269}
270
271/*
272 * Undo octal escaping in a string, inplace. This is useful to
273 * allow the user to express a query which matches a format
274 * containing embedded spaces.
275 */
276#define isodigit(c) ((c) >= '0' && (c) <= '7')
277static char *unescape(char *str)
278{
279 char *in = str;
280 char *out = str;
281
282 while (*in) {
283 if (*in == '\\') {
284 if (in[1] == '\\') {
285 *out++ = '\\';
286 in += 2;
287 continue;
288 } else if (in[1] == 't') {
289 *out++ = '\t';
290 in += 2;
291 continue;
292 } else if (in[1] == 'n') {
293 *out++ = '\n';
294 in += 2;
295 continue;
296 } else if (isodigit(in[1]) &&
Joe Perchesf657fd22012-12-05 16:48:26 -0500297 isodigit(in[2]) &&
298 isodigit(in[3])) {
299 *out++ = (((in[1] - '0') << 6) |
300 ((in[2] - '0') << 3) |
301 (in[3] - '0'));
Jason Barone9d376f2009-02-05 11:51:38 -0500302 in += 4;
303 continue;
304 }
305 }
306 *out++ = *in++;
307 }
308 *out = '\0';
309
310 return str;
311}
312
Jim Cromie820874c2011-12-19 17:12:49 -0500313static int check_set(const char **dest, char *src, char *name)
314{
315 int rc = 0;
316
317 if (*dest) {
318 rc = -EINVAL;
Joe Perchesf657fd22012-12-05 16:48:26 -0500319 pr_err("match-spec:%s val:%s overridden by %s\n",
320 name, *dest, src);
Jim Cromie820874c2011-12-19 17:12:49 -0500321 }
322 *dest = src;
323 return rc;
324}
325
Jason Barone9d376f2009-02-05 11:51:38 -0500326/*
327 * Parse words[] as a ddebug query specification, which is a series
328 * of (keyword, value) pairs chosen from these possibilities:
329 *
330 * func <function-name>
331 * file <full-pathname>
332 * file <base-filename>
333 * module <module-name>
334 * format <escaped-string-to-find-in-format>
335 * line <lineno>
336 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500337 *
338 * Only 1 of each type is allowed.
339 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500340 */
341static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600342 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500343{
344 unsigned int i;
Jim Cromie820874c2011-12-19 17:12:49 -0500345 int rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500346
347 /* check we have an even number of words */
348 if (nwords % 2 != 0)
349 return -EINVAL;
350 memset(query, 0, sizeof(*query));
351
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600352 if (modname)
353 /* support $modname.dyndbg=<multiple queries> */
354 query->module = modname;
355
Joe Perchesf657fd22012-12-05 16:48:26 -0500356 for (i = 0; i < nwords; i += 2) {
357 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500358 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500359 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500360 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500361 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500362 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500363 } else if (!strcmp(words[i], "format")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500364 rc = check_set(&query->format, unescape(words[i+1]),
Joe Perchesf657fd22012-12-05 16:48:26 -0500365 "format");
366 } else if (!strcmp(words[i], "line")) {
Jason Barone9d376f2009-02-05 11:51:38 -0500367 char *first = words[i+1];
368 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500369 if (query->first_lineno || query->last_lineno) {
370 pr_err("match-spec:line given 2 times\n");
371 return -EINVAL;
372 }
Jason Barone9d376f2009-02-05 11:51:38 -0500373 if (last)
374 *last++ = '\0';
375 if (parse_lineno(first, &query->first_lineno) < 0)
376 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500377 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500378 /* range <first>-<last> */
Jim Cromie820874c2011-12-19 17:12:49 -0500379 if (parse_lineno(last, &query->last_lineno)
380 < query->first_lineno) {
381 pr_err("last-line < 1st-line\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500382 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500383 }
Jason Barone9d376f2009-02-05 11:51:38 -0500384 } else {
385 query->last_lineno = query->first_lineno;
386 }
387 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500388 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500389 return -EINVAL;
390 }
Jim Cromie820874c2011-12-19 17:12:49 -0500391 if (rc)
392 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500393 }
Jim Cromie574b3722011-12-19 17:13:16 -0500394 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500395 return 0;
396}
397
398/*
399 * Parse `str' as a flags specification, format [-+=][p]+.
400 * Sets up *maskp and *flagsp to be used when changing the
401 * flags fields of matched _ddebug's. Returns 0 on success
402 * or <0 on error.
403 */
404static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
405 unsigned int *maskp)
406{
407 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100408 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500409
410 switch (*str) {
411 case '+':
412 case '-':
413 case '=':
414 op = *str++;
415 break;
416 default:
417 return -EINVAL;
418 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600419 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500420
Joe Perchesf657fd22012-12-05 16:48:26 -0500421 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100422 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
423 if (*str == opt_array[i].opt_char) {
424 flags |= opt_array[i].flag;
425 break;
426 }
Jason Barone9d376f2009-02-05 11:51:38 -0500427 }
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100428 if (i < 0)
429 return -EINVAL;
Jason Barone9d376f2009-02-05 11:51:38 -0500430 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600431 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500432
433 /* calculate final *flagsp, *maskp according to mask and op */
434 switch (op) {
435 case '=':
436 *maskp = 0;
437 *flagsp = flags;
438 break;
439 case '+':
440 *maskp = ~0U;
441 *flagsp = flags;
442 break;
443 case '-':
444 *maskp = ~flags;
445 *flagsp = 0;
446 break;
447 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600448 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500449 return 0;
450}
451
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600452static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200453{
454 unsigned int flags = 0, mask = 0;
455 struct ddebug_query query;
456#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500457 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200458 char *words[MAXWORDS];
459
460 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
461 if (nwords <= 0)
462 return -EINVAL;
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600463 if (ddebug_parse_query(words, nwords-1, &query, modname))
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200464 return -EINVAL;
465 if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
466 return -EINVAL;
467
468 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500469 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500470 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500471
472 return nfound;
473}
474
475/* handle multiple queries in query string, continue on error, return
476 last error or number of matching callsites. Module name is either
477 in param (for boot arg) or perhaps in query string.
478*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600479static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500480{
481 char *split;
482 int i, errs = 0, exitcode = 0, rc, nfound = 0;
483
484 for (i = 0; query; query = split) {
485 split = strpbrk(query, ";\n");
486 if (split)
487 *split++ = '\0';
488
489 query = skip_spaces(query);
490 if (!query || !*query || *query == '#')
491 continue;
492
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600493 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500494
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600495 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500496 if (rc < 0) {
497 errs++;
498 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500499 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500500 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500501 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500502 i++;
503 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600504 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500505 i, nfound, errs);
506
507 if (exitcode)
508 return exitcode;
509 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200510}
511
Jason Baron431625d2011-10-04 14:13:19 -0700512#define PREFIX_SIZE 64
513
514static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100515{
Jason Baron431625d2011-10-04 14:13:19 -0700516 if (PREFIX_SIZE - wrote > 0)
517 return PREFIX_SIZE - wrote;
518 return 0;
519}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100520
Jason Baron431625d2011-10-04 14:13:19 -0700521static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
522{
523 int pos_after_tid;
524 int pos = 0;
525
Joe Perches798efc62012-09-12 20:11:29 -0700526 *buf = '\0';
527
Jason Baron431625d2011-10-04 14:13:19 -0700528 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100529 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700530 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100531 else
Jason Baron431625d2011-10-04 14:13:19 -0700532 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700533 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100534 }
Jason Baron431625d2011-10-04 14:13:19 -0700535 pos_after_tid = pos;
536 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
537 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700538 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700539 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
540 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700541 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700542 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500543 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700544 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700545 if (pos - pos_after_tid)
546 pos += snprintf(buf + pos, remaining(pos), " ");
547 if (pos >= PREFIX_SIZE)
548 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400549
Jason Baron431625d2011-10-04 14:13:19 -0700550 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400551}
552
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100553int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
554{
555 va_list args;
556 int res;
Jason Baron431625d2011-10-04 14:13:19 -0700557 struct va_format vaf;
558 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100559
560 BUG_ON(!descriptor);
561 BUG_ON(!fmt);
562
563 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700564
Jason Baron431625d2011-10-04 14:13:19 -0700565 vaf.fmt = fmt;
566 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700567
568 res = printk(KERN_DEBUG "%s%pV",
569 dynamic_emit_prefix(descriptor, buf), &vaf);
570
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100571 va_end(args);
572
573 return res;
574}
575EXPORT_SYMBOL(__dynamic_pr_debug);
576
Joe Perchescbc46632011-08-11 14:36:21 -0400577int __dynamic_dev_dbg(struct _ddebug *descriptor,
578 const struct device *dev, const char *fmt, ...)
579{
580 struct va_format vaf;
581 va_list args;
582 int res;
583
584 BUG_ON(!descriptor);
585 BUG_ON(!fmt);
586
587 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700588
Joe Perchescbc46632011-08-11 14:36:21 -0400589 vaf.fmt = fmt;
590 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700591
592 if (!dev) {
593 res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
594 } else {
595 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700596
Joe Perches666f3552012-09-12 20:14:11 -0700597 res = dev_printk_emit(7, dev, "%s%s %s: %pV",
598 dynamic_emit_prefix(descriptor, buf),
599 dev_driver_string(dev), dev_name(dev),
600 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700601 }
602
Joe Perchescbc46632011-08-11 14:36:21 -0400603 va_end(args);
604
605 return res;
606}
607EXPORT_SYMBOL(__dynamic_dev_dbg);
608
Jason Baron0feefd92011-10-04 14:13:22 -0700609#ifdef CONFIG_NET
610
Jason Baronffa10cb2011-08-11 14:36:48 -0400611int __dynamic_netdev_dbg(struct _ddebug *descriptor,
Joe Perchesb004ff42012-09-12 20:12:19 -0700612 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400613{
614 struct va_format vaf;
615 va_list args;
616 int res;
617
618 BUG_ON(!descriptor);
619 BUG_ON(!fmt);
620
621 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700622
Jason Baronffa10cb2011-08-11 14:36:48 -0400623 vaf.fmt = fmt;
624 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700625
626 if (dev && dev->dev.parent) {
627 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700628
Joe Perches666f3552012-09-12 20:14:11 -0700629 res = dev_printk_emit(7, dev->dev.parent,
630 "%s%s %s %s: %pV",
631 dynamic_emit_prefix(descriptor, buf),
632 dev_driver_string(dev->dev.parent),
633 dev_name(dev->dev.parent),
634 netdev_name(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700635 } else if (dev) {
636 res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
637 } else {
638 res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
639 }
640
Jason Baronffa10cb2011-08-11 14:36:48 -0400641 va_end(args);
642
643 return res;
644}
645EXPORT_SYMBOL(__dynamic_netdev_dbg);
646
Jason Baron0feefd92011-10-04 14:13:22 -0700647#endif
648
Jim Cromiebc757f62011-12-19 17:12:29 -0500649#define DDEBUG_STRING_SIZE 1024
650static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
651
Thomas Renningera648ec02010-08-06 16:11:02 +0200652static __init int ddebug_setup_query(char *str)
653{
Jim Cromiebc757f62011-12-19 17:12:29 -0500654 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400655 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200656 return 0;
657 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500658 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200659 return 1;
660}
661
662__setup("ddebug_query=", ddebug_setup_query);
663
Jason Barone9d376f2009-02-05 11:51:38 -0500664/*
665 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
666 * command text from userspace, parses and executes it.
667 */
Jim Cromie72814912011-12-19 17:13:07 -0500668#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500669static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
670 size_t len, loff_t *offp)
671{
Jim Cromie72814912011-12-19 17:13:07 -0500672 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200673 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500674
675 if (len == 0)
676 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500677 if (len > USER_BUF_PAGE - 1) {
678 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500679 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500680 }
681 tmpbuf = kmalloc(len + 1, GFP_KERNEL);
682 if (!tmpbuf)
683 return -ENOMEM;
684 if (copy_from_user(tmpbuf, ubuf, len)) {
685 kfree(tmpbuf);
Jason Barone9d376f2009-02-05 11:51:38 -0500686 return -EFAULT;
Jim Cromie72814912011-12-19 17:13:07 -0500687 }
Jason Barone9d376f2009-02-05 11:51:38 -0500688 tmpbuf[len] = '\0';
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600689 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500690
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600691 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500692 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500693 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200694 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500695
696 *offp += len;
697 return len;
698}
699
700/*
701 * Set the iterator to point to the first _ddebug object
702 * and return a pointer to that first object. Returns
703 * NULL if there are no _ddebugs at all.
704 */
705static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
706{
707 if (list_empty(&ddebug_tables)) {
708 iter->table = NULL;
709 iter->idx = 0;
710 return NULL;
711 }
712 iter->table = list_entry(ddebug_tables.next,
713 struct ddebug_table, link);
714 iter->idx = 0;
715 return &iter->table->ddebugs[iter->idx];
716}
717
718/*
719 * Advance the iterator to point to the next _ddebug
720 * object from the one the iterator currently points at,
721 * and returns a pointer to the new _ddebug. Returns
722 * NULL if the iterator has seen all the _ddebugs.
723 */
724static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
725{
726 if (iter->table == NULL)
727 return NULL;
728 if (++iter->idx == iter->table->num_ddebugs) {
729 /* iterate to next table */
730 iter->idx = 0;
731 if (list_is_last(&iter->table->link, &ddebug_tables)) {
732 iter->table = NULL;
733 return NULL;
734 }
735 iter->table = list_entry(iter->table->link.next,
736 struct ddebug_table, link);
737 }
738 return &iter->table->ddebugs[iter->idx];
739}
740
741/*
742 * Seq_ops start method. Called at the start of every
743 * read() call from userspace. Takes the ddebug_lock and
744 * seeks the seq_file's iterator to the given position.
745 */
746static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
747{
748 struct ddebug_iter *iter = m->private;
749 struct _ddebug *dp;
750 int n = *pos;
751
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600752 vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500753
754 mutex_lock(&ddebug_lock);
755
756 if (!n)
757 return SEQ_START_TOKEN;
758 if (n < 0)
759 return NULL;
760 dp = ddebug_iter_first(iter);
761 while (dp != NULL && --n > 0)
762 dp = ddebug_iter_next(iter);
763 return dp;
764}
765
766/*
767 * Seq_ops next method. Called several times within a read()
768 * call from userspace, with ddebug_lock held. Walks to the
769 * next _ddebug object with a special case for the header line.
770 */
771static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
772{
773 struct ddebug_iter *iter = m->private;
774 struct _ddebug *dp;
775
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600776 vpr_info("called m=%p p=%p *pos=%lld\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500777 m, p, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500778
779 if (p == SEQ_START_TOKEN)
780 dp = ddebug_iter_first(iter);
781 else
782 dp = ddebug_iter_next(iter);
783 ++*pos;
784 return dp;
785}
786
787/*
788 * Seq_ops show method. Called several times within a read()
789 * call from userspace, with ddebug_lock held. Formats the
790 * current _ddebug as a single human-readable line, with a
791 * special case for the header line.
792 */
793static int ddebug_proc_show(struct seq_file *m, void *p)
794{
795 struct ddebug_iter *iter = m->private;
796 struct _ddebug *dp = p;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500797 char flagsbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500798
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600799 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500800
801 if (p == SEQ_START_TOKEN) {
802 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500803 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500804 return 0;
805 }
806
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500807 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500808 trim_prefix(dp->filename), dp->lineno,
809 iter->table->mod_name, dp->function,
810 ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500811 seq_escape(m, dp->format, "\t\r\n\"");
812 seq_puts(m, "\"\n");
813
814 return 0;
815}
816
817/*
818 * Seq_ops stop method. Called at the end of each read()
819 * call from userspace. Drops ddebug_lock.
820 */
821static void ddebug_proc_stop(struct seq_file *m, void *p)
822{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600823 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500824 mutex_unlock(&ddebug_lock);
825}
826
827static const struct seq_operations ddebug_proc_seqops = {
828 .start = ddebug_proc_start,
829 .next = ddebug_proc_next,
830 .show = ddebug_proc_show,
831 .stop = ddebug_proc_stop
832};
833
834/*
Jim Cromie07100be2011-12-19 17:11:09 -0500835 * File_ops->open method for <debugfs>/dynamic_debug/control. Does
836 * the seq_file setup dance, and also creates an iterator to walk the
837 * _ddebugs. Note that we create a seq_file always, even for O_WRONLY
838 * files where it's not needed, as doing so simplifies the ->release
839 * method.
Jason Barone9d376f2009-02-05 11:51:38 -0500840 */
841static int ddebug_proc_open(struct inode *inode, struct file *file)
842{
843 struct ddebug_iter *iter;
844 int err;
845
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600846 vpr_info("called\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500847
848 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
849 if (iter == NULL)
850 return -ENOMEM;
851
852 err = seq_open(file, &ddebug_proc_seqops);
853 if (err) {
854 kfree(iter);
855 return err;
856 }
Joe Perchesf657fd22012-12-05 16:48:26 -0500857 ((struct seq_file *)file->private_data)->private = iter;
Jason Barone9d376f2009-02-05 11:51:38 -0500858 return 0;
859}
860
861static const struct file_operations ddebug_proc_fops = {
862 .owner = THIS_MODULE,
863 .open = ddebug_proc_open,
864 .read = seq_read,
865 .llseek = seq_lseek,
866 .release = seq_release_private,
867 .write = ddebug_proc_write
868};
869
870/*
871 * Allocate a new ddebug_table for the given module
872 * and add it to the global list.
873 */
874int ddebug_add_module(struct _ddebug *tab, unsigned int n,
875 const char *name)
876{
877 struct ddebug_table *dt;
878 char *new_name;
879
880 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
881 if (dt == NULL)
882 return -ENOMEM;
883 new_name = kstrdup(name, GFP_KERNEL);
884 if (new_name == NULL) {
885 kfree(dt);
886 return -ENOMEM;
887 }
888 dt->mod_name = new_name;
889 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500890 dt->ddebugs = tab;
891
892 mutex_lock(&ddebug_lock);
893 list_add_tail(&dt->link, &ddebug_tables);
894 mutex_unlock(&ddebug_lock);
895
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600896 vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500897 return 0;
898}
899EXPORT_SYMBOL_GPL(ddebug_add_module);
900
Jim Cromie6ab676e2012-04-27 14:30:37 -0600901/* helper for ddebug_dyndbg_(boot|module)_param_cb */
902static int ddebug_dyndbg_param_cb(char *param, char *val,
903 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600904{
Jim Cromieb48420c2012-04-27 14:30:35 -0600905 char *sep;
906
907 sep = strchr(param, '.');
908 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600909 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600910 *sep = '\0';
911 modname = param;
912 param = sep + 1;
913 }
914 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600915 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600916
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600917 ddebug_exec_queries((val ? val : "+p"), modname);
918
Jim Cromieb48420c2012-04-27 14:30:35 -0600919 return 0; /* query failure shouldnt stop module load */
920}
921
Jim Cromie6ab676e2012-04-27 14:30:37 -0600922/* handle both dyndbg and $module.dyndbg params at boot */
923static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
924 const char *unused)
Jim Cromieb48420c2012-04-27 14:30:35 -0600925{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600926 vpr_info("%s=\"%s\"\n", param, val);
927 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
928}
Jim Cromieb48420c2012-04-27 14:30:35 -0600929
Jim Cromie6ab676e2012-04-27 14:30:37 -0600930/*
931 * modprobe foo finds foo.params in boot-args, strips "foo.", and
932 * passes them to load_module(). This callback gets unknown params,
933 * processes dyndbg params, rejects others.
934 */
935int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
936{
937 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
938 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600939}
940
Jason Barone9d376f2009-02-05 11:51:38 -0500941static void ddebug_table_free(struct ddebug_table *dt)
942{
943 list_del_init(&dt->link);
944 kfree(dt->mod_name);
945 kfree(dt);
946}
947
948/*
949 * Called in response to a module being unloaded. Removes
950 * any ddebug_table's which point at the module.
951 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000952int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500953{
954 struct ddebug_table *dt, *nextdt;
955 int ret = -ENOENT;
956
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600957 vpr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500958
959 mutex_lock(&ddebug_lock);
960 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
961 if (!strcmp(dt->mod_name, mod_name)) {
962 ddebug_table_free(dt);
963 ret = 0;
964 }
965 }
966 mutex_unlock(&ddebug_lock);
967 return ret;
968}
969EXPORT_SYMBOL_GPL(ddebug_remove_module);
970
971static void ddebug_remove_all_tables(void)
972{
973 mutex_lock(&ddebug_lock);
974 while (!list_empty(&ddebug_tables)) {
975 struct ddebug_table *dt = list_entry(ddebug_tables.next,
976 struct ddebug_table,
977 link);
978 ddebug_table_free(dt);
979 }
980 mutex_unlock(&ddebug_lock);
981}
982
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200983static __initdata int ddebug_init_success;
984
985static int __init dynamic_debug_init_debugfs(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500986{
987 struct dentry *dir, *file;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200988
989 if (!ddebug_init_success)
990 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -0500991
992 dir = debugfs_create_dir("dynamic_debug", NULL);
993 if (!dir)
994 return -ENOMEM;
995 file = debugfs_create_file("control", 0644, dir, NULL,
996 &ddebug_proc_fops);
997 if (!file) {
998 debugfs_remove(dir);
999 return -ENOMEM;
1000 }
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001001 return 0;
1002}
1003
1004static int __init dynamic_debug_init(void)
1005{
1006 struct _ddebug *iter, *iter_start;
1007 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001008 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001009 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001010 int n = 0, entries = 0, modct = 0;
1011 int verbose_bytes = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001012
Jim Cromieb5b78f82011-12-19 17:12:54 -05001013 if (__start___verbose == __stop___verbose) {
Joe Perchesf657fd22012-12-05 16:48:26 -05001014 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
Jim Cromieb5b78f82011-12-19 17:12:54 -05001015 return 1;
Jason Barone9d376f2009-02-05 11:51:38 -05001016 }
Jim Cromieb5b78f82011-12-19 17:12:54 -05001017 iter = __start___verbose;
1018 modname = iter->modname;
1019 iter_start = iter;
1020 for (; iter < __stop___verbose; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001021 entries++;
1022 verbose_bytes += strlen(iter->modname) + strlen(iter->function)
1023 + strlen(iter->filename) + strlen(iter->format);
1024
Jim Cromieb5b78f82011-12-19 17:12:54 -05001025 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001026 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001027 ret = ddebug_add_module(iter_start, n, modname);
1028 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001029 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001030 n = 0;
1031 modname = iter->modname;
1032 iter_start = iter;
1033 }
1034 n++;
1035 }
1036 ret = ddebug_add_module(iter_start, n, modname);
1037 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001038 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001039
Jim Cromieaf442392012-04-27 14:30:38 -06001040 ddebug_init_success = 1;
Joe Perchesf657fd22012-12-05 16:48:26 -05001041 vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
1042 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
1043 verbose_bytes + (int)(__stop___verbose - __start___verbose));
Jim Cromieaf442392012-04-27 14:30:38 -06001044
1045 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001046 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001047 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001048 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001049 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001050 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001051 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001052 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001053 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001054 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001055 /* now that ddebug tables are loaded, process all boot args
1056 * again to find and activate queries given in dyndbg params.
1057 * While this has already been done for known boot params, it
1058 * ignored the unknown ones (dyndbg in particular). Reusing
1059 * parse_args avoids ad-hoc parsing. This will also attempt
1060 * to activate queries for not-yet-loaded modules, which is
1061 * slightly noisy if verbose, but harmless.
1062 */
1063 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1064 parse_args("dyndbg params", cmdline, NULL,
1065 0, 0, 0, &ddebug_dyndbg_boot_param_cb);
1066 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001067 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001068
Jim Cromieaf442392012-04-27 14:30:38 -06001069out_err:
1070 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001071 return 0;
1072}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001073/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001074early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001075
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001076/* Debugfs setup must be done later */
Jim Cromie3ec56522012-04-27 14:30:42 -06001077fs_initcall(dynamic_debug_init_debugfs);