blob: 99fec3ae405aa2e785c66605044d715633b894ac [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>
Andy Shevchenkod338b132013-04-30 15:27:32 -070027#include <linux/string_helpers.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070028#include <linux/uaccess.h>
Jason Barone9d376f2009-02-05 11:51:38 -050029#include <linux/dynamic_debug.h>
30#include <linux/debugfs.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090031#include <linux/slab.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070032#include <linux/jump_label.h>
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +010033#include <linux/hardirq.h>
Greg Kroah-Hartmane8d97922011-02-03 15:59:58 -080034#include <linux/sched.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070035#include <linux/device.h>
Jason Baronffa10cb2011-08-11 14:36:48 -040036#include <linux/netdevice.h>
Jason Barone9d376f2009-02-05 11:51:38 -050037
38extern struct _ddebug __start___verbose[];
39extern struct _ddebug __stop___verbose[];
40
Jason Barone9d376f2009-02-05 11:51:38 -050041struct ddebug_table {
42 struct list_head link;
43 char *mod_name;
44 unsigned int num_ddebugs;
Jason Barone9d376f2009-02-05 11:51:38 -050045 struct _ddebug *ddebugs;
46};
47
48struct ddebug_query {
49 const char *filename;
50 const char *module;
51 const char *function;
52 const char *format;
53 unsigned int first_lineno, last_lineno;
54};
55
56struct ddebug_iter {
57 struct ddebug_table *table;
58 unsigned int idx;
59};
60
61static DEFINE_MUTEX(ddebug_lock);
62static LIST_HEAD(ddebug_tables);
Joe Perchesf657fd22012-12-05 16:48:26 -050063static int verbose;
Jim Cromie74df1382011-12-19 17:12:24 -050064module_param(verbose, int, 0644);
Jason Barone9d376f2009-02-05 11:51:38 -050065
Jim Cromie2b678312011-12-19 17:13:12 -050066/* Return the path relative to source root */
67static inline const char *trim_prefix(const char *path)
68{
69 int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
70
71 if (strncmp(path, __FILE__, skip))
72 skip = 0; /* prefix mismatch, don't skip */
73
74 return path + skip;
75}
76
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +010077static struct { unsigned flag:8; char opt_char; } opt_array[] = {
78 { _DPRINTK_FLAGS_PRINT, 'p' },
79 { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
80 { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
81 { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
82 { _DPRINTK_FLAGS_INCL_TID, 't' },
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050083 { _DPRINTK_FLAGS_NONE, '_' },
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +010084};
85
Jason Barone9d376f2009-02-05 11:51:38 -050086/* format a string into buf[] which describes the _ddebug's flags */
87static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
88 size_t maxlen)
89{
90 char *p = buf;
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +010091 int i;
Jason Barone9d376f2009-02-05 11:51:38 -050092
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050093 BUG_ON(maxlen < 6);
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +010094 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
95 if (dp->flags & opt_array[i].flag)
96 *p++ = opt_array[i].opt_char;
Jason Barone9d376f2009-02-05 11:51:38 -050097 if (p == buf)
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050098 *p++ = '_';
Jason Barone9d376f2009-02-05 11:51:38 -050099 *p = '\0';
100
101 return buf;
102}
103
Joe Perchesf657fd22012-12-05 16:48:26 -0500104#define vpr_info(fmt, ...) \
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600105do { \
Joe Perchesf657fd22012-12-05 16:48:26 -0500106 if (verbose) \
107 pr_info(fmt, ##__VA_ARGS__); \
Jim Cromie574b3722011-12-19 17:13:16 -0500108} while (0)
109
Joe Perchesf657fd22012-12-05 16:48:26 -0500110static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
111{
112 /* trim any trailing newlines */
113 int fmtlen = 0;
114
115 if (query->format) {
116 fmtlen = strlen(query->format);
117 while (fmtlen && query->format[fmtlen - 1] == '\n')
118 fmtlen--;
119 }
120
121 vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
122 msg,
123 query->function ? query->function : "",
124 query->filename ? query->filename : "",
125 query->module ? query->module : "",
126 fmtlen, query->format ? query->format : "",
127 query->first_lineno, query->last_lineno);
128}
129
Jason Barone9d376f2009-02-05 11:51:38 -0500130/*
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500131 * Search the tables for _ddebug's which match the given `query' and
132 * apply the `flags' and `mask' to them. Returns number of matching
133 * callsites, normally the same as number of changes. If verbose,
134 * logs the changes. Takes ddebug_lock.
Jason Barone9d376f2009-02-05 11:51:38 -0500135 */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500136static int ddebug_change(const struct ddebug_query *query,
137 unsigned int flags, unsigned int mask)
Jason Barone9d376f2009-02-05 11:51:38 -0500138{
139 int i;
140 struct ddebug_table *dt;
141 unsigned int newflags;
142 unsigned int nfound = 0;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500143 char flagbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500144
145 /* search for matching ddebugs */
146 mutex_lock(&ddebug_lock);
147 list_for_each_entry(dt, &ddebug_tables, link) {
148
149 /* match against the module name */
Jim Cromied6a238d2011-12-19 17:12:39 -0500150 if (query->module && strcmp(query->module, dt->mod_name))
Jason Barone9d376f2009-02-05 11:51:38 -0500151 continue;
152
Joe Perchesf657fd22012-12-05 16:48:26 -0500153 for (i = 0; i < dt->num_ddebugs; i++) {
Jason Barone9d376f2009-02-05 11:51:38 -0500154 struct _ddebug *dp = &dt->ddebugs[i];
155
156 /* match against the source filename */
Jim Cromied6a238d2011-12-19 17:12:39 -0500157 if (query->filename &&
Jason Barone9d376f2009-02-05 11:51:38 -0500158 strcmp(query->filename, dp->filename) &&
Andy Shevchenko35367ab2012-12-17 16:01:21 -0800159 strcmp(query->filename, kbasename(dp->filename)) &&
Jim Cromie2b678312011-12-19 17:13:12 -0500160 strcmp(query->filename, trim_prefix(dp->filename)))
Jason Barone9d376f2009-02-05 11:51:38 -0500161 continue;
162
163 /* match against the function */
Jim Cromied6a238d2011-12-19 17:12:39 -0500164 if (query->function &&
Jason Barone9d376f2009-02-05 11:51:38 -0500165 strcmp(query->function, dp->function))
166 continue;
167
168 /* match against the format */
Jim Cromied6a238d2011-12-19 17:12:39 -0500169 if (query->format &&
170 !strstr(dp->format, query->format))
Jason Barone9d376f2009-02-05 11:51:38 -0500171 continue;
172
173 /* match against the line number range */
174 if (query->first_lineno &&
175 dp->lineno < query->first_lineno)
176 continue;
177 if (query->last_lineno &&
178 dp->lineno > query->last_lineno)
179 continue;
180
181 nfound++;
182
183 newflags = (dp->flags & mask) | flags;
184 if (newflags == dp->flags)
185 continue;
Jason Barone9d376f2009-02-05 11:51:38 -0500186 dp->flags = newflags;
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600187 vpr_info("changed %s:%d [%s]%s =%s\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500188 trim_prefix(dp->filename), dp->lineno,
189 dt->mod_name, dp->function,
190 ddebug_describe_flags(dp, flagbuf,
191 sizeof(flagbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500192 }
193 }
194 mutex_unlock(&ddebug_lock);
195
196 if (!nfound && verbose)
Joe Perches4ad275e2011-08-11 14:36:33 -0400197 pr_info("no matches for query\n");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500198
199 return nfound;
Jason Barone9d376f2009-02-05 11:51:38 -0500200}
201
202/*
Jason Barone9d376f2009-02-05 11:51:38 -0500203 * Split the buffer `buf' into space-separated words.
Greg Banks9898abb2009-02-06 12:54:26 +1100204 * Handles simple " and ' quoting, i.e. without nested,
205 * embedded or escaped \". Return the number of words
206 * or <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500207 */
208static int ddebug_tokenize(char *buf, char *words[], int maxwords)
209{
210 int nwords = 0;
211
Greg Banks9898abb2009-02-06 12:54:26 +1100212 while (*buf) {
213 char *end;
214
215 /* Skip leading whitespace */
André Goddard Rosae7d28602009-12-14 18:01:06 -0800216 buf = skip_spaces(buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100217 if (!*buf)
218 break; /* oh, it was trailing whitespace */
Jim Cromie8bd60262011-12-19 17:13:03 -0500219 if (*buf == '#')
220 break; /* token starts comment, skip rest of line */
Greg Banks9898abb2009-02-06 12:54:26 +1100221
Jim Cromie07100be2011-12-19 17:11:09 -0500222 /* find `end' of word, whitespace separated or quoted */
Greg Banks9898abb2009-02-06 12:54:26 +1100223 if (*buf == '"' || *buf == '\'') {
224 int quote = *buf++;
Joe Perchesf657fd22012-12-05 16:48:26 -0500225 for (end = buf; *end && *end != quote; end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100226 ;
Jim Cromie18c216c2012-12-05 16:48:27 -0500227 if (!*end) {
228 pr_err("unclosed quote: %s\n", buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100229 return -EINVAL; /* unclosed quote */
Jim Cromie18c216c2012-12-05 16:48:27 -0500230 }
Greg Banks9898abb2009-02-06 12:54:26 +1100231 } else {
Joe Perchesf657fd22012-12-05 16:48:26 -0500232 for (end = buf; *end && !isspace(*end); end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100233 ;
234 BUG_ON(end == buf);
235 }
Greg Banks9898abb2009-02-06 12:54:26 +1100236
Jim Cromie07100be2011-12-19 17:11:09 -0500237 /* `buf' is start of word, `end' is one past its end */
Jim Cromie18c216c2012-12-05 16:48:27 -0500238 if (nwords == maxwords) {
239 pr_err("too many words, legal max <=%d\n", maxwords);
Greg Banks9898abb2009-02-06 12:54:26 +1100240 return -EINVAL; /* ran out of words[] before bytes */
Jim Cromie18c216c2012-12-05 16:48:27 -0500241 }
Greg Banks9898abb2009-02-06 12:54:26 +1100242 if (*end)
243 *end++ = '\0'; /* terminate the word */
244 words[nwords++] = buf;
245 buf = end;
246 }
Jason Barone9d376f2009-02-05 11:51:38 -0500247
248 if (verbose) {
249 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400250 pr_info("split into words:");
Joe Perchesf657fd22012-12-05 16:48:26 -0500251 for (i = 0; i < nwords; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400252 pr_cont(" \"%s\"", words[i]);
253 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500254 }
255
256 return nwords;
257}
258
259/*
260 * Parse a single line number. Note that the empty string ""
261 * is treated as a special case and converted to zero, which
262 * is later treated as a "don't care" value.
263 */
264static inline int parse_lineno(const char *str, unsigned int *val)
265{
266 char *end = NULL;
267 BUG_ON(str == NULL);
268 if (*str == '\0') {
269 *val = 0;
270 return 0;
271 }
272 *val = simple_strtoul(str, &end, 10);
Jim Cromie18c216c2012-12-05 16:48:27 -0500273 if (end == NULL || end == str || *end != '\0') {
274 pr_err("bad line-number: %s\n", str);
275 return -EINVAL;
276 }
277 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500278}
279
Jim Cromie820874c2011-12-19 17:12:49 -0500280static int check_set(const char **dest, char *src, char *name)
281{
282 int rc = 0;
283
284 if (*dest) {
285 rc = -EINVAL;
Joe Perchesf657fd22012-12-05 16:48:26 -0500286 pr_err("match-spec:%s val:%s overridden by %s\n",
287 name, *dest, src);
Jim Cromie820874c2011-12-19 17:12:49 -0500288 }
289 *dest = src;
290 return rc;
291}
292
Jason Barone9d376f2009-02-05 11:51:38 -0500293/*
294 * Parse words[] as a ddebug query specification, which is a series
295 * of (keyword, value) pairs chosen from these possibilities:
296 *
297 * func <function-name>
298 * file <full-pathname>
299 * file <base-filename>
300 * module <module-name>
301 * format <escaped-string-to-find-in-format>
302 * line <lineno>
303 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500304 *
305 * Only 1 of each type is allowed.
306 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500307 */
308static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600309 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500310{
311 unsigned int i;
Jim Cromie820874c2011-12-19 17:12:49 -0500312 int rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500313
314 /* check we have an even number of words */
Jim Cromie18c216c2012-12-05 16:48:27 -0500315 if (nwords % 2 != 0) {
316 pr_err("expecting pairs of match-spec <value>\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500317 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500318 }
Jason Barone9d376f2009-02-05 11:51:38 -0500319 memset(query, 0, sizeof(*query));
320
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600321 if (modname)
322 /* support $modname.dyndbg=<multiple queries> */
323 query->module = modname;
324
Joe Perchesf657fd22012-12-05 16:48:26 -0500325 for (i = 0; i < nwords; i += 2) {
326 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500327 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500328 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500329 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500330 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500331 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500332 } else if (!strcmp(words[i], "format")) {
Andy Shevchenkod338b132013-04-30 15:27:32 -0700333 string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
334 UNESCAPE_OCTAL |
335 UNESCAPE_SPECIAL);
336 rc = check_set(&query->format, words[i+1], "format");
Joe Perchesf657fd22012-12-05 16:48:26 -0500337 } else if (!strcmp(words[i], "line")) {
Jason Barone9d376f2009-02-05 11:51:38 -0500338 char *first = words[i+1];
339 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500340 if (query->first_lineno || query->last_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500341 pr_err("match-spec: line used 2x\n");
Jim Cromie820874c2011-12-19 17:12:49 -0500342 return -EINVAL;
343 }
Jason Barone9d376f2009-02-05 11:51:38 -0500344 if (last)
345 *last++ = '\0';
Jim Cromie18c216c2012-12-05 16:48:27 -0500346 if (parse_lineno(first, &query->first_lineno) < 0) {
347 pr_err("line-number is <0\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500348 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500349 }
Jim Cromie820874c2011-12-19 17:12:49 -0500350 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500351 /* range <first>-<last> */
Jim Cromie820874c2011-12-19 17:12:49 -0500352 if (parse_lineno(last, &query->last_lineno)
353 < query->first_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500354 pr_err("last-line:%d < 1st-line:%d\n",
355 query->last_lineno,
356 query->first_lineno);
Jason Barone9d376f2009-02-05 11:51:38 -0500357 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500358 }
Jason Barone9d376f2009-02-05 11:51:38 -0500359 } else {
360 query->last_lineno = query->first_lineno;
361 }
362 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500363 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500364 return -EINVAL;
365 }
Jim Cromie820874c2011-12-19 17:12:49 -0500366 if (rc)
367 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500368 }
Jim Cromie574b3722011-12-19 17:13:16 -0500369 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500370 return 0;
371}
372
373/*
374 * Parse `str' as a flags specification, format [-+=][p]+.
375 * Sets up *maskp and *flagsp to be used when changing the
376 * flags fields of matched _ddebug's. Returns 0 on success
377 * or <0 on error.
378 */
379static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
380 unsigned int *maskp)
381{
382 unsigned flags = 0;
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100383 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500384
385 switch (*str) {
386 case '+':
387 case '-':
388 case '=':
389 op = *str++;
390 break;
391 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500392 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500393 return -EINVAL;
394 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600395 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500396
Joe Perchesf657fd22012-12-05 16:48:26 -0500397 for (; *str ; ++str) {
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100398 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
399 if (*str == opt_array[i].opt_char) {
400 flags |= opt_array[i].flag;
401 break;
402 }
Jason Barone9d376f2009-02-05 11:51:38 -0500403 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500404 if (i < 0) {
405 pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100406 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500407 }
Jason Barone9d376f2009-02-05 11:51:38 -0500408 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600409 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500410
411 /* calculate final *flagsp, *maskp according to mask and op */
412 switch (op) {
413 case '=':
414 *maskp = 0;
415 *flagsp = flags;
416 break;
417 case '+':
418 *maskp = ~0U;
419 *flagsp = flags;
420 break;
421 case '-':
422 *maskp = ~flags;
423 *flagsp = 0;
424 break;
425 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600426 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500427 return 0;
428}
429
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600430static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200431{
432 unsigned int flags = 0, mask = 0;
433 struct ddebug_query query;
434#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500435 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200436 char *words[MAXWORDS];
437
438 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500439 if (nwords <= 0) {
440 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200441 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500442 }
443 /* check flags 1st (last arg) so query is pairs of spec,val */
444 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
445 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200446 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500447 }
448 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
449 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200450 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500451 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200452 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500453 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500454 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500455
456 return nfound;
457}
458
459/* handle multiple queries in query string, continue on error, return
460 last error or number of matching callsites. Module name is either
461 in param (for boot arg) or perhaps in query string.
462*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600463static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500464{
465 char *split;
466 int i, errs = 0, exitcode = 0, rc, nfound = 0;
467
468 for (i = 0; query; query = split) {
469 split = strpbrk(query, ";\n");
470 if (split)
471 *split++ = '\0';
472
473 query = skip_spaces(query);
474 if (!query || !*query || *query == '#')
475 continue;
476
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600477 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500478
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600479 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500480 if (rc < 0) {
481 errs++;
482 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500483 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500484 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500485 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500486 i++;
487 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600488 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500489 i, nfound, errs);
490
491 if (exitcode)
492 return exitcode;
493 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200494}
495
Jason Baron431625d2011-10-04 14:13:19 -0700496#define PREFIX_SIZE 64
497
498static int remaining(int wrote)
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100499{
Jason Baron431625d2011-10-04 14:13:19 -0700500 if (PREFIX_SIZE - wrote > 0)
501 return PREFIX_SIZE - wrote;
502 return 0;
503}
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100504
Jason Baron431625d2011-10-04 14:13:19 -0700505static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
506{
507 int pos_after_tid;
508 int pos = 0;
509
Joe Perches798efc62012-09-12 20:11:29 -0700510 *buf = '\0';
511
Jason Baron431625d2011-10-04 14:13:19 -0700512 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100513 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700514 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100515 else
Jason Baron431625d2011-10-04 14:13:19 -0700516 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700517 task_pid_vnr(current));
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100518 }
Jason Baron431625d2011-10-04 14:13:19 -0700519 pos_after_tid = pos;
520 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
521 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700522 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700523 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
524 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700525 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700526 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500527 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700528 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700529 if (pos - pos_after_tid)
530 pos += snprintf(buf + pos, remaining(pos), " ");
531 if (pos >= PREFIX_SIZE)
532 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400533
Jason Baron431625d2011-10-04 14:13:19 -0700534 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400535}
536
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100537int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
538{
539 va_list args;
540 int res;
Jason Baron431625d2011-10-04 14:13:19 -0700541 struct va_format vaf;
542 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100543
544 BUG_ON(!descriptor);
545 BUG_ON(!fmt);
546
547 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700548
Jason Baron431625d2011-10-04 14:13:19 -0700549 vaf.fmt = fmt;
550 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700551
552 res = printk(KERN_DEBUG "%s%pV",
553 dynamic_emit_prefix(descriptor, buf), &vaf);
554
Bart Van Assche8ba6ebf2011-01-23 17:17:24 +0100555 va_end(args);
556
557 return res;
558}
559EXPORT_SYMBOL(__dynamic_pr_debug);
560
Joe Perchescbc46632011-08-11 14:36:21 -0400561int __dynamic_dev_dbg(struct _ddebug *descriptor,
562 const struct device *dev, const char *fmt, ...)
563{
564 struct va_format vaf;
565 va_list args;
566 int res;
567
568 BUG_ON(!descriptor);
569 BUG_ON(!fmt);
570
571 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700572
Joe Perchescbc46632011-08-11 14:36:21 -0400573 vaf.fmt = fmt;
574 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700575
576 if (!dev) {
577 res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
578 } else {
579 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700580
Joe Perches666f3552012-09-12 20:14:11 -0700581 res = dev_printk_emit(7, dev, "%s%s %s: %pV",
582 dynamic_emit_prefix(descriptor, buf),
583 dev_driver_string(dev), dev_name(dev),
584 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700585 }
586
Joe Perchescbc46632011-08-11 14:36:21 -0400587 va_end(args);
588
589 return res;
590}
591EXPORT_SYMBOL(__dynamic_dev_dbg);
592
Jason Baron0feefd92011-10-04 14:13:22 -0700593#ifdef CONFIG_NET
594
Jason Baronffa10cb2011-08-11 14:36:48 -0400595int __dynamic_netdev_dbg(struct _ddebug *descriptor,
Joe Perchesb004ff42012-09-12 20:12:19 -0700596 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400597{
598 struct va_format vaf;
599 va_list args;
600 int res;
601
602 BUG_ON(!descriptor);
603 BUG_ON(!fmt);
604
605 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700606
Jason Baronffa10cb2011-08-11 14:36:48 -0400607 vaf.fmt = fmt;
608 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700609
610 if (dev && dev->dev.parent) {
611 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700612
Joe Perches666f3552012-09-12 20:14:11 -0700613 res = dev_printk_emit(7, dev->dev.parent,
614 "%s%s %s %s: %pV",
615 dynamic_emit_prefix(descriptor, buf),
616 dev_driver_string(dev->dev.parent),
617 dev_name(dev->dev.parent),
618 netdev_name(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700619 } else if (dev) {
620 res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
621 } else {
622 res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
623 }
624
Jason Baronffa10cb2011-08-11 14:36:48 -0400625 va_end(args);
626
627 return res;
628}
629EXPORT_SYMBOL(__dynamic_netdev_dbg);
630
Jason Baron0feefd92011-10-04 14:13:22 -0700631#endif
632
Jim Cromiebc757f62011-12-19 17:12:29 -0500633#define DDEBUG_STRING_SIZE 1024
634static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
635
Thomas Renningera648ec02010-08-06 16:11:02 +0200636static __init int ddebug_setup_query(char *str)
637{
Jim Cromiebc757f62011-12-19 17:12:29 -0500638 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400639 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200640 return 0;
641 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500642 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200643 return 1;
644}
645
646__setup("ddebug_query=", ddebug_setup_query);
647
Jason Barone9d376f2009-02-05 11:51:38 -0500648/*
649 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
650 * command text from userspace, parses and executes it.
651 */
Jim Cromie72814912011-12-19 17:13:07 -0500652#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500653static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
654 size_t len, loff_t *offp)
655{
Jim Cromie72814912011-12-19 17:13:07 -0500656 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200657 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500658
659 if (len == 0)
660 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500661 if (len > USER_BUF_PAGE - 1) {
662 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500663 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500664 }
665 tmpbuf = kmalloc(len + 1, GFP_KERNEL);
666 if (!tmpbuf)
667 return -ENOMEM;
668 if (copy_from_user(tmpbuf, ubuf, len)) {
669 kfree(tmpbuf);
Jason Barone9d376f2009-02-05 11:51:38 -0500670 return -EFAULT;
Jim Cromie72814912011-12-19 17:13:07 -0500671 }
Jason Barone9d376f2009-02-05 11:51:38 -0500672 tmpbuf[len] = '\0';
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600673 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500674
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600675 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500676 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500677 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200678 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500679
680 *offp += len;
681 return len;
682}
683
684/*
685 * Set the iterator to point to the first _ddebug object
686 * and return a pointer to that first object. Returns
687 * NULL if there are no _ddebugs at all.
688 */
689static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
690{
691 if (list_empty(&ddebug_tables)) {
692 iter->table = NULL;
693 iter->idx = 0;
694 return NULL;
695 }
696 iter->table = list_entry(ddebug_tables.next,
697 struct ddebug_table, link);
698 iter->idx = 0;
699 return &iter->table->ddebugs[iter->idx];
700}
701
702/*
703 * Advance the iterator to point to the next _ddebug
704 * object from the one the iterator currently points at,
705 * and returns a pointer to the new _ddebug. Returns
706 * NULL if the iterator has seen all the _ddebugs.
707 */
708static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
709{
710 if (iter->table == NULL)
711 return NULL;
712 if (++iter->idx == iter->table->num_ddebugs) {
713 /* iterate to next table */
714 iter->idx = 0;
715 if (list_is_last(&iter->table->link, &ddebug_tables)) {
716 iter->table = NULL;
717 return NULL;
718 }
719 iter->table = list_entry(iter->table->link.next,
720 struct ddebug_table, link);
721 }
722 return &iter->table->ddebugs[iter->idx];
723}
724
725/*
726 * Seq_ops start method. Called at the start of every
727 * read() call from userspace. Takes the ddebug_lock and
728 * seeks the seq_file's iterator to the given position.
729 */
730static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
731{
732 struct ddebug_iter *iter = m->private;
733 struct _ddebug *dp;
734 int n = *pos;
735
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600736 vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500737
738 mutex_lock(&ddebug_lock);
739
740 if (!n)
741 return SEQ_START_TOKEN;
742 if (n < 0)
743 return NULL;
744 dp = ddebug_iter_first(iter);
745 while (dp != NULL && --n > 0)
746 dp = ddebug_iter_next(iter);
747 return dp;
748}
749
750/*
751 * Seq_ops next method. Called several times within a read()
752 * call from userspace, with ddebug_lock held. Walks to the
753 * next _ddebug object with a special case for the header line.
754 */
755static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
756{
757 struct ddebug_iter *iter = m->private;
758 struct _ddebug *dp;
759
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600760 vpr_info("called m=%p p=%p *pos=%lld\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500761 m, p, (unsigned long long)*pos);
Jason Barone9d376f2009-02-05 11:51:38 -0500762
763 if (p == SEQ_START_TOKEN)
764 dp = ddebug_iter_first(iter);
765 else
766 dp = ddebug_iter_next(iter);
767 ++*pos;
768 return dp;
769}
770
771/*
772 * Seq_ops show method. Called several times within a read()
773 * call from userspace, with ddebug_lock held. Formats the
774 * current _ddebug as a single human-readable line, with a
775 * special case for the header line.
776 */
777static int ddebug_proc_show(struct seq_file *m, void *p)
778{
779 struct ddebug_iter *iter = m->private;
780 struct _ddebug *dp = p;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500781 char flagsbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500782
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600783 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500784
785 if (p == SEQ_START_TOKEN) {
786 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500787 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500788 return 0;
789 }
790
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500791 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500792 trim_prefix(dp->filename), dp->lineno,
793 iter->table->mod_name, dp->function,
794 ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500795 seq_escape(m, dp->format, "\t\r\n\"");
796 seq_puts(m, "\"\n");
797
798 return 0;
799}
800
801/*
802 * Seq_ops stop method. Called at the end of each read()
803 * call from userspace. Drops ddebug_lock.
804 */
805static void ddebug_proc_stop(struct seq_file *m, void *p)
806{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600807 vpr_info("called m=%p p=%p\n", m, p);
Jason Barone9d376f2009-02-05 11:51:38 -0500808 mutex_unlock(&ddebug_lock);
809}
810
811static const struct seq_operations ddebug_proc_seqops = {
812 .start = ddebug_proc_start,
813 .next = ddebug_proc_next,
814 .show = ddebug_proc_show,
815 .stop = ddebug_proc_stop
816};
817
818/*
Jim Cromie07100be2011-12-19 17:11:09 -0500819 * File_ops->open method for <debugfs>/dynamic_debug/control. Does
820 * the seq_file setup dance, and also creates an iterator to walk the
821 * _ddebugs. Note that we create a seq_file always, even for O_WRONLY
822 * files where it's not needed, as doing so simplifies the ->release
823 * method.
Jason Barone9d376f2009-02-05 11:51:38 -0500824 */
825static int ddebug_proc_open(struct inode *inode, struct file *file)
826{
827 struct ddebug_iter *iter;
828 int err;
829
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600830 vpr_info("called\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500831
832 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
833 if (iter == NULL)
834 return -ENOMEM;
835
836 err = seq_open(file, &ddebug_proc_seqops);
837 if (err) {
838 kfree(iter);
839 return err;
840 }
Joe Perchesf657fd22012-12-05 16:48:26 -0500841 ((struct seq_file *)file->private_data)->private = iter;
Jason Barone9d376f2009-02-05 11:51:38 -0500842 return 0;
843}
844
845static const struct file_operations ddebug_proc_fops = {
846 .owner = THIS_MODULE,
847 .open = ddebug_proc_open,
848 .read = seq_read,
849 .llseek = seq_lseek,
850 .release = seq_release_private,
851 .write = ddebug_proc_write
852};
853
854/*
855 * Allocate a new ddebug_table for the given module
856 * and add it to the global list.
857 */
858int ddebug_add_module(struct _ddebug *tab, unsigned int n,
859 const char *name)
860{
861 struct ddebug_table *dt;
862 char *new_name;
863
864 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
865 if (dt == NULL)
866 return -ENOMEM;
867 new_name = kstrdup(name, GFP_KERNEL);
868 if (new_name == NULL) {
869 kfree(dt);
870 return -ENOMEM;
871 }
872 dt->mod_name = new_name;
873 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500874 dt->ddebugs = tab;
875
876 mutex_lock(&ddebug_lock);
877 list_add_tail(&dt->link, &ddebug_tables);
878 mutex_unlock(&ddebug_lock);
879
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600880 vpr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500881 return 0;
882}
883EXPORT_SYMBOL_GPL(ddebug_add_module);
884
Jim Cromie6ab676e2012-04-27 14:30:37 -0600885/* helper for ddebug_dyndbg_(boot|module)_param_cb */
886static int ddebug_dyndbg_param_cb(char *param, char *val,
887 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600888{
Jim Cromieb48420c2012-04-27 14:30:35 -0600889 char *sep;
890
891 sep = strchr(param, '.');
892 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600893 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600894 *sep = '\0';
895 modname = param;
896 param = sep + 1;
897 }
898 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600899 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600900
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600901 ddebug_exec_queries((val ? val : "+p"), modname);
902
Jim Cromieb48420c2012-04-27 14:30:35 -0600903 return 0; /* query failure shouldnt stop module load */
904}
905
Jim Cromie6ab676e2012-04-27 14:30:37 -0600906/* handle both dyndbg and $module.dyndbg params at boot */
907static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
908 const char *unused)
Jim Cromieb48420c2012-04-27 14:30:35 -0600909{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600910 vpr_info("%s=\"%s\"\n", param, val);
911 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
912}
Jim Cromieb48420c2012-04-27 14:30:35 -0600913
Jim Cromie6ab676e2012-04-27 14:30:37 -0600914/*
915 * modprobe foo finds foo.params in boot-args, strips "foo.", and
916 * passes them to load_module(). This callback gets unknown params,
917 * processes dyndbg params, rejects others.
918 */
919int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
920{
921 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
922 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600923}
924
Jason Barone9d376f2009-02-05 11:51:38 -0500925static void ddebug_table_free(struct ddebug_table *dt)
926{
927 list_del_init(&dt->link);
928 kfree(dt->mod_name);
929 kfree(dt);
930}
931
932/*
933 * Called in response to a module being unloaded. Removes
934 * any ddebug_table's which point at the module.
935 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000936int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500937{
938 struct ddebug_table *dt, *nextdt;
939 int ret = -ENOENT;
940
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600941 vpr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500942
943 mutex_lock(&ddebug_lock);
944 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
945 if (!strcmp(dt->mod_name, mod_name)) {
946 ddebug_table_free(dt);
947 ret = 0;
948 }
949 }
950 mutex_unlock(&ddebug_lock);
951 return ret;
952}
953EXPORT_SYMBOL_GPL(ddebug_remove_module);
954
955static void ddebug_remove_all_tables(void)
956{
957 mutex_lock(&ddebug_lock);
958 while (!list_empty(&ddebug_tables)) {
959 struct ddebug_table *dt = list_entry(ddebug_tables.next,
960 struct ddebug_table,
961 link);
962 ddebug_table_free(dt);
963 }
964 mutex_unlock(&ddebug_lock);
965}
966
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200967static __initdata int ddebug_init_success;
968
969static int __init dynamic_debug_init_debugfs(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500970{
971 struct dentry *dir, *file;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200972
973 if (!ddebug_init_success)
974 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -0500975
976 dir = debugfs_create_dir("dynamic_debug", NULL);
977 if (!dir)
978 return -ENOMEM;
979 file = debugfs_create_file("control", 0644, dir, NULL,
980 &ddebug_proc_fops);
981 if (!file) {
982 debugfs_remove(dir);
983 return -ENOMEM;
984 }
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200985 return 0;
986}
987
988static int __init dynamic_debug_init(void)
989{
990 struct _ddebug *iter, *iter_start;
991 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -0600992 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200993 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -0600994 int n = 0, entries = 0, modct = 0;
995 int verbose_bytes = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200996
Jim Cromieb5b78f82011-12-19 17:12:54 -0500997 if (__start___verbose == __stop___verbose) {
Joe Perchesf657fd22012-12-05 16:48:26 -0500998 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
Jim Cromieb5b78f82011-12-19 17:12:54 -0500999 return 1;
Jason Barone9d376f2009-02-05 11:51:38 -05001000 }
Jim Cromieb5b78f82011-12-19 17:12:54 -05001001 iter = __start___verbose;
1002 modname = iter->modname;
1003 iter_start = iter;
1004 for (; iter < __stop___verbose; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001005 entries++;
1006 verbose_bytes += strlen(iter->modname) + strlen(iter->function)
1007 + strlen(iter->filename) + strlen(iter->format);
1008
Jim Cromieb5b78f82011-12-19 17:12:54 -05001009 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001010 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001011 ret = ddebug_add_module(iter_start, n, modname);
1012 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001013 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001014 n = 0;
1015 modname = iter->modname;
1016 iter_start = iter;
1017 }
1018 n++;
1019 }
1020 ret = ddebug_add_module(iter_start, n, modname);
1021 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001022 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001023
Jim Cromieaf442392012-04-27 14:30:38 -06001024 ddebug_init_success = 1;
Joe Perchesf657fd22012-12-05 16:48:26 -05001025 vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
1026 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
1027 verbose_bytes + (int)(__stop___verbose - __start___verbose));
Jim Cromieaf442392012-04-27 14:30:38 -06001028
1029 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001030 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001031 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001032 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001033 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001034 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001035 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001036 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001037 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001038 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001039 /* now that ddebug tables are loaded, process all boot args
1040 * again to find and activate queries given in dyndbg params.
1041 * While this has already been done for known boot params, it
1042 * ignored the unknown ones (dyndbg in particular). Reusing
1043 * parse_args avoids ad-hoc parsing. This will also attempt
1044 * to activate queries for not-yet-loaded modules, which is
1045 * slightly noisy if verbose, but harmless.
1046 */
1047 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1048 parse_args("dyndbg params", cmdline, NULL,
1049 0, 0, 0, &ddebug_dyndbg_boot_param_cb);
1050 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001051 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001052
Jim Cromieaf442392012-04-27 14:30:38 -06001053out_err:
1054 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001055 return 0;
1056}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001057/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001058early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001059
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001060/* Debugfs setup must be done later */
Jim Cromie3ec56522012-04-27 14:30:42 -06001061fs_initcall(dynamic_debug_init_debugfs);