blob: 1d25a846553b3ff044df1f52c979bb94121933b7 [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.
Du, Changbin578b1e02014-01-23 15:54:14 -080011 * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
Jason Barone9d376f2009-02-05 11:51:38 -050012 */
13
Joe Perches4ad275e2011-08-11 14:36:33 -040014#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
15
Jason Barone9d376f2009-02-05 11:51:38 -050016#include <linux/kernel.h>
17#include <linux/module.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070018#include <linux/moduleparam.h>
19#include <linux/kallsyms.h>
20#include <linux/types.h>
Jason Barone9d376f2009-02-05 11:51:38 -050021#include <linux/mutex.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070022#include <linux/proc_fs.h>
Jason Barone9d376f2009-02-05 11:51:38 -050023#include <linux/seq_file.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070024#include <linux/list.h>
25#include <linux/sysctl.h>
Jason Barone9d376f2009-02-05 11:51:38 -050026#include <linux/ctype.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070027#include <linux/string.h>
Du, Changbin578b1e02014-01-23 15:54:14 -080028#include <linux/parser.h>
Andy Shevchenkod338b132013-04-30 15:27:32 -070029#include <linux/string_helpers.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070030#include <linux/uaccess.h>
Jason Barone9d376f2009-02-05 11:51:38 -050031#include <linux/dynamic_debug.h>
32#include <linux/debugfs.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090033#include <linux/slab.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070034#include <linux/jump_label.h>
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010035#include <linux/hardirq.h>
Greg Kroah-Hartmane8d97922011-02-03 15:59:58 -080036#include <linux/sched.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070037#include <linux/device.h>
Jason Baronffa10cb2011-08-11 14:36:48 -040038#include <linux/netdevice.h>
Jason Barone9d376f2009-02-05 11:51:38 -050039
Gal Pressman923abb92019-05-01 13:48:13 +030040#include <rdma/ib_verbs.h>
41
Jim Cromiee5ebffe2020-07-19 17:10:45 -060042extern struct _ddebug __start___dyndbg[];
43extern struct _ddebug __stop___dyndbg[];
Jason Barone9d376f2009-02-05 11:51:38 -050044
Jason Barone9d376f2009-02-05 11:51:38 -050045struct ddebug_table {
46 struct list_head link;
Rasmus Villemoes3e406b12015-11-06 16:30:15 -080047 const char *mod_name;
Jason Barone9d376f2009-02-05 11:51:38 -050048 unsigned int num_ddebugs;
Jason Barone9d376f2009-02-05 11:51:38 -050049 struct _ddebug *ddebugs;
50};
51
52struct ddebug_query {
53 const char *filename;
54 const char *module;
55 const char *function;
56 const char *format;
57 unsigned int first_lineno, last_lineno;
58};
59
60struct ddebug_iter {
61 struct ddebug_table *table;
62 unsigned int idx;
63};
64
65static DEFINE_MUTEX(ddebug_lock);
66static LIST_HEAD(ddebug_tables);
Joe Perchesf657fd22012-12-05 16:48:26 -050067static int verbose;
Jim Cromie74df1382011-12-19 17:12:24 -050068module_param(verbose, int, 0644);
Jason Barone9d376f2009-02-05 11:51:38 -050069
Jim Cromie2b678312011-12-19 17:13:12 -050070/* Return the path relative to source root */
71static inline const char *trim_prefix(const char *path)
72{
73 int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
74
75 if (strncmp(path, __FILE__, skip))
76 skip = 0; /* prefix mismatch, don't skip */
77
78 return path + skip;
79}
80
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010081static struct { unsigned flag:8; char opt_char; } opt_array[] = {
82 { _DPRINTK_FLAGS_PRINT, 'p' },
83 { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
84 { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
85 { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
86 { _DPRINTK_FLAGS_INCL_TID, 't' },
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050087 { _DPRINTK_FLAGS_NONE, '_' },
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010088};
89
Jim Cromief678ce82020-07-19 17:10:47 -060090struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };
91
Jason Barone9d376f2009-02-05 11:51:38 -050092/* format a string into buf[] which describes the _ddebug's flags */
Jim Cromief678ce82020-07-19 17:10:47 -060093static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)
Jason Barone9d376f2009-02-05 11:51:38 -050094{
Jim Cromief678ce82020-07-19 17:10:47 -060095 char *p = fb->buf;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010096 int i;
Jason Barone9d376f2009-02-05 11:51:38 -050097
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010098 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
Jim Cromief678ce82020-07-19 17:10:47 -060099 if (flags & opt_array[i].flag)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100100 *p++ = opt_array[i].opt_char;
Jim Cromief678ce82020-07-19 17:10:47 -0600101 if (p == fb->buf)
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500102 *p++ = '_';
Jason Barone9d376f2009-02-05 11:51:38 -0500103 *p = '\0';
104
Jim Cromief678ce82020-07-19 17:10:47 -0600105 return fb->buf;
Jason Barone9d376f2009-02-05 11:51:38 -0500106}
107
Jim Cromie481c0e32020-07-19 17:10:44 -0600108#define vnpr_info(lvl, fmt, ...) \
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600109do { \
Jim Cromie481c0e32020-07-19 17:10:44 -0600110 if (verbose >= lvl) \
Joe Perchesf657fd22012-12-05 16:48:26 -0500111 pr_info(fmt, ##__VA_ARGS__); \
Jim Cromie574b3722011-12-19 17:13:16 -0500112} while (0)
113
Jim Cromie481c0e32020-07-19 17:10:44 -0600114#define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__)
115#define v2pr_info(fmt, ...) vnpr_info(2, fmt, ##__VA_ARGS__)
116
Joe Perchesf657fd22012-12-05 16:48:26 -0500117static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
118{
119 /* trim any trailing newlines */
120 int fmtlen = 0;
121
122 if (query->format) {
123 fmtlen = strlen(query->format);
124 while (fmtlen && query->format[fmtlen - 1] == '\n')
125 fmtlen--;
126 }
127
128 vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
129 msg,
130 query->function ? query->function : "",
131 query->filename ? query->filename : "",
132 query->module ? query->module : "",
133 fmtlen, query->format ? query->format : "",
134 query->first_lineno, query->last_lineno);
135}
136
Jason Barone9d376f2009-02-05 11:51:38 -0500137/*
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500138 * Search the tables for _ddebug's which match the given `query' and
139 * apply the `flags' and `mask' to them. Returns number of matching
140 * callsites, normally the same as number of changes. If verbose,
141 * logs the changes. Takes ddebug_lock.
Jason Barone9d376f2009-02-05 11:51:38 -0500142 */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500143static int ddebug_change(const struct ddebug_query *query,
144 unsigned int flags, unsigned int mask)
Jason Barone9d376f2009-02-05 11:51:38 -0500145{
146 int i;
147 struct ddebug_table *dt;
148 unsigned int newflags;
149 unsigned int nfound = 0;
Jim Cromief678ce82020-07-19 17:10:47 -0600150 struct flagsbuf fbuf;
Jason Barone9d376f2009-02-05 11:51:38 -0500151
152 /* search for matching ddebugs */
153 mutex_lock(&ddebug_lock);
154 list_for_each_entry(dt, &ddebug_tables, link) {
155
156 /* match against the module name */
Du, Changbin578b1e02014-01-23 15:54:14 -0800157 if (query->module &&
158 !match_wildcard(query->module, dt->mod_name))
Jason Barone9d376f2009-02-05 11:51:38 -0500159 continue;
160
Joe Perchesf657fd22012-12-05 16:48:26 -0500161 for (i = 0; i < dt->num_ddebugs; i++) {
Jason Barone9d376f2009-02-05 11:51:38 -0500162 struct _ddebug *dp = &dt->ddebugs[i];
163
164 /* match against the source filename */
Jim Cromied6a238d2011-12-19 17:12:39 -0500165 if (query->filename &&
Du, Changbin578b1e02014-01-23 15:54:14 -0800166 !match_wildcard(query->filename, dp->filename) &&
167 !match_wildcard(query->filename,
168 kbasename(dp->filename)) &&
169 !match_wildcard(query->filename,
170 trim_prefix(dp->filename)))
Jason Barone9d376f2009-02-05 11:51:38 -0500171 continue;
172
173 /* match against the function */
Jim Cromied6a238d2011-12-19 17:12:39 -0500174 if (query->function &&
Du, Changbin578b1e02014-01-23 15:54:14 -0800175 !match_wildcard(query->function, dp->function))
Jason Barone9d376f2009-02-05 11:51:38 -0500176 continue;
177
178 /* match against the format */
Jim Cromied6a238d2011-12-19 17:12:39 -0500179 if (query->format &&
180 !strstr(dp->format, query->format))
Jason Barone9d376f2009-02-05 11:51:38 -0500181 continue;
182
183 /* match against the line number range */
184 if (query->first_lineno &&
185 dp->lineno < query->first_lineno)
186 continue;
187 if (query->last_lineno &&
188 dp->lineno > query->last_lineno)
189 continue;
190
191 nfound++;
192
193 newflags = (dp->flags & mask) | flags;
194 if (newflags == dp->flags)
195 continue;
Masahiro Yamadae9666d12018-12-31 00:14:15 +0900196#ifdef CONFIG_JUMP_LABEL
Jason Baron9049fc72016-08-03 13:46:39 -0700197 if (dp->flags & _DPRINTK_FLAGS_PRINT) {
198 if (!(flags & _DPRINTK_FLAGS_PRINT))
199 static_branch_disable(&dp->key.dd_key_true);
200 } else if (flags & _DPRINTK_FLAGS_PRINT)
201 static_branch_enable(&dp->key.dd_key_true);
202#endif
Jason Barone9d376f2009-02-05 11:51:38 -0500203 dp->flags = newflags;
Jim Cromie481c0e32020-07-19 17:10:44 -0600204 v2pr_info("changed %s:%d [%s]%s =%s\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500205 trim_prefix(dp->filename), dp->lineno,
206 dt->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600207 ddebug_describe_flags(dp->flags, &fbuf));
Jason Barone9d376f2009-02-05 11:51:38 -0500208 }
209 }
210 mutex_unlock(&ddebug_lock);
211
212 if (!nfound && verbose)
Joe Perches4ad275e2011-08-11 14:36:33 -0400213 pr_info("no matches for query\n");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500214
215 return nfound;
Jason Barone9d376f2009-02-05 11:51:38 -0500216}
217
218/*
Jason Barone9d376f2009-02-05 11:51:38 -0500219 * Split the buffer `buf' into space-separated words.
Greg Banks9898abb2009-02-06 12:54:26 +1100220 * Handles simple " and ' quoting, i.e. without nested,
221 * embedded or escaped \". Return the number of words
222 * or <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500223 */
224static int ddebug_tokenize(char *buf, char *words[], int maxwords)
225{
226 int nwords = 0;
227
Greg Banks9898abb2009-02-06 12:54:26 +1100228 while (*buf) {
229 char *end;
230
231 /* Skip leading whitespace */
André Goddard Rosae7d28602009-12-14 18:01:06 -0800232 buf = skip_spaces(buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100233 if (!*buf)
234 break; /* oh, it was trailing whitespace */
Jim Cromie8bd60262011-12-19 17:13:03 -0500235 if (*buf == '#')
236 break; /* token starts comment, skip rest of line */
Greg Banks9898abb2009-02-06 12:54:26 +1100237
Jim Cromie07100be2011-12-19 17:11:09 -0500238 /* find `end' of word, whitespace separated or quoted */
Greg Banks9898abb2009-02-06 12:54:26 +1100239 if (*buf == '"' || *buf == '\'') {
240 int quote = *buf++;
Joe Perchesf657fd22012-12-05 16:48:26 -0500241 for (end = buf; *end && *end != quote; end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100242 ;
Jim Cromie18c216c2012-12-05 16:48:27 -0500243 if (!*end) {
244 pr_err("unclosed quote: %s\n", buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100245 return -EINVAL; /* unclosed quote */
Jim Cromie18c216c2012-12-05 16:48:27 -0500246 }
Greg Banks9898abb2009-02-06 12:54:26 +1100247 } else {
Joe Perchesf657fd22012-12-05 16:48:26 -0500248 for (end = buf; *end && !isspace(*end); end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100249 ;
250 BUG_ON(end == buf);
251 }
Greg Banks9898abb2009-02-06 12:54:26 +1100252
Jim Cromie07100be2011-12-19 17:11:09 -0500253 /* `buf' is start of word, `end' is one past its end */
Jim Cromie18c216c2012-12-05 16:48:27 -0500254 if (nwords == maxwords) {
255 pr_err("too many words, legal max <=%d\n", maxwords);
Greg Banks9898abb2009-02-06 12:54:26 +1100256 return -EINVAL; /* ran out of words[] before bytes */
Jim Cromie18c216c2012-12-05 16:48:27 -0500257 }
Greg Banks9898abb2009-02-06 12:54:26 +1100258 if (*end)
259 *end++ = '\0'; /* terminate the word */
260 words[nwords++] = buf;
261 buf = end;
262 }
Jason Barone9d376f2009-02-05 11:51:38 -0500263
264 if (verbose) {
265 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400266 pr_info("split into words:");
Joe Perchesf657fd22012-12-05 16:48:26 -0500267 for (i = 0; i < nwords; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400268 pr_cont(" \"%s\"", words[i]);
269 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500270 }
271
272 return nwords;
273}
274
275/*
276 * Parse a single line number. Note that the empty string ""
277 * is treated as a special case and converted to zero, which
278 * is later treated as a "don't care" value.
279 */
280static inline int parse_lineno(const char *str, unsigned int *val)
281{
Jason Barone9d376f2009-02-05 11:51:38 -0500282 BUG_ON(str == NULL);
283 if (*str == '\0') {
284 *val = 0;
285 return 0;
286 }
Andrey Ryabinin45925992014-01-27 17:06:59 -0800287 if (kstrtouint(str, 10, val) < 0) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500288 pr_err("bad line-number: %s\n", str);
289 return -EINVAL;
290 }
291 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500292}
293
Jim Cromie820874c2011-12-19 17:12:49 -0500294static int check_set(const char **dest, char *src, char *name)
295{
296 int rc = 0;
297
298 if (*dest) {
299 rc = -EINVAL;
Joe Perchesf657fd22012-12-05 16:48:26 -0500300 pr_err("match-spec:%s val:%s overridden by %s\n",
301 name, *dest, src);
Jim Cromie820874c2011-12-19 17:12:49 -0500302 }
303 *dest = src;
304 return rc;
305}
306
Jason Barone9d376f2009-02-05 11:51:38 -0500307/*
308 * Parse words[] as a ddebug query specification, which is a series
309 * of (keyword, value) pairs chosen from these possibilities:
310 *
311 * func <function-name>
312 * file <full-pathname>
313 * file <base-filename>
314 * module <module-name>
315 * format <escaped-string-to-find-in-format>
316 * line <lineno>
317 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500318 *
319 * Only 1 of each type is allowed.
320 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500321 */
322static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600323 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500324{
325 unsigned int i;
jbaron@akamai.combd8c154a2013-08-27 16:50:03 +0000326 int rc = 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500327
328 /* check we have an even number of words */
Jim Cromie18c216c2012-12-05 16:48:27 -0500329 if (nwords % 2 != 0) {
330 pr_err("expecting pairs of match-spec <value>\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500331 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500332 }
Jason Barone9d376f2009-02-05 11:51:38 -0500333 memset(query, 0, sizeof(*query));
334
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600335 if (modname)
336 /* support $modname.dyndbg=<multiple queries> */
337 query->module = modname;
338
Joe Perchesf657fd22012-12-05 16:48:26 -0500339 for (i = 0; i < nwords; i += 2) {
340 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500341 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500342 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500343 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500344 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500345 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500346 } else if (!strcmp(words[i], "format")) {
Andy Shevchenkod338b132013-04-30 15:27:32 -0700347 string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
348 UNESCAPE_OCTAL |
349 UNESCAPE_SPECIAL);
350 rc = check_set(&query->format, words[i+1], "format");
Joe Perchesf657fd22012-12-05 16:48:26 -0500351 } else if (!strcmp(words[i], "line")) {
Jason Barone9d376f2009-02-05 11:51:38 -0500352 char *first = words[i+1];
353 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500354 if (query->first_lineno || query->last_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500355 pr_err("match-spec: line used 2x\n");
Jim Cromie820874c2011-12-19 17:12:49 -0500356 return -EINVAL;
357 }
Jason Barone9d376f2009-02-05 11:51:38 -0500358 if (last)
359 *last++ = '\0';
Andrey Ryabinind9e133e2014-01-27 17:06:57 -0800360 if (parse_lineno(first, &query->first_lineno) < 0)
Jason Barone9d376f2009-02-05 11:51:38 -0500361 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500362 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500363 /* range <first>-<last> */
Andrey Ryabinin3ace6782014-01-27 17:06:58 -0800364 if (parse_lineno(last, &query->last_lineno) < 0)
365 return -EINVAL;
366
Randy Dunlap1f3c7902017-11-17 15:27:35 -0800367 /* special case for last lineno not specified */
368 if (query->last_lineno == 0)
369 query->last_lineno = UINT_MAX;
370
Andrey Ryabinin3ace6782014-01-27 17:06:58 -0800371 if (query->last_lineno < query->first_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500372 pr_err("last-line:%d < 1st-line:%d\n",
373 query->last_lineno,
374 query->first_lineno);
Jason Barone9d376f2009-02-05 11:51:38 -0500375 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500376 }
Jason Barone9d376f2009-02-05 11:51:38 -0500377 } else {
378 query->last_lineno = query->first_lineno;
379 }
380 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500381 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500382 return -EINVAL;
383 }
Jim Cromie820874c2011-12-19 17:12:49 -0500384 if (rc)
385 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500386 }
Jim Cromie574b3722011-12-19 17:13:16 -0500387 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500388 return 0;
389}
390
391/*
392 * Parse `str' as a flags specification, format [-+=][p]+.
393 * Sets up *maskp and *flagsp to be used when changing the
394 * flags fields of matched _ddebug's. Returns 0 on success
395 * or <0 on error.
396 */
397static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
398 unsigned int *maskp)
399{
400 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100401 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500402
403 switch (*str) {
404 case '+':
405 case '-':
406 case '=':
407 op = *str++;
408 break;
409 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500410 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500411 return -EINVAL;
412 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600413 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500414
Joe Perchesf657fd22012-12-05 16:48:26 -0500415 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100416 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
417 if (*str == opt_array[i].opt_char) {
418 flags |= opt_array[i].flag;
419 break;
420 }
Jason Barone9d376f2009-02-05 11:51:38 -0500421 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500422 if (i < 0) {
Jim Cromie0b8f96b2020-07-19 17:10:48 -0600423 pr_err("unknown flag '%c'\n", *str);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100424 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500425 }
Jason Barone9d376f2009-02-05 11:51:38 -0500426 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600427 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500428
429 /* calculate final *flagsp, *maskp according to mask and op */
430 switch (op) {
431 case '=':
432 *maskp = 0;
433 *flagsp = flags;
434 break;
435 case '+':
436 *maskp = ~0U;
437 *flagsp = flags;
438 break;
439 case '-':
440 *maskp = ~flags;
441 *flagsp = 0;
442 break;
443 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600444 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500445 return 0;
446}
447
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600448static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200449{
450 unsigned int flags = 0, mask = 0;
451 struct ddebug_query query;
452#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500453 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200454 char *words[MAXWORDS];
455
456 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500457 if (nwords <= 0) {
458 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200459 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500460 }
461 /* check flags 1st (last arg) so query is pairs of spec,val */
462 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
463 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200464 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500465 }
466 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
467 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200468 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500469 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200470 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500471 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500472 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500473
474 return nfound;
475}
476
477/* handle multiple queries in query string, continue on error, return
478 last error or number of matching callsites. Module name is either
479 in param (for boot arg) or perhaps in query string.
480*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600481static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500482{
483 char *split;
484 int i, errs = 0, exitcode = 0, rc, nfound = 0;
485
486 for (i = 0; query; query = split) {
487 split = strpbrk(query, ";\n");
488 if (split)
489 *split++ = '\0';
490
491 query = skip_spaces(query);
492 if (!query || !*query || *query == '#')
493 continue;
494
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600495 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500496
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600497 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500498 if (rc < 0) {
499 errs++;
500 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500501 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500502 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500503 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500504 i++;
505 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600506 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500507 i, nfound, errs);
508
509 if (exitcode)
510 return exitcode;
511 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200512}
513
Jason Baron431625d2011-10-04 14:13:19 -0700514#define PREFIX_SIZE 64
515
516static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100517{
Jason Baron431625d2011-10-04 14:13:19 -0700518 if (PREFIX_SIZE - wrote > 0)
519 return PREFIX_SIZE - wrote;
520 return 0;
521}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100522
Jason Baron431625d2011-10-04 14:13:19 -0700523static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
524{
525 int pos_after_tid;
526 int pos = 0;
527
Joe Perches798efc62012-09-12 20:11:29 -0700528 *buf = '\0';
529
Jason Baron431625d2011-10-04 14:13:19 -0700530 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100531 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700532 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100533 else
Jason Baron431625d2011-10-04 14:13:19 -0700534 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700535 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100536 }
Jason Baron431625d2011-10-04 14:13:19 -0700537 pos_after_tid = pos;
538 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
539 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700540 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700541 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
542 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700543 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700544 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500545 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700546 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700547 if (pos - pos_after_tid)
548 pos += snprintf(buf + pos, remaining(pos), " ");
549 if (pos >= PREFIX_SIZE)
550 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400551
Jason Baron431625d2011-10-04 14:13:19 -0700552 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400553}
554
Joe Perches906d2012014-09-24 11:17:56 -0700555void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100556{
557 va_list args;
Jason Baron431625d2011-10-04 14:13:19 -0700558 struct va_format vaf;
559 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100560
561 BUG_ON(!descriptor);
562 BUG_ON(!fmt);
563
564 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700565
Jason Baron431625d2011-10-04 14:13:19 -0700566 vaf.fmt = fmt;
567 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700568
Joe Perches906d2012014-09-24 11:17:56 -0700569 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700570
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100571 va_end(args);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100572}
573EXPORT_SYMBOL(__dynamic_pr_debug);
574
Joe Perches906d2012014-09-24 11:17:56 -0700575void __dynamic_dev_dbg(struct _ddebug *descriptor,
Joe Perchescbc46632011-08-11 14:36:21 -0400576 const struct device *dev, const char *fmt, ...)
577{
578 struct va_format vaf;
579 va_list args;
Joe Perchescbc46632011-08-11 14:36:21 -0400580
581 BUG_ON(!descriptor);
582 BUG_ON(!fmt);
583
584 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700585
Joe Perchescbc46632011-08-11 14:36:21 -0400586 vaf.fmt = fmt;
587 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700588
589 if (!dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700590 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700591 } else {
592 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700593
Joe Perchesa39d4a82014-12-10 15:50:15 -0800594 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
Joe Perches906d2012014-09-24 11:17:56 -0700595 dynamic_emit_prefix(descriptor, buf),
596 dev_driver_string(dev), dev_name(dev),
597 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700598 }
599
Joe Perchescbc46632011-08-11 14:36:21 -0400600 va_end(args);
Joe Perchescbc46632011-08-11 14:36:21 -0400601}
602EXPORT_SYMBOL(__dynamic_dev_dbg);
603
Jason Baron0feefd92011-10-04 14:13:22 -0700604#ifdef CONFIG_NET
605
Joe Perches906d2012014-09-24 11:17:56 -0700606void __dynamic_netdev_dbg(struct _ddebug *descriptor,
607 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400608{
609 struct va_format vaf;
610 va_list args;
Jason Baronffa10cb2011-08-11 14:36:48 -0400611
612 BUG_ON(!descriptor);
613 BUG_ON(!fmt);
614
615 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700616
Jason Baronffa10cb2011-08-11 14:36:48 -0400617 vaf.fmt = fmt;
618 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700619
620 if (dev && dev->dev.parent) {
621 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700622
Joe Perchesa39d4a82014-12-10 15:50:15 -0800623 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
Joe Perches906d2012014-09-24 11:17:56 -0700624 "%s%s %s %s%s: %pV",
625 dynamic_emit_prefix(descriptor, buf),
626 dev_driver_string(dev->dev.parent),
627 dev_name(dev->dev.parent),
628 netdev_name(dev), netdev_reg_state(dev),
629 &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700630 } else if (dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700631 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
632 netdev_reg_state(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700633 } else {
Joe Perches906d2012014-09-24 11:17:56 -0700634 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700635 }
636
Jason Baronffa10cb2011-08-11 14:36:48 -0400637 va_end(args);
Jason Baronffa10cb2011-08-11 14:36:48 -0400638}
639EXPORT_SYMBOL(__dynamic_netdev_dbg);
640
Jason Baron0feefd92011-10-04 14:13:22 -0700641#endif
642
Gal Pressman923abb92019-05-01 13:48:13 +0300643#if IS_ENABLED(CONFIG_INFINIBAND)
644
645void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
646 const struct ib_device *ibdev, const char *fmt, ...)
647{
648 struct va_format vaf;
649 va_list args;
650
651 va_start(args, fmt);
652
653 vaf.fmt = fmt;
654 vaf.va = &args;
655
656 if (ibdev && ibdev->dev.parent) {
657 char buf[PREFIX_SIZE];
658
659 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
660 "%s%s %s %s: %pV",
661 dynamic_emit_prefix(descriptor, buf),
662 dev_driver_string(ibdev->dev.parent),
663 dev_name(ibdev->dev.parent),
664 dev_name(&ibdev->dev),
665 &vaf);
666 } else if (ibdev) {
667 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
668 } else {
669 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
670 }
671
672 va_end(args);
673}
674EXPORT_SYMBOL(__dynamic_ibdev_dbg);
675
676#endif
677
Jim Cromiebc757f62011-12-19 17:12:29 -0500678#define DDEBUG_STRING_SIZE 1024
679static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
680
Thomas Renningera648ec02010-08-06 16:11:02 +0200681static __init int ddebug_setup_query(char *str)
682{
Jim Cromiebc757f62011-12-19 17:12:29 -0500683 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400684 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200685 return 0;
686 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500687 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200688 return 1;
689}
690
691__setup("ddebug_query=", ddebug_setup_query);
692
Jason Barone9d376f2009-02-05 11:51:38 -0500693/*
Masatake YAMATO231821d2014-12-15 12:04:16 +0900694 * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
Jason Barone9d376f2009-02-05 11:51:38 -0500695 * command text from userspace, parses and executes it.
696 */
Jim Cromie72814912011-12-19 17:13:07 -0500697#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500698static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
699 size_t len, loff_t *offp)
700{
Jim Cromie72814912011-12-19 17:13:07 -0500701 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200702 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500703
704 if (len == 0)
705 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500706 if (len > USER_BUF_PAGE - 1) {
707 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500708 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500709 }
Al Viro16e5c1f2015-12-24 00:06:05 -0500710 tmpbuf = memdup_user_nul(ubuf, len);
711 if (IS_ERR(tmpbuf))
712 return PTR_ERR(tmpbuf);
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600713 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500714
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600715 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500716 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500717 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200718 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500719
720 *offp += len;
721 return len;
722}
723
724/*
725 * Set the iterator to point to the first _ddebug object
726 * and return a pointer to that first object. Returns
727 * NULL if there are no _ddebugs at all.
728 */
729static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
730{
731 if (list_empty(&ddebug_tables)) {
732 iter->table = NULL;
733 iter->idx = 0;
734 return NULL;
735 }
736 iter->table = list_entry(ddebug_tables.next,
737 struct ddebug_table, link);
738 iter->idx = 0;
739 return &iter->table->ddebugs[iter->idx];
740}
741
742/*
743 * Advance the iterator to point to the next _ddebug
744 * object from the one the iterator currently points at,
745 * and returns a pointer to the new _ddebug. Returns
746 * NULL if the iterator has seen all the _ddebugs.
747 */
748static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
749{
750 if (iter->table == NULL)
751 return NULL;
752 if (++iter->idx == iter->table->num_ddebugs) {
753 /* iterate to next table */
754 iter->idx = 0;
755 if (list_is_last(&iter->table->link, &ddebug_tables)) {
756 iter->table = NULL;
757 return NULL;
758 }
759 iter->table = list_entry(iter->table->link.next,
760 struct ddebug_table, link);
761 }
762 return &iter->table->ddebugs[iter->idx];
763}
764
765/*
766 * Seq_ops start method. Called at the start of every
767 * read() call from userspace. Takes the ddebug_lock and
768 * seeks the seq_file's iterator to the given position.
769 */
770static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
771{
772 struct ddebug_iter *iter = m->private;
773 struct _ddebug *dp;
774 int n = *pos;
775
Jason Barone9d376f2009-02-05 11:51:38 -0500776 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
Jason Barone9d376f2009-02-05 11:51:38 -0500798 if (p == SEQ_START_TOKEN)
799 dp = ddebug_iter_first(iter);
800 else
801 dp = ddebug_iter_next(iter);
802 ++*pos;
803 return dp;
804}
805
806/*
807 * Seq_ops show method. Called several times within a read()
808 * call from userspace, with ddebug_lock held. Formats the
809 * current _ddebug as a single human-readable line, with a
810 * special case for the header line.
811 */
812static int ddebug_proc_show(struct seq_file *m, void *p)
813{
814 struct ddebug_iter *iter = m->private;
815 struct _ddebug *dp = p;
Jim Cromief678ce82020-07-19 17:10:47 -0600816 struct flagsbuf flags;
Jason Barone9d376f2009-02-05 11:51:38 -0500817
Jason Barone9d376f2009-02-05 11:51:38 -0500818 if (p == SEQ_START_TOKEN) {
819 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500820 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500821 return 0;
822 }
823
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500824 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500825 trim_prefix(dp->filename), dp->lineno,
826 iter->table->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600827 ddebug_describe_flags(dp->flags, &flags));
Jason Barone9d376f2009-02-05 11:51:38 -0500828 seq_escape(m, dp->format, "\t\r\n\"");
829 seq_puts(m, "\"\n");
830
831 return 0;
832}
833
834/*
835 * Seq_ops stop method. Called at the end of each read()
836 * call from userspace. Drops ddebug_lock.
837 */
838static void ddebug_proc_stop(struct seq_file *m, void *p)
839{
Jason Barone9d376f2009-02-05 11:51:38 -0500840 mutex_unlock(&ddebug_lock);
841}
842
843static const struct seq_operations ddebug_proc_seqops = {
844 .start = ddebug_proc_start,
845 .next = ddebug_proc_next,
846 .show = ddebug_proc_show,
847 .stop = ddebug_proc_stop
848};
849
Jason Barone9d376f2009-02-05 11:51:38 -0500850static int ddebug_proc_open(struct inode *inode, struct file *file)
851{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600852 vpr_info("called\n");
Rob Jones4bad78c2014-10-13 15:51:32 -0700853 return seq_open_private(file, &ddebug_proc_seqops,
854 sizeof(struct ddebug_iter));
Jason Barone9d376f2009-02-05 11:51:38 -0500855}
856
857static const struct file_operations ddebug_proc_fops = {
858 .owner = THIS_MODULE,
859 .open = ddebug_proc_open,
860 .read = seq_read,
861 .llseek = seq_lseek,
862 .release = seq_release_private,
863 .write = ddebug_proc_write
864};
865
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800866static const struct proc_ops proc_fops = {
867 .proc_open = ddebug_proc_open,
868 .proc_read = seq_read,
869 .proc_lseek = seq_lseek,
870 .proc_release = seq_release_private,
871 .proc_write = ddebug_proc_write
872};
873
Jason Barone9d376f2009-02-05 11:51:38 -0500874/*
875 * Allocate a new ddebug_table for the given module
876 * and add it to the global list.
877 */
878int ddebug_add_module(struct _ddebug *tab, unsigned int n,
879 const char *name)
880{
881 struct ddebug_table *dt;
Jason Barone9d376f2009-02-05 11:51:38 -0500882
883 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800884 if (dt == NULL) {
885 pr_err("error adding module: %s\n", name);
Jason Barone9d376f2009-02-05 11:51:38 -0500886 return -ENOMEM;
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800887 }
Rasmus Villemoescdf6d002019-03-07 16:27:37 -0800888 /*
889 * For built-in modules, name lives in .rodata and is
890 * immortal. For loaded modules, name points at the name[]
891 * member of struct module, which lives at least as long as
892 * this struct ddebug_table.
893 */
894 dt->mod_name = name;
Jason Barone9d376f2009-02-05 11:51:38 -0500895 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500896 dt->ddebugs = tab;
897
898 mutex_lock(&ddebug_lock);
899 list_add_tail(&dt->link, &ddebug_tables);
900 mutex_unlock(&ddebug_lock);
901
Jim Cromie481c0e32020-07-19 17:10:44 -0600902 v2pr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500903 return 0;
904}
Jason Barone9d376f2009-02-05 11:51:38 -0500905
Jim Cromie6ab676e2012-04-27 14:30:37 -0600906/* helper for ddebug_dyndbg_(boot|module)_param_cb */
907static int ddebug_dyndbg_param_cb(char *param, char *val,
908 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600909{
Jim Cromieb48420c2012-04-27 14:30:35 -0600910 char *sep;
911
912 sep = strchr(param, '.');
913 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600914 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600915 *sep = '\0';
916 modname = param;
917 param = sep + 1;
918 }
919 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600920 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600921
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600922 ddebug_exec_queries((val ? val : "+p"), modname);
923
Jim Cromieb48420c2012-04-27 14:30:35 -0600924 return 0; /* query failure shouldnt stop module load */
925}
926
Jim Cromie6ab676e2012-04-27 14:30:37 -0600927/* handle both dyndbg and $module.dyndbg params at boot */
928static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -0700929 const char *unused, void *arg)
Jim Cromieb48420c2012-04-27 14:30:35 -0600930{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600931 vpr_info("%s=\"%s\"\n", param, val);
932 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
933}
Jim Cromieb48420c2012-04-27 14:30:35 -0600934
Jim Cromie6ab676e2012-04-27 14:30:37 -0600935/*
936 * modprobe foo finds foo.params in boot-args, strips "foo.", and
937 * passes them to load_module(). This callback gets unknown params,
938 * processes dyndbg params, rejects others.
939 */
940int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
941{
942 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
943 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600944}
945
Jason Barone9d376f2009-02-05 11:51:38 -0500946static void ddebug_table_free(struct ddebug_table *dt)
947{
948 list_del_init(&dt->link);
Jason Barone9d376f2009-02-05 11:51:38 -0500949 kfree(dt);
950}
951
952/*
953 * Called in response to a module being unloaded. Removes
954 * any ddebug_table's which point at the module.
955 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000956int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500957{
958 struct ddebug_table *dt, *nextdt;
959 int ret = -ENOENT;
960
Jim Cromie481c0e32020-07-19 17:10:44 -0600961 v2pr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500962
963 mutex_lock(&ddebug_lock);
964 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800965 if (dt->mod_name == mod_name) {
Jason Barone9d376f2009-02-05 11:51:38 -0500966 ddebug_table_free(dt);
967 ret = 0;
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800968 break;
Jason Barone9d376f2009-02-05 11:51:38 -0500969 }
970 }
971 mutex_unlock(&ddebug_lock);
972 return ret;
973}
Jason Barone9d376f2009-02-05 11:51:38 -0500974
975static void ddebug_remove_all_tables(void)
976{
977 mutex_lock(&ddebug_lock);
978 while (!list_empty(&ddebug_tables)) {
979 struct ddebug_table *dt = list_entry(ddebug_tables.next,
980 struct ddebug_table,
981 link);
982 ddebug_table_free(dt);
983 }
984 mutex_unlock(&ddebug_lock);
985}
986
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200987static __initdata int ddebug_init_success;
988
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800989static int __init dynamic_debug_init_control(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500990{
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800991 struct proc_dir_entry *procfs_dir;
992 struct dentry *debugfs_dir;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200993
994 if (!ddebug_init_success)
995 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -0500996
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800997 /* Create the control file in debugfs if it is enabled */
998 if (debugfs_initialized()) {
999 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
1000 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1001 &ddebug_proc_fops);
1002 }
1003
1004 /* Also create the control file in procfs */
1005 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1006 if (procfs_dir)
1007 proc_create("control", 0644, procfs_dir, &proc_fops);
Greg Kroah-Hartman9fd714c2019-06-12 17:35:34 +02001008
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001009 return 0;
1010}
1011
1012static int __init dynamic_debug_init(void)
1013{
1014 struct _ddebug *iter, *iter_start;
1015 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001016 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001017 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001018 int n = 0, entries = 0, modct = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001019
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001020 if (&__start___dyndbg == &__stop___dyndbg) {
Orson Zhaiceabef72020-06-07 21:40:14 -07001021 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1022 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1023 return 1;
1024 }
1025 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1026 ddebug_init_success = 1;
1027 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -05001028 }
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001029 iter = __start___dyndbg;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001030 modname = iter->modname;
1031 iter_start = iter;
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001032 for (; iter < __stop___dyndbg; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001033 entries++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001034 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001035 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001036 ret = ddebug_add_module(iter_start, n, modname);
1037 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001038 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001039 n = 0;
1040 modname = iter->modname;
1041 iter_start = iter;
1042 }
1043 n++;
1044 }
1045 ret = ddebug_add_module(iter_start, n, modname);
1046 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001047 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001048
Jim Cromieaf442392012-04-27 14:30:38 -06001049 ddebug_init_success = 1;
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001050 vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in __dyndbg section\n",
Joe Perchesf657fd22012-12-05 16:48:26 -05001051 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001052 (int)(entries * sizeof(struct _ddebug)));
Jim Cromieaf442392012-04-27 14:30:38 -06001053
1054 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001055 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001056 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001057 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001058 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001059 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001060 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001061 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001062 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001063 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001064 /* now that ddebug tables are loaded, process all boot args
1065 * again to find and activate queries given in dyndbg params.
1066 * While this has already been done for known boot params, it
1067 * ignored the unknown ones (dyndbg in particular). Reusing
1068 * parse_args avoids ad-hoc parsing. This will also attempt
1069 * to activate queries for not-yet-loaded modules, which is
1070 * slightly noisy if verbose, but harmless.
1071 */
1072 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1073 parse_args("dyndbg params", cmdline, NULL,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -07001074 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
Jim Cromieb48420c2012-04-27 14:30:35 -06001075 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001076 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001077
Jim Cromieaf442392012-04-27 14:30:38 -06001078out_err:
1079 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001080 return 0;
1081}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001082/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001083early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001084
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001085/* Debugfs setup must be done later */
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001086fs_initcall(dynamic_debug_init_control);