blob: 46032453abd50cfcfcc4ce277e8f8ec2d34fffc3 [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 Assche8ba6ebf2011-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 Assche8ba6ebf2011-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 Assche8ba6ebf2011-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 Assche8ba6ebf2011-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 Assche8ba6ebf2011-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 Assche8ba6ebf2011-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 ;
Jim Cromie18c216c2012-12-05 16:48:27 -0500226 if (!*end) {
227 pr_err("unclosed quote: %s\n", buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100228 return -EINVAL; /* unclosed quote */
Jim Cromie18c216c2012-12-05 16:48:27 -0500229 }
Greg Banks9898abb2009-02-06 12:54:26 +1100230 } else {
Joe Perchesf657fd22012-12-05 16:48:26 -0500231 for (end = buf; *end && !isspace(*end); end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100232 ;
233 BUG_ON(end == buf);
234 }
Greg Banks9898abb2009-02-06 12:54:26 +1100235
Jim Cromie07100be2011-12-19 17:11:09 -0500236 /* `buf' is start of word, `end' is one past its end */
Jim Cromie18c216c2012-12-05 16:48:27 -0500237 if (nwords == maxwords) {
238 pr_err("too many words, legal max <=%d\n", maxwords);
Greg Banks9898abb2009-02-06 12:54:26 +1100239 return -EINVAL; /* ran out of words[] before bytes */
Jim Cromie18c216c2012-12-05 16:48:27 -0500240 }
Greg Banks9898abb2009-02-06 12:54:26 +1100241 if (*end)
242 *end++ = '\0'; /* terminate the word */
243 words[nwords++] = buf;
244 buf = end;
245 }
Jason Barone9d376f2009-02-05 11:51:38 -0500246
247 if (verbose) {
248 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400249 pr_info("split into words:");
Joe Perchesf657fd22012-12-05 16:48:26 -0500250 for (i = 0; i < nwords; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400251 pr_cont(" \"%s\"", words[i]);
252 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500253 }
254
255 return nwords;
256}
257
258/*
259 * Parse a single line number. Note that the empty string ""
260 * is treated as a special case and converted to zero, which
261 * is later treated as a "don't care" value.
262 */
263static inline int parse_lineno(const char *str, unsigned int *val)
264{
265 char *end = NULL;
266 BUG_ON(str == NULL);
267 if (*str == '\0') {
268 *val = 0;
269 return 0;
270 }
271 *val = simple_strtoul(str, &end, 10);
Jim Cromie18c216c2012-12-05 16:48:27 -0500272 if (end == NULL || end == str || *end != '\0') {
273 pr_err("bad line-number: %s\n", str);
274 return -EINVAL;
275 }
276 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500277}
278
279/*
280 * Undo octal escaping in a string, inplace. This is useful to
281 * allow the user to express a query which matches a format
282 * containing embedded spaces.
283 */
Jason Barone9d376f2009-02-05 11:51:38 -0500284static char *unescape(char *str)
285{
286 char *in = str;
287 char *out = str;
288
289 while (*in) {
290 if (*in == '\\') {
291 if (in[1] == '\\') {
292 *out++ = '\\';
293 in += 2;
294 continue;
295 } else if (in[1] == 't') {
296 *out++ = '\t';
297 in += 2;
298 continue;
299 } else if (in[1] == 'n') {
300 *out++ = '\n';
301 in += 2;
302 continue;
303 } else if (isodigit(in[1]) &&
Joe Perchesf657fd22012-12-05 16:48:26 -0500304 isodigit(in[2]) &&
305 isodigit(in[3])) {
306 *out++ = (((in[1] - '0') << 6) |
307 ((in[2] - '0') << 3) |
308 (in[3] - '0'));
Jason Barone9d376f2009-02-05 11:51:38 -0500309 in += 4;
310 continue;
311 }
312 }
313 *out++ = *in++;
314 }
315 *out = '\0';
316
317 return str;
318}
319
Jim Cromie820874c2011-12-19 17:12:49 -0500320static int check_set(const char **dest, char *src, char *name)
321{
322 int rc = 0;
323
324 if (*dest) {
325 rc = -EINVAL;
Joe Perchesf657fd22012-12-05 16:48:26 -0500326 pr_err("match-spec:%s val:%s overridden by %s\n",
327 name, *dest, src);
Jim Cromie820874c2011-12-19 17:12:49 -0500328 }
329 *dest = src;
330 return rc;
331}
332
Jason Barone9d376f2009-02-05 11:51:38 -0500333/*
334 * Parse words[] as a ddebug query specification, which is a series
335 * of (keyword, value) pairs chosen from these possibilities:
336 *
337 * func <function-name>
338 * file <full-pathname>
339 * file <base-filename>
340 * module <module-name>
341 * format <escaped-string-to-find-in-format>
342 * line <lineno>
343 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500344 *
345 * Only 1 of each type is allowed.
346 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500347 */
348static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600349 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500350{
351 unsigned int i;
Jim Cromie820874c2011-12-19 17:12:49 -0500352 int rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500353
354 /* check we have an even number of words */
Jim Cromie18c216c2012-12-05 16:48:27 -0500355 if (nwords % 2 != 0) {
356 pr_err("expecting pairs of match-spec <value>\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500357 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500358 }
Jason Barone9d376f2009-02-05 11:51:38 -0500359 memset(query, 0, sizeof(*query));
360
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600361 if (modname)
362 /* support $modname.dyndbg=<multiple queries> */
363 query->module = modname;
364
Joe Perchesf657fd22012-12-05 16:48:26 -0500365 for (i = 0; i < nwords; i += 2) {
366 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500367 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500368 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500369 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500370 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500371 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500372 } else if (!strcmp(words[i], "format")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500373 rc = check_set(&query->format, unescape(words[i+1]),
Joe Perchesf657fd22012-12-05 16:48:26 -0500374 "format");
375 } else if (!strcmp(words[i], "line")) {
Jason Barone9d376f2009-02-05 11:51:38 -0500376 char *first = words[i+1];
377 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500378 if (query->first_lineno || query->last_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500379 pr_err("match-spec: line used 2x\n");
Jim Cromie820874c2011-12-19 17:12:49 -0500380 return -EINVAL;
381 }
Jason Barone9d376f2009-02-05 11:51:38 -0500382 if (last)
383 *last++ = '\0';
Jim Cromie18c216c2012-12-05 16:48:27 -0500384 if (parse_lineno(first, &query->first_lineno) < 0) {
385 pr_err("line-number is <0\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500386 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500387 }
Jim Cromie820874c2011-12-19 17:12:49 -0500388 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500389 /* range <first>-<last> */
Jim Cromie820874c2011-12-19 17:12:49 -0500390 if (parse_lineno(last, &query->last_lineno)
391 < query->first_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500392 pr_err("last-line:%d < 1st-line:%d\n",
393 query->last_lineno,
394 query->first_lineno);
Jason Barone9d376f2009-02-05 11:51:38 -0500395 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500396 }
Jason Barone9d376f2009-02-05 11:51:38 -0500397 } else {
398 query->last_lineno = query->first_lineno;
399 }
400 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500401 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500402 return -EINVAL;
403 }
Jim Cromie820874c2011-12-19 17:12:49 -0500404 if (rc)
405 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500406 }
Jim Cromie574b3722011-12-19 17:13:16 -0500407 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500408 return 0;
409}
410
411/*
412 * Parse `str' as a flags specification, format [-+=][p]+.
413 * Sets up *maskp and *flagsp to be used when changing the
414 * flags fields of matched _ddebug's. Returns 0 on success
415 * or <0 on error.
416 */
417static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
418 unsigned int *maskp)
419{
420 unsigned flags = 0;
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100421 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500422
423 switch (*str) {
424 case '+':
425 case '-':
426 case '=':
427 op = *str++;
428 break;
429 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500430 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500431 return -EINVAL;
432 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600433 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500434
Joe Perchesf657fd22012-12-05 16:48:26 -0500435 for (; *str ; ++str) {
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100436 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
437 if (*str == opt_array[i].opt_char) {
438 flags |= opt_array[i].flag;
439 break;
440 }
Jason Barone9d376f2009-02-05 11:51:38 -0500441 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500442 if (i < 0) {
443 pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100444 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500445 }
Jason Barone9d376f2009-02-05 11:51:38 -0500446 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600447 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500448
449 /* calculate final *flagsp, *maskp according to mask and op */
450 switch (op) {
451 case '=':
452 *maskp = 0;
453 *flagsp = flags;
454 break;
455 case '+':
456 *maskp = ~0U;
457 *flagsp = flags;
458 break;
459 case '-':
460 *maskp = ~flags;
461 *flagsp = 0;
462 break;
463 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600464 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500465 return 0;
466}
467
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600468static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200469{
470 unsigned int flags = 0, mask = 0;
471 struct ddebug_query query;
472#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500473 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200474 char *words[MAXWORDS];
475
476 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500477 if (nwords <= 0) {
478 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200479 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500480 }
481 /* check flags 1st (last arg) so query is pairs of spec,val */
482 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
483 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200484 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500485 }
486 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
487 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200488 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500489 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200490 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500491 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500492 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500493
494 return nfound;
495}
496
497/* handle multiple queries in query string, continue on error, return
498 last error or number of matching callsites. Module name is either
499 in param (for boot arg) or perhaps in query string.
500*/
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600501static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500502{
503 char *split;
504 int i, errs = 0, exitcode = 0, rc, nfound = 0;
505
506 for (i = 0; query; query = split) {
507 split = strpbrk(query, ";\n");
508 if (split)
509 *split++ = '\0';
510
511 query = skip_spaces(query);
512 if (!query || !*query || *query == '#')
513 continue;
514
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600515 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500516
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600517 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500518 if (rc < 0) {
519 errs++;
520 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500521 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500522 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500523 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500524 i++;
525 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600526 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500527 i, nfound, errs);
528
529 if (exitcode)
530 return exitcode;
531 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200532}
533
Jason Baron431625d2011-10-04 14:13:19 -0700534#define PREFIX_SIZE 64
535
536static int remaining(int wrote)
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100537{
Jason Baron431625d2011-10-04 14:13:19 -0700538 if (PREFIX_SIZE - wrote > 0)
539 return PREFIX_SIZE - wrote;
540 return 0;
541}
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100542
Jason Baron431625d2011-10-04 14:13:19 -0700543static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
544{
545 int pos_after_tid;
546 int pos = 0;
547
Joe Perches798efc62012-09-12 20:11:29 -0700548 *buf = '\0';
549
Jason Baron431625d2011-10-04 14:13:19 -0700550 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100551 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700552 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100553 else
Jason Baron431625d2011-10-04 14:13:19 -0700554 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700555 task_pid_vnr(current));
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100556 }
Jason Baron431625d2011-10-04 14:13:19 -0700557 pos_after_tid = pos;
558 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
559 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700560 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700561 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
562 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700563 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700564 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500565 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700566 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700567 if (pos - pos_after_tid)
568 pos += snprintf(buf + pos, remaining(pos), " ");
569 if (pos >= PREFIX_SIZE)
570 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400571
Jason Baron431625d2011-10-04 14:13:19 -0700572 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400573}
574
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100575int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
576{
577 va_list args;
578 int res;
Jason Baron431625d2011-10-04 14:13:19 -0700579 struct va_format vaf;
580 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100581
582 BUG_ON(!descriptor);
583 BUG_ON(!fmt);
584
585 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700586
Jason Baron431625d2011-10-04 14:13:19 -0700587 vaf.fmt = fmt;
588 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700589
590 res = printk(KERN_DEBUG "%s%pV",
591 dynamic_emit_prefix(descriptor, buf), &vaf);
592
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100593 va_end(args);
594
595 return res;
596}
597EXPORT_SYMBOL(__dynamic_pr_debug);
598
Joe Perchescbc46632011-08-11 14:36:21 -0400599int __dynamic_dev_dbg(struct _ddebug *descriptor,
600 const struct device *dev, const char *fmt, ...)
601{
602 struct va_format vaf;
603 va_list args;
604 int res;
605
606 BUG_ON(!descriptor);
607 BUG_ON(!fmt);
608
609 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700610
Joe Perchescbc46632011-08-11 14:36:21 -0400611 vaf.fmt = fmt;
612 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700613
614 if (!dev) {
615 res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
616 } else {
617 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700618
Joe Perches666f3552012-09-12 20:14:11 -0700619 res = dev_printk_emit(7, dev, "%s%s %s: %pV",
620 dynamic_emit_prefix(descriptor, buf),
621 dev_driver_string(dev), dev_name(dev),
622 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700623 }
624
Joe Perchescbc46632011-08-11 14:36:21 -0400625 va_end(args);
626
627 return res;
628}
629EXPORT_SYMBOL(__dynamic_dev_dbg);
630
Jason Baron0feefd92011-10-04 14:13:22 -0700631#ifdef CONFIG_NET
632
Jason Baronffa10cb2011-08-11 14:36:48 -0400633int __dynamic_netdev_dbg(struct _ddebug *descriptor,
Joe Perchesb004ff42012-09-12 20:12:19 -0700634 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400635{
636 struct va_format vaf;
637 va_list args;
638 int res;
639
640 BUG_ON(!descriptor);
641 BUG_ON(!fmt);
642
643 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700644
Jason Baronffa10cb2011-08-11 14:36:48 -0400645 vaf.fmt = fmt;
646 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700647
648 if (dev && dev->dev.parent) {
649 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700650
Joe Perches666f3552012-09-12 20:14:11 -0700651 res = dev_printk_emit(7, dev->dev.parent,
652 "%s%s %s %s: %pV",
653 dynamic_emit_prefix(descriptor, buf),
654 dev_driver_string(dev->dev.parent),
655 dev_name(dev->dev.parent),
656 netdev_name(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700657 } else if (dev) {
658 res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
659 } else {
660 res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
661 }
662
Jason Baronffa10cb2011-08-11 14:36:48 -0400663 va_end(args);
664
665 return res;
666}
667EXPORT_SYMBOL(__dynamic_netdev_dbg);
668
Jason Baron0feefd92011-10-04 14:13:22 -0700669#endif
670
Jim Cromiebc757f62011-12-19 17:12:29 -0500671#define DDEBUG_STRING_SIZE 1024
672static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
673
Thomas Renningera648ec02010-08-06 16:11:02 +0200674static __init int ddebug_setup_query(char *str)
675{
Jim Cromiebc757f62011-12-19 17:12:29 -0500676 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400677 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200678 return 0;
679 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500680 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200681 return 1;
682}
683
684__setup("ddebug_query=", ddebug_setup_query);
685
Jason Barone9d376f2009-02-05 11:51:38 -0500686/*
687 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
688 * command text from userspace, parses and executes it.
689 */
Jim Cromie72814912011-12-19 17:13:07 -0500690#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500691static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
692 size_t len, loff_t *offp)
693{
Jim Cromie72814912011-12-19 17:13:07 -0500694 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200695 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500696
697 if (len == 0)
698 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500699 if (len > USER_BUF_PAGE - 1) {
700 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500701 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500702 }
703 tmpbuf = kmalloc(len + 1, GFP_KERNEL);
704 if (!tmpbuf)
705 return -ENOMEM;
706 if (copy_from_user(tmpbuf, ubuf, len)) {
707 kfree(tmpbuf);
Jason Barone9d376f2009-02-05 11:51:38 -0500708 return -EFAULT;
Jim Cromie72814912011-12-19 17:13:07 -0500709 }
Jason Barone9d376f2009-02-05 11:51:38 -0500710 tmpbuf[len] = '\0';
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600711 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500712
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600713 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500714 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500715 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200716 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500717
718 *offp += len;
719 return len;
720}
721
722/*
723 * Set the iterator to point to the first _ddebug object
724 * and return a pointer to that first object. Returns
725 * NULL if there are no _ddebugs at all.
726 */
727static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
728{
729 if (list_empty(&ddebug_tables)) {
730 iter->table = NULL;
731 iter->idx = 0;
732 return NULL;
733 }
734 iter->table = list_entry(ddebug_tables.next,
735 struct ddebug_table, link);
736 iter->idx = 0;
737 return &iter->table->ddebugs[iter->idx];
738}
739
740/*
741 * Advance the iterator to point to the next _ddebug
742 * object from the one the iterator currently points at,
743 * and returns a pointer to the new _ddebug. Returns
744 * NULL if the iterator has seen all the _ddebugs.
745 */
746static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
747{
748 if (iter->table == NULL)
749 return NULL;
750 if (++iter->idx == iter->table->num_ddebugs) {
751 /* iterate to next table */
752 iter->idx = 0;
753 if (list_is_last(&iter->table->link, &ddebug_tables)) {
754 iter->table = NULL;
755 return NULL;
756 }
757 iter->table = list_entry(iter->table->link.next,
758 struct ddebug_table, link);
759 }
760 return &iter->table->ddebugs[iter->idx];
761}
762
763/*
764 * Seq_ops start method. Called at the start of every
765 * read() call from userspace. Takes the ddebug_lock and
766 * seeks the seq_file's iterator to the given position.
767 */
768static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
769{
770 struct ddebug_iter *iter = m->private;
771 struct _ddebug *dp;
772 int n = *pos;
773
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600774 vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500775
776 mutex_lock(&ddebug_lock);
777
778 if (!n)
779 return SEQ_START_TOKEN;
780 if (n < 0)
781 return NULL;
782 dp = ddebug_iter_first(iter);
783 while (dp != NULL && --n > 0)
784 dp = ddebug_iter_next(iter);
785 return dp;
786}
787
788/*
789 * Seq_ops next method. Called several times within a read()
790 * call from userspace, with ddebug_lock held. Walks to the
791 * next _ddebug object with a special case for the header line.
792 */
793static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
794{
795 struct ddebug_iter *iter = m->private;
796 struct _ddebug *dp;
797
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600798 vpr_info("called m=%p p=%p *pos=%lld\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500799 m, p, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500800
801 if (p == SEQ_START_TOKEN)
802 dp = ddebug_iter_first(iter);
803 else
804 dp = ddebug_iter_next(iter);
805 ++*pos;
806 return dp;
807}
808
809/*
810 * Seq_ops show method. Called several times within a read()
811 * call from userspace, with ddebug_lock held. Formats the
812 * current _ddebug as a single human-readable line, with a
813 * special case for the header line.
814 */
815static int ddebug_proc_show(struct seq_file *m, void *p)
816{
817 struct ddebug_iter *iter = m->private;
818 struct _ddebug *dp = p;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500819 char flagsbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500820
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600821 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500822
823 if (p == SEQ_START_TOKEN) {
824 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500825 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500826 return 0;
827 }
828
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500829 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500830 trim_prefix(dp->filename), dp->lineno,
831 iter->table->mod_name, dp->function,
832 ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500833 seq_escape(m, dp->format, "\t\r\n\"");
834 seq_puts(m, "\"\n");
835
836 return 0;
837}
838
839/*
840 * Seq_ops stop method. Called at the end of each read()
841 * call from userspace. Drops ddebug_lock.
842 */
843static void ddebug_proc_stop(struct seq_file *m, void *p)
844{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600845 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500846 mutex_unlock(&ddebug_lock);
847}
848
849static const struct seq_operations ddebug_proc_seqops = {
850 .start = ddebug_proc_start,
851 .next = ddebug_proc_next,
852 .show = ddebug_proc_show,
853 .stop = ddebug_proc_stop
854};
855
856/*
Jim Cromie07100be2011-12-19 17:11:09 -0500857 * File_ops->open method for <debugfs>/dynamic_debug/control. Does
858 * the seq_file setup dance, and also creates an iterator to walk the
859 * _ddebugs. Note that we create a seq_file always, even for O_WRONLY
860 * files where it's not needed, as doing so simplifies the ->release
861 * method.
Jason Barone9d376f2009-02-05 11:51:38 -0500862 */
863static int ddebug_proc_open(struct inode *inode, struct file *file)
864{
865 struct ddebug_iter *iter;
866 int err;
867
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600868 vpr_info("called\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500869
870 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
871 if (iter == NULL)
872 return -ENOMEM;
873
874 err = seq_open(file, &ddebug_proc_seqops);
875 if (err) {
876 kfree(iter);
877 return err;
878 }
Joe Perchesf657fd22012-12-05 16:48:26 -0500879 ((struct seq_file *)file->private_data)->private = iter;
Jason Barone9d376f2009-02-05 11:51:38 -0500880 return 0;
881}
882
883static const struct file_operations ddebug_proc_fops = {
884 .owner = THIS_MODULE,
885 .open = ddebug_proc_open,
886 .read = seq_read,
887 .llseek = seq_lseek,
888 .release = seq_release_private,
889 .write = ddebug_proc_write
890};
891
892/*
893 * Allocate a new ddebug_table for the given module
894 * and add it to the global list.
895 */
896int ddebug_add_module(struct _ddebug *tab, unsigned int n,
897 const char *name)
898{
899 struct ddebug_table *dt;
900 char *new_name;
901
902 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
903 if (dt == NULL)
904 return -ENOMEM;
905 new_name = kstrdup(name, GFP_KERNEL);
906 if (new_name == NULL) {
907 kfree(dt);
908 return -ENOMEM;
909 }
910 dt->mod_name = new_name;
911 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500912 dt->ddebugs = tab;
913
914 mutex_lock(&ddebug_lock);
915 list_add_tail(&dt->link, &ddebug_tables);
916 mutex_unlock(&ddebug_lock);
917
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600918 vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500919 return 0;
920}
921EXPORT_SYMBOL_GPL(ddebug_add_module);
922
Jim Cromie6ab676e2012-04-27 14:30:37 -0600923/* helper for ddebug_dyndbg_(boot|module)_param_cb */
924static int ddebug_dyndbg_param_cb(char *param, char *val,
925 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600926{
Jim Cromieb48420c2012-04-27 14:30:35 -0600927 char *sep;
928
929 sep = strchr(param, '.');
930 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600931 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600932 *sep = '\0';
933 modname = param;
934 param = sep + 1;
935 }
936 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600937 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600938
Jim Cromie8e59b5c2012-04-27 14:30:40 -0600939 ddebug_exec_queries((val ? val : "+p"), modname);
940
Jim Cromieb48420c2012-04-27 14:30:35 -0600941 return 0; /* query failure shouldnt stop module load */
942}
943
Jim Cromie6ab676e2012-04-27 14:30:37 -0600944/* handle both dyndbg and $module.dyndbg params at boot */
945static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
946 const char *unused)
Jim Cromieb48420c2012-04-27 14:30:35 -0600947{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600948 vpr_info("%s=\"%s\"\n", param, val);
949 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
950}
Jim Cromieb48420c2012-04-27 14:30:35 -0600951
Jim Cromie6ab676e2012-04-27 14:30:37 -0600952/*
953 * modprobe foo finds foo.params in boot-args, strips "foo.", and
954 * passes them to load_module(). This callback gets unknown params,
955 * processes dyndbg params, rejects others.
956 */
957int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
958{
959 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
960 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600961}
962
Jason Barone9d376f2009-02-05 11:51:38 -0500963static void ddebug_table_free(struct ddebug_table *dt)
964{
965 list_del_init(&dt->link);
966 kfree(dt->mod_name);
967 kfree(dt);
968}
969
970/*
971 * Called in response to a module being unloaded. Removes
972 * any ddebug_table's which point at the module.
973 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000974int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500975{
976 struct ddebug_table *dt, *nextdt;
977 int ret = -ENOENT;
978
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600979 vpr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500980
981 mutex_lock(&ddebug_lock);
982 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
983 if (!strcmp(dt->mod_name, mod_name)) {
984 ddebug_table_free(dt);
985 ret = 0;
986 }
987 }
988 mutex_unlock(&ddebug_lock);
989 return ret;
990}
991EXPORT_SYMBOL_GPL(ddebug_remove_module);
992
993static void ddebug_remove_all_tables(void)
994{
995 mutex_lock(&ddebug_lock);
996 while (!list_empty(&ddebug_tables)) {
997 struct ddebug_table *dt = list_entry(ddebug_tables.next,
998 struct ddebug_table,
999 link);
1000 ddebug_table_free(dt);
1001 }
1002 mutex_unlock(&ddebug_lock);
1003}
1004
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001005static __initdata int ddebug_init_success;
1006
1007static int __init dynamic_debug_init_debugfs(void)
Jason Barone9d376f2009-02-05 11:51:38 -05001008{
1009 struct dentry *dir, *file;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001010
1011 if (!ddebug_init_success)
1012 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -05001013
1014 dir = debugfs_create_dir("dynamic_debug", NULL);
1015 if (!dir)
1016 return -ENOMEM;
1017 file = debugfs_create_file("control", 0644, dir, NULL,
1018 &ddebug_proc_fops);
1019 if (!file) {
1020 debugfs_remove(dir);
1021 return -ENOMEM;
1022 }
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001023 return 0;
1024}
1025
1026static int __init dynamic_debug_init(void)
1027{
1028 struct _ddebug *iter, *iter_start;
1029 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001030 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001031 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001032 int n = 0, entries = 0, modct = 0;
1033 int verbose_bytes = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001034
Jim Cromieb5b78f82011-12-19 17:12:54 -05001035 if (__start___verbose == __stop___verbose) {
Joe Perchesf657fd22012-12-05 16:48:26 -05001036 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
Jim Cromieb5b78f82011-12-19 17:12:54 -05001037 return 1;
Jason Barone9d376f2009-02-05 11:51:38 -05001038 }
Jim Cromieb5b78f82011-12-19 17:12:54 -05001039 iter = __start___verbose;
1040 modname = iter->modname;
1041 iter_start = iter;
1042 for (; iter < __stop___verbose; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001043 entries++;
1044 verbose_bytes += strlen(iter->modname) + strlen(iter->function)
1045 + strlen(iter->filename) + strlen(iter->format);
1046
Jim Cromieb5b78f82011-12-19 17:12:54 -05001047 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001048 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001049 ret = ddebug_add_module(iter_start, n, modname);
1050 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001051 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001052 n = 0;
1053 modname = iter->modname;
1054 iter_start = iter;
1055 }
1056 n++;
1057 }
1058 ret = ddebug_add_module(iter_start, n, modname);
1059 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001060 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001061
Jim Cromieaf442392012-04-27 14:30:38 -06001062 ddebug_init_success = 1;
Joe Perchesf657fd22012-12-05 16:48:26 -05001063 vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
1064 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
1065 verbose_bytes + (int)(__stop___verbose - __start___verbose));
Jim Cromieaf442392012-04-27 14:30:38 -06001066
1067 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001068 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001069 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5c2012-04-27 14:30:40 -06001070 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001071 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001072 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001073 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001074 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001075 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001076 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001077 /* now that ddebug tables are loaded, process all boot args
1078 * again to find and activate queries given in dyndbg params.
1079 * While this has already been done for known boot params, it
1080 * ignored the unknown ones (dyndbg in particular). Reusing
1081 * parse_args avoids ad-hoc parsing. This will also attempt
1082 * to activate queries for not-yet-loaded modules, which is
1083 * slightly noisy if verbose, but harmless.
1084 */
1085 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1086 parse_args("dyndbg params", cmdline, NULL,
1087 0, 0, 0, &ddebug_dyndbg_boot_param_cb);
1088 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001089 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001090
Jim Cromieaf442392012-04-27 14:30:38 -06001091out_err:
1092 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001093 return 0;
1094}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001095/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001096early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001097
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001098/* Debugfs setup must be done later */
Jim Cromie3ec56522012-04-27 14:30:42 -06001099fs_initcall(dynamic_debug_init_debugfs);