blob: da3ed54a6521160535dc9e0234ccdfebf9825741 [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
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600334 if (modname)
335 /* support $modname.dyndbg=<multiple queries> */
336 query->module = modname;
337
Joe Perchesf657fd22012-12-05 16:48:26 -0500338 for (i = 0; i < nwords; i += 2) {
339 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500340 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500341 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500342 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500343 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500344 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500345 } else if (!strcmp(words[i], "format")) {
Andy Shevchenkod338b132013-04-30 15:27:32 -0700346 string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
347 UNESCAPE_OCTAL |
348 UNESCAPE_SPECIAL);
349 rc = check_set(&query->format, words[i+1], "format");
Joe Perchesf657fd22012-12-05 16:48:26 -0500350 } else if (!strcmp(words[i], "line")) {
Jason Barone9d376f2009-02-05 11:51:38 -0500351 char *first = words[i+1];
352 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500353 if (query->first_lineno || query->last_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500354 pr_err("match-spec: line used 2x\n");
Jim Cromie820874c2011-12-19 17:12:49 -0500355 return -EINVAL;
356 }
Jason Barone9d376f2009-02-05 11:51:38 -0500357 if (last)
358 *last++ = '\0';
Andrey Ryabinind9e133e2014-01-27 17:06:57 -0800359 if (parse_lineno(first, &query->first_lineno) < 0)
Jason Barone9d376f2009-02-05 11:51:38 -0500360 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500361 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500362 /* range <first>-<last> */
Andrey Ryabinin3ace6782014-01-27 17:06:58 -0800363 if (parse_lineno(last, &query->last_lineno) < 0)
364 return -EINVAL;
365
Randy Dunlap1f3c7902017-11-17 15:27:35 -0800366 /* special case for last lineno not specified */
367 if (query->last_lineno == 0)
368 query->last_lineno = UINT_MAX;
369
Andrey Ryabinin3ace6782014-01-27 17:06:58 -0800370 if (query->last_lineno < query->first_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500371 pr_err("last-line:%d < 1st-line:%d\n",
372 query->last_lineno,
373 query->first_lineno);
Jason Barone9d376f2009-02-05 11:51:38 -0500374 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500375 }
Jason Barone9d376f2009-02-05 11:51:38 -0500376 } else {
377 query->last_lineno = query->first_lineno;
378 }
379 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500380 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500381 return -EINVAL;
382 }
Jim Cromie820874c2011-12-19 17:12:49 -0500383 if (rc)
384 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500385 }
Jim Cromie574b3722011-12-19 17:13:16 -0500386 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500387 return 0;
388}
389
390/*
391 * Parse `str' as a flags specification, format [-+=][p]+.
392 * Sets up *maskp and *flagsp to be used when changing the
393 * flags fields of matched _ddebug's. Returns 0 on success
394 * or <0 on error.
395 */
396static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
397 unsigned int *maskp)
398{
399 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100400 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500401
402 switch (*str) {
403 case '+':
404 case '-':
405 case '=':
406 op = *str++;
407 break;
408 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500409 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500410 return -EINVAL;
411 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600412 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500413
Joe Perchesf657fd22012-12-05 16:48:26 -0500414 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100415 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
416 if (*str == opt_array[i].opt_char) {
417 flags |= opt_array[i].flag;
418 break;
419 }
Jason Barone9d376f2009-02-05 11:51:38 -0500420 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500421 if (i < 0) {
Jim Cromie0b8f96b2020-07-19 17:10:48 -0600422 pr_err("unknown flag '%c'\n", *str);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100423 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500424 }
Jason Barone9d376f2009-02-05 11:51:38 -0500425 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600426 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500427
428 /* calculate final *flagsp, *maskp according to mask and op */
429 switch (op) {
430 case '=':
431 *maskp = 0;
432 *flagsp = flags;
433 break;
434 case '+':
435 *maskp = ~0U;
436 *flagsp = flags;
437 break;
438 case '-':
439 *maskp = ~flags;
440 *flagsp = 0;
441 break;
442 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600443 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500444 return 0;
445}
446
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600447static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200448{
449 unsigned int flags = 0, mask = 0;
Jim Cromie9c9d0ac2020-07-19 17:10:49 -0600450 struct ddebug_query query = {};
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200451#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500452 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200453 char *words[MAXWORDS];
454
455 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500456 if (nwords <= 0) {
457 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200458 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500459 }
460 /* check flags 1st (last arg) so query is pairs of spec,val */
461 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
462 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200463 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500464 }
465 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
466 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200467 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500468 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200469 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500470 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500471 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500472
473 return nfound;
474}
475
476/* handle multiple queries in query string, continue on error, return
477 last error or number of matching callsites. Module name is either
478 in param (for boot arg) or perhaps in query string.
479*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600480static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500481{
482 char *split;
483 int i, errs = 0, exitcode = 0, rc, nfound = 0;
484
485 for (i = 0; query; query = split) {
486 split = strpbrk(query, ";\n");
487 if (split)
488 *split++ = '\0';
489
490 query = skip_spaces(query);
491 if (!query || !*query || *query == '#')
492 continue;
493
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600494 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500495
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600496 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500497 if (rc < 0) {
498 errs++;
499 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500500 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500501 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500502 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500503 i++;
504 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600505 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500506 i, nfound, errs);
507
508 if (exitcode)
509 return exitcode;
510 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200511}
512
Jason Baron431625d2011-10-04 14:13:19 -0700513#define PREFIX_SIZE 64
514
515static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100516{
Jason Baron431625d2011-10-04 14:13:19 -0700517 if (PREFIX_SIZE - wrote > 0)
518 return PREFIX_SIZE - wrote;
519 return 0;
520}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100521
Jason Baron431625d2011-10-04 14:13:19 -0700522static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
523{
524 int pos_after_tid;
525 int pos = 0;
526
Joe Perches798efc62012-09-12 20:11:29 -0700527 *buf = '\0';
528
Jason Baron431625d2011-10-04 14:13:19 -0700529 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100530 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700531 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100532 else
Jason Baron431625d2011-10-04 14:13:19 -0700533 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700534 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100535 }
Jason Baron431625d2011-10-04 14:13:19 -0700536 pos_after_tid = pos;
537 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
538 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700539 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700540 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
541 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700542 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700543 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500544 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700545 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700546 if (pos - pos_after_tid)
547 pos += snprintf(buf + pos, remaining(pos), " ");
548 if (pos >= PREFIX_SIZE)
549 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400550
Jason Baron431625d2011-10-04 14:13:19 -0700551 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400552}
553
Joe Perches906d2012014-09-24 11:17:56 -0700554void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100555{
556 va_list args;
Jason Baron431625d2011-10-04 14:13:19 -0700557 struct va_format vaf;
558 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100559
560 BUG_ON(!descriptor);
561 BUG_ON(!fmt);
562
563 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700564
Jason Baron431625d2011-10-04 14:13:19 -0700565 vaf.fmt = fmt;
566 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700567
Joe Perches906d2012014-09-24 11:17:56 -0700568 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700569
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100570 va_end(args);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100571}
572EXPORT_SYMBOL(__dynamic_pr_debug);
573
Joe Perches906d2012014-09-24 11:17:56 -0700574void __dynamic_dev_dbg(struct _ddebug *descriptor,
Joe Perchescbc46632011-08-11 14:36:21 -0400575 const struct device *dev, const char *fmt, ...)
576{
577 struct va_format vaf;
578 va_list args;
Joe Perchescbc46632011-08-11 14:36:21 -0400579
580 BUG_ON(!descriptor);
581 BUG_ON(!fmt);
582
583 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700584
Joe Perchescbc46632011-08-11 14:36:21 -0400585 vaf.fmt = fmt;
586 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700587
588 if (!dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700589 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700590 } else {
591 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700592
Joe Perchesa39d4a82014-12-10 15:50:15 -0800593 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
Joe Perches906d2012014-09-24 11:17:56 -0700594 dynamic_emit_prefix(descriptor, buf),
595 dev_driver_string(dev), dev_name(dev),
596 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700597 }
598
Joe Perchescbc46632011-08-11 14:36:21 -0400599 va_end(args);
Joe Perchescbc46632011-08-11 14:36:21 -0400600}
601EXPORT_SYMBOL(__dynamic_dev_dbg);
602
Jason Baron0feefd92011-10-04 14:13:22 -0700603#ifdef CONFIG_NET
604
Joe Perches906d2012014-09-24 11:17:56 -0700605void __dynamic_netdev_dbg(struct _ddebug *descriptor,
606 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400607{
608 struct va_format vaf;
609 va_list args;
Jason Baronffa10cb2011-08-11 14:36:48 -0400610
611 BUG_ON(!descriptor);
612 BUG_ON(!fmt);
613
614 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700615
Jason Baronffa10cb2011-08-11 14:36:48 -0400616 vaf.fmt = fmt;
617 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700618
619 if (dev && dev->dev.parent) {
620 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700621
Joe Perchesa39d4a82014-12-10 15:50:15 -0800622 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
Joe Perches906d2012014-09-24 11:17:56 -0700623 "%s%s %s %s%s: %pV",
624 dynamic_emit_prefix(descriptor, buf),
625 dev_driver_string(dev->dev.parent),
626 dev_name(dev->dev.parent),
627 netdev_name(dev), netdev_reg_state(dev),
628 &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700629 } else if (dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700630 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
631 netdev_reg_state(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700632 } else {
Joe Perches906d2012014-09-24 11:17:56 -0700633 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700634 }
635
Jason Baronffa10cb2011-08-11 14:36:48 -0400636 va_end(args);
Jason Baronffa10cb2011-08-11 14:36:48 -0400637}
638EXPORT_SYMBOL(__dynamic_netdev_dbg);
639
Jason Baron0feefd92011-10-04 14:13:22 -0700640#endif
641
Gal Pressman923abb92019-05-01 13:48:13 +0300642#if IS_ENABLED(CONFIG_INFINIBAND)
643
644void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
645 const struct ib_device *ibdev, const char *fmt, ...)
646{
647 struct va_format vaf;
648 va_list args;
649
650 va_start(args, fmt);
651
652 vaf.fmt = fmt;
653 vaf.va = &args;
654
655 if (ibdev && ibdev->dev.parent) {
656 char buf[PREFIX_SIZE];
657
658 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
659 "%s%s %s %s: %pV",
660 dynamic_emit_prefix(descriptor, buf),
661 dev_driver_string(ibdev->dev.parent),
662 dev_name(ibdev->dev.parent),
663 dev_name(&ibdev->dev),
664 &vaf);
665 } else if (ibdev) {
666 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
667 } else {
668 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
669 }
670
671 va_end(args);
672}
673EXPORT_SYMBOL(__dynamic_ibdev_dbg);
674
675#endif
676
Jim Cromiebc757f62011-12-19 17:12:29 -0500677#define DDEBUG_STRING_SIZE 1024
678static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
679
Thomas Renningera648ec02010-08-06 16:11:02 +0200680static __init int ddebug_setup_query(char *str)
681{
Jim Cromiebc757f62011-12-19 17:12:29 -0500682 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400683 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200684 return 0;
685 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500686 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200687 return 1;
688}
689
690__setup("ddebug_query=", ddebug_setup_query);
691
Jason Barone9d376f2009-02-05 11:51:38 -0500692/*
Masatake YAMATO231821d2014-12-15 12:04:16 +0900693 * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
Jason Barone9d376f2009-02-05 11:51:38 -0500694 * command text from userspace, parses and executes it.
695 */
Jim Cromie72814912011-12-19 17:13:07 -0500696#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500697static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
698 size_t len, loff_t *offp)
699{
Jim Cromie72814912011-12-19 17:13:07 -0500700 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200701 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500702
703 if (len == 0)
704 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500705 if (len > USER_BUF_PAGE - 1) {
706 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500707 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500708 }
Al Viro16e5c1f2015-12-24 00:06:05 -0500709 tmpbuf = memdup_user_nul(ubuf, len);
710 if (IS_ERR(tmpbuf))
711 return PTR_ERR(tmpbuf);
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600712 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500713
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600714 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500715 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500716 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200717 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500718
719 *offp += len;
720 return len;
721}
722
723/*
724 * Set the iterator to point to the first _ddebug object
725 * and return a pointer to that first object. Returns
726 * NULL if there are no _ddebugs at all.
727 */
728static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
729{
730 if (list_empty(&ddebug_tables)) {
731 iter->table = NULL;
732 iter->idx = 0;
733 return NULL;
734 }
735 iter->table = list_entry(ddebug_tables.next,
736 struct ddebug_table, link);
737 iter->idx = 0;
738 return &iter->table->ddebugs[iter->idx];
739}
740
741/*
742 * Advance the iterator to point to the next _ddebug
743 * object from the one the iterator currently points at,
744 * and returns a pointer to the new _ddebug. Returns
745 * NULL if the iterator has seen all the _ddebugs.
746 */
747static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
748{
749 if (iter->table == NULL)
750 return NULL;
751 if (++iter->idx == iter->table->num_ddebugs) {
752 /* iterate to next table */
753 iter->idx = 0;
754 if (list_is_last(&iter->table->link, &ddebug_tables)) {
755 iter->table = NULL;
756 return NULL;
757 }
758 iter->table = list_entry(iter->table->link.next,
759 struct ddebug_table, link);
760 }
761 return &iter->table->ddebugs[iter->idx];
762}
763
764/*
765 * Seq_ops start method. Called at the start of every
766 * read() call from userspace. Takes the ddebug_lock and
767 * seeks the seq_file's iterator to the given position.
768 */
769static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
770{
771 struct ddebug_iter *iter = m->private;
772 struct _ddebug *dp;
773 int n = *pos;
774
Jason Barone9d376f2009-02-05 11:51:38 -0500775 mutex_lock(&ddebug_lock);
776
777 if (!n)
778 return SEQ_START_TOKEN;
779 if (n < 0)
780 return NULL;
781 dp = ddebug_iter_first(iter);
782 while (dp != NULL && --n > 0)
783 dp = ddebug_iter_next(iter);
784 return dp;
785}
786
787/*
788 * Seq_ops next method. Called several times within a read()
789 * call from userspace, with ddebug_lock held. Walks to the
790 * next _ddebug object with a special case for the header line.
791 */
792static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
793{
794 struct ddebug_iter *iter = m->private;
795 struct _ddebug *dp;
796
Jason Barone9d376f2009-02-05 11:51:38 -0500797 if (p == SEQ_START_TOKEN)
798 dp = ddebug_iter_first(iter);
799 else
800 dp = ddebug_iter_next(iter);
801 ++*pos;
802 return dp;
803}
804
805/*
806 * Seq_ops show method. Called several times within a read()
807 * call from userspace, with ddebug_lock held. Formats the
808 * current _ddebug as a single human-readable line, with a
809 * special case for the header line.
810 */
811static int ddebug_proc_show(struct seq_file *m, void *p)
812{
813 struct ddebug_iter *iter = m->private;
814 struct _ddebug *dp = p;
Jim Cromief678ce82020-07-19 17:10:47 -0600815 struct flagsbuf flags;
Jason Barone9d376f2009-02-05 11:51:38 -0500816
Jason Barone9d376f2009-02-05 11:51:38 -0500817 if (p == SEQ_START_TOKEN) {
818 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500819 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500820 return 0;
821 }
822
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500823 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500824 trim_prefix(dp->filename), dp->lineno,
825 iter->table->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600826 ddebug_describe_flags(dp->flags, &flags));
Jason Barone9d376f2009-02-05 11:51:38 -0500827 seq_escape(m, dp->format, "\t\r\n\"");
828 seq_puts(m, "\"\n");
829
830 return 0;
831}
832
833/*
834 * Seq_ops stop method. Called at the end of each read()
835 * call from userspace. Drops ddebug_lock.
836 */
837static void ddebug_proc_stop(struct seq_file *m, void *p)
838{
Jason Barone9d376f2009-02-05 11:51:38 -0500839 mutex_unlock(&ddebug_lock);
840}
841
842static const struct seq_operations ddebug_proc_seqops = {
843 .start = ddebug_proc_start,
844 .next = ddebug_proc_next,
845 .show = ddebug_proc_show,
846 .stop = ddebug_proc_stop
847};
848
Jason Barone9d376f2009-02-05 11:51:38 -0500849static int ddebug_proc_open(struct inode *inode, struct file *file)
850{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600851 vpr_info("called\n");
Rob Jones4bad78c2014-10-13 15:51:32 -0700852 return seq_open_private(file, &ddebug_proc_seqops,
853 sizeof(struct ddebug_iter));
Jason Barone9d376f2009-02-05 11:51:38 -0500854}
855
856static const struct file_operations ddebug_proc_fops = {
857 .owner = THIS_MODULE,
858 .open = ddebug_proc_open,
859 .read = seq_read,
860 .llseek = seq_lseek,
861 .release = seq_release_private,
862 .write = ddebug_proc_write
863};
864
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800865static const struct proc_ops proc_fops = {
866 .proc_open = ddebug_proc_open,
867 .proc_read = seq_read,
868 .proc_lseek = seq_lseek,
869 .proc_release = seq_release_private,
870 .proc_write = ddebug_proc_write
871};
872
Jason Barone9d376f2009-02-05 11:51:38 -0500873/*
874 * Allocate a new ddebug_table for the given module
875 * and add it to the global list.
876 */
877int ddebug_add_module(struct _ddebug *tab, unsigned int n,
878 const char *name)
879{
880 struct ddebug_table *dt;
Jason Barone9d376f2009-02-05 11:51:38 -0500881
882 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800883 if (dt == NULL) {
884 pr_err("error adding module: %s\n", name);
Jason Barone9d376f2009-02-05 11:51:38 -0500885 return -ENOMEM;
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800886 }
Rasmus Villemoescdf6d002019-03-07 16:27:37 -0800887 /*
888 * For built-in modules, name lives in .rodata and is
889 * immortal. For loaded modules, name points at the name[]
890 * member of struct module, which lives at least as long as
891 * this struct ddebug_table.
892 */
893 dt->mod_name = name;
Jason Barone9d376f2009-02-05 11:51:38 -0500894 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500895 dt->ddebugs = tab;
896
897 mutex_lock(&ddebug_lock);
898 list_add_tail(&dt->link, &ddebug_tables);
899 mutex_unlock(&ddebug_lock);
900
Jim Cromie481c0e32020-07-19 17:10:44 -0600901 v2pr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500902 return 0;
903}
Jason Barone9d376f2009-02-05 11:51:38 -0500904
Jim Cromie6ab676e2012-04-27 14:30:37 -0600905/* helper for ddebug_dyndbg_(boot|module)_param_cb */
906static int ddebug_dyndbg_param_cb(char *param, char *val,
907 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600908{
Jim Cromieb48420c2012-04-27 14:30:35 -0600909 char *sep;
910
911 sep = strchr(param, '.');
912 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600913 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600914 *sep = '\0';
915 modname = param;
916 param = sep + 1;
917 }
918 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600919 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600920
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600921 ddebug_exec_queries((val ? val : "+p"), modname);
922
Jim Cromieb48420c2012-04-27 14:30:35 -0600923 return 0; /* query failure shouldnt stop module load */
924}
925
Jim Cromie6ab676e2012-04-27 14:30:37 -0600926/* handle both dyndbg and $module.dyndbg params at boot */
927static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -0700928 const char *unused, void *arg)
Jim Cromieb48420c2012-04-27 14:30:35 -0600929{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600930 vpr_info("%s=\"%s\"\n", param, val);
931 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
932}
Jim Cromieb48420c2012-04-27 14:30:35 -0600933
Jim Cromie6ab676e2012-04-27 14:30:37 -0600934/*
935 * modprobe foo finds foo.params in boot-args, strips "foo.", and
936 * passes them to load_module(). This callback gets unknown params,
937 * processes dyndbg params, rejects others.
938 */
939int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
940{
941 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
942 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600943}
944
Jason Barone9d376f2009-02-05 11:51:38 -0500945static void ddebug_table_free(struct ddebug_table *dt)
946{
947 list_del_init(&dt->link);
Jason Barone9d376f2009-02-05 11:51:38 -0500948 kfree(dt);
949}
950
951/*
952 * Called in response to a module being unloaded. Removes
953 * any ddebug_table's which point at the module.
954 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000955int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500956{
957 struct ddebug_table *dt, *nextdt;
958 int ret = -ENOENT;
959
Jim Cromie481c0e32020-07-19 17:10:44 -0600960 v2pr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500961
962 mutex_lock(&ddebug_lock);
963 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800964 if (dt->mod_name == mod_name) {
Jason Barone9d376f2009-02-05 11:51:38 -0500965 ddebug_table_free(dt);
966 ret = 0;
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800967 break;
Jason Barone9d376f2009-02-05 11:51:38 -0500968 }
969 }
970 mutex_unlock(&ddebug_lock);
971 return ret;
972}
Jason Barone9d376f2009-02-05 11:51:38 -0500973
974static void ddebug_remove_all_tables(void)
975{
976 mutex_lock(&ddebug_lock);
977 while (!list_empty(&ddebug_tables)) {
978 struct ddebug_table *dt = list_entry(ddebug_tables.next,
979 struct ddebug_table,
980 link);
981 ddebug_table_free(dt);
982 }
983 mutex_unlock(&ddebug_lock);
984}
985
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200986static __initdata int ddebug_init_success;
987
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800988static int __init dynamic_debug_init_control(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500989{
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800990 struct proc_dir_entry *procfs_dir;
991 struct dentry *debugfs_dir;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200992
993 if (!ddebug_init_success)
994 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -0500995
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800996 /* Create the control file in debugfs if it is enabled */
997 if (debugfs_initialized()) {
998 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
999 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1000 &ddebug_proc_fops);
1001 }
1002
1003 /* Also create the control file in procfs */
1004 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1005 if (procfs_dir)
1006 proc_create("control", 0644, procfs_dir, &proc_fops);
Greg Kroah-Hartman9fd714c2019-06-12 17:35:34 +02001007
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001008 return 0;
1009}
1010
1011static int __init dynamic_debug_init(void)
1012{
1013 struct _ddebug *iter, *iter_start;
1014 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001015 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001016 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001017 int n = 0, entries = 0, modct = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001018
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001019 if (&__start___dyndbg == &__stop___dyndbg) {
Orson Zhaiceabef72020-06-07 21:40:14 -07001020 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1021 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1022 return 1;
1023 }
1024 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1025 ddebug_init_success = 1;
1026 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -05001027 }
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001028 iter = __start___dyndbg;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001029 modname = iter->modname;
1030 iter_start = iter;
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001031 for (; iter < __stop___dyndbg; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001032 entries++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001033 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001034 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001035 ret = ddebug_add_module(iter_start, n, modname);
1036 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001037 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001038 n = 0;
1039 modname = iter->modname;
1040 iter_start = iter;
1041 }
1042 n++;
1043 }
1044 ret = ddebug_add_module(iter_start, n, modname);
1045 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001046 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001047
Jim Cromieaf442392012-04-27 14:30:38 -06001048 ddebug_init_success = 1;
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001049 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 -05001050 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001051 (int)(entries * sizeof(struct _ddebug)));
Jim Cromieaf442392012-04-27 14:30:38 -06001052
1053 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001054 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001055 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001056 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001057 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001058 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001059 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001060 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001061 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001062 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001063 /* now that ddebug tables are loaded, process all boot args
1064 * again to find and activate queries given in dyndbg params.
1065 * While this has already been done for known boot params, it
1066 * ignored the unknown ones (dyndbg in particular). Reusing
1067 * parse_args avoids ad-hoc parsing. This will also attempt
1068 * to activate queries for not-yet-loaded modules, which is
1069 * slightly noisy if verbose, but harmless.
1070 */
1071 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1072 parse_args("dyndbg params", cmdline, NULL,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -07001073 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
Jim Cromieb48420c2012-04-27 14:30:35 -06001074 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001075 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001076
Jim Cromieaf442392012-04-27 14:30:38 -06001077out_err:
1078 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001079 return 0;
1080}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001081/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001082early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001083
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001084/* Debugfs setup must be done later */
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001085fs_initcall(dynamic_debug_init_control);