e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 2) * lib/dynamic_debug.c
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 3) *
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 4) * make pr_debug()/dev_dbg() calls runtime configurable based upon their
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 5) * source module.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 6) *
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 7) * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 8) * By Greg Banks <gnb@melbourne.sgi.com>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 9) * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved.
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 10) * Copyright (C) 2011 Bart Van Assche. All Rights Reserved.
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 11) * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 12) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 13)
5aa9ffbbaeb3a (Jim Cromie 2020-07-19 17:10:57 -0600 14) #define pr_fmt(fmt) "dyndbg: " fmt
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 15)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 16) #include <linux/kernel.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 17) #include <linux/module.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 18) #include <linux/moduleparam.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 19) #include <linux/kallsyms.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 20) #include <linux/types.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 21) #include <linux/mutex.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 22) #include <linux/proc_fs.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 23) #include <linux/seq_file.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 24) #include <linux/list.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 25) #include <linux/sysctl.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 26) #include <linux/ctype.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 27) #include <linux/string.h>
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 28) #include <linux/parser.h>
d338b1379f96b (Andy Shevchenko 2013-04-30 15:27:32 -0700 29) #include <linux/string_helpers.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 30) #include <linux/uaccess.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 31) #include <linux/dynamic_debug.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 32) #include <linux/debugfs.h>
5a0e3ad6af866 (Tejun Heo 2010-03-24 17:04:11 +0900 33) #include <linux/slab.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 34) #include <linux/jump_label.h>
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 35) #include <linux/hardirq.h>
e8d9792aa514e (Greg Kroah-Hartman 2011-02-03 15:59:58 -0800 36) #include <linux/sched.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700 37) #include <linux/device.h>
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 38) #include <linux/netdevice.h>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 39)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 40) #include <rdma/ib_verbs.h>
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 41)
e5ebffe18e5ad (Jim Cromie 2020-07-19 17:10:45 -0600 42) extern struct _ddebug __start___dyndbg[];
e5ebffe18e5ad (Jim Cromie 2020-07-19 17:10:45 -0600 43) extern struct _ddebug __stop___dyndbg[];
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 44)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 45) struct ddebug_table {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 46) struct list_head link;
3e406b1d7c1e5 (Rasmus Villemoes 2015-11-06 16:30:15 -0800 47) const char *mod_name;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 48) unsigned int num_ddebugs;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 49) struct _ddebug *ddebugs;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 50) };
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 51)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 52) struct ddebug_query {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 53) const char *filename;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 54) const char *module;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 55) const char *function;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 56) const char *format;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 57) unsigned int first_lineno, last_lineno;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 58) };
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 59)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 60) struct ddebug_iter {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 61) struct ddebug_table *table;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 62) unsigned int idx;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 63) };
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 64)
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 65) struct flag_settings {
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 66) unsigned int flags;
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 67) unsigned int mask;
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 68) };
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 69)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 70) static DEFINE_MUTEX(ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 71) static LIST_HEAD(ddebug_tables);
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 72) static int verbose;
74df138d508eb (Jim Cromie 2011-12-19 17:12:24 -0500 73) module_param(verbose, int, 0644);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 74)
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 75) /* Return the path relative to source root */
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 76) static inline const char *trim_prefix(const char *path)
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 77) {
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 78) int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 79)
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 80) if (strncmp(path, __FILE__, skip))
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 81) skip = 0; /* prefix mismatch, don't skip */
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 82)
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 83) return path + skip;
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 84) }
2b6783191da72 (Jim Cromie 2011-12-19 17:13:12 -0500 85)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 86) static struct { unsigned flag:8; char opt_char; } opt_array[] = {
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 87) { _DPRINTK_FLAGS_PRINT, 'p' },
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 88) { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 89) { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 90) { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 91) { _DPRINTK_FLAGS_INCL_TID, 't' },
5ca7d2a6c5e4f (Jim Cromie 2011-12-19 17:12:44 -0500 92) { _DPRINTK_FLAGS_NONE, '_' },
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 93) };
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 94)
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 95) struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 96)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 97) /* format a string into buf[] which describes the _ddebug's flags */
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 98) static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 99) {
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 100) char *p = fb->buf;
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 101) int i;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 102)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 103) for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 104) if (flags & opt_array[i].flag)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 105) *p++ = opt_array[i].opt_char;
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 106) if (p == fb->buf)
5ca7d2a6c5e4f (Jim Cromie 2011-12-19 17:12:44 -0500 107) *p++ = '_';
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 108) *p = '\0';
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 109)
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 110) return fb->buf;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 111) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 112)
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 113) #define vnpr_info(lvl, fmt, ...) \
b8ccd5dee776d (Jim Cromie 2012-04-27 14:30:32 -0600 114) do { \
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 115) if (verbose >= lvl) \
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 116) pr_info(fmt, ##__VA_ARGS__); \
574b3725e3275 (Jim Cromie 2011-12-19 17:13:16 -0500 117) } while (0)
574b3725e3275 (Jim Cromie 2011-12-19 17:13:16 -0500 118)
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 119) #define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__)
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 120) #define v2pr_info(fmt, ...) vnpr_info(2, fmt, ##__VA_ARGS__)
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 121)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 122) static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 123) {
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 124) /* trim any trailing newlines */
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 125) int fmtlen = 0;
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 126)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 127) if (query->format) {
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 128) fmtlen = strlen(query->format);
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 129) while (fmtlen && query->format[fmtlen - 1] == '\n')
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 130) fmtlen--;
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 131) }
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 132)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 133) vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 134) msg,
f62fc08fdc51d (Jim Cromie 2020-07-19 17:10:51 -0600 135) query->function ?: "",
f62fc08fdc51d (Jim Cromie 2020-07-19 17:10:51 -0600 136) query->filename ?: "",
f62fc08fdc51d (Jim Cromie 2020-07-19 17:10:51 -0600 137) query->module ?: "",
f62fc08fdc51d (Jim Cromie 2020-07-19 17:10:51 -0600 138) fmtlen, query->format ?: "",
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 139) query->first_lineno, query->last_lineno);
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 140) }
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 141)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 142) /*
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 143) * Search the tables for _ddebug's which match the given `query' and
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 144) * apply the `flags' and `mask' to them. Returns number of matching
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 145) * callsites, normally the same as number of changes. If verbose,
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 146) * logs the changes. Takes ddebug_lock.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 147) */
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 148) static int ddebug_change(const struct ddebug_query *query,
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 149) struct flag_settings *modifiers)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 150) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 151) int i;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 152) struct ddebug_table *dt;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 153) unsigned int newflags;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 154) unsigned int nfound = 0;
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 155) struct flagsbuf fbuf;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 156)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 157) /* search for matching ddebugs */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 158) mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 159) list_for_each_entry(dt, &ddebug_tables, link) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 160)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 161) /* match against the module name */
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 162) if (query->module &&
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 163) !match_wildcard(query->module, dt->mod_name))
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 164) continue;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 165)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 166) for (i = 0; i < dt->num_ddebugs; i++) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 167) struct _ddebug *dp = &dt->ddebugs[i];
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 168)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 169) /* match against the source filename */
d6a238d25014d (Jim Cromie 2011-12-19 17:12:39 -0500 170) if (query->filename &&
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 171) !match_wildcard(query->filename, dp->filename) &&
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 172) !match_wildcard(query->filename,
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 173) kbasename(dp->filename)) &&
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 174) !match_wildcard(query->filename,
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 175) trim_prefix(dp->filename)))
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 176) continue;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 177)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 178) /* match against the function */
d6a238d25014d (Jim Cromie 2011-12-19 17:12:39 -0500 179) if (query->function &&
578b1e0701af3 (Changbin Du 2014-01-23 15:54:14 -0800 180) !match_wildcard(query->function, dp->function))
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 181) continue;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 182)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 183) /* match against the format */
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 184) if (query->format) {
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 185) if (*query->format == '^') {
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 186) char *p;
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 187) /* anchored search. match must be at beginning */
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 188) p = strstr(dp->format, query->format+1);
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 189) if (p != dp->format)
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 190) continue;
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 191) } else if (!strstr(dp->format, query->format))
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 192) continue;
4b334484fa7f4 (Jim Cromie 2020-07-19 17:10:56 -0600 193) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 194)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 195) /* match against the line number range */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 196) if (query->first_lineno &&
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 197) dp->lineno < query->first_lineno)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 198) continue;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 199) if (query->last_lineno &&
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 200) dp->lineno > query->last_lineno)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 201) continue;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 202)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 203) nfound++;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 204)
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 205) newflags = (dp->flags & modifiers->mask) | modifiers->flags;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 206) if (newflags == dp->flags)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 207) continue;
e9666d10a5677 (Masahiro Yamada 2018-12-31 00:14:15 +0900 208) #ifdef CONFIG_JUMP_LABEL
9049fc745300c (Jason Baron 2016-08-03 13:46:39 -0700 209) if (dp->flags & _DPRINTK_FLAGS_PRINT) {
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 210) if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
9049fc745300c (Jason Baron 2016-08-03 13:46:39 -0700 211) static_branch_disable(&dp->key.dd_key_true);
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 212) } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
9049fc745300c (Jason Baron 2016-08-03 13:46:39 -0700 213) static_branch_enable(&dp->key.dd_key_true);
9049fc745300c (Jason Baron 2016-08-03 13:46:39 -0700 214) #endif
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 215) dp->flags = newflags;
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 216) v2pr_info("changed %s:%d [%s]%s =%s\n",
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 217) trim_prefix(dp->filename), dp->lineno,
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 218) dt->mod_name, dp->function,
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 219) ddebug_describe_flags(dp->flags, &fbuf));
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 220) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 221) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 222) mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 223)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 224) if (!nfound && verbose)
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 225) pr_info("no matches for query\n");
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 226)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 227) return nfound;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 228) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 229)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 230) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 231) * Split the buffer `buf' into space-separated words.
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 232) * Handles simple " and ' quoting, i.e. without nested,
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 233) * embedded or escaped \". Return the number of words
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 234) * or <0 on error.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 235) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 236) static int ddebug_tokenize(char *buf, char *words[], int maxwords)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 237) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 238) int nwords = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 239)
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 240) while (*buf) {
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 241) char *end;
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 242)
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 243) /* Skip leading whitespace */
e7d2860b690d4 (André Goddard Rosa 2009-12-14 18:01:06 -0800 244) buf = skip_spaces(buf);
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 245) if (!*buf)
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 246) break; /* oh, it was trailing whitespace */
8bd6026e88cb2 (Jim Cromie 2011-12-19 17:13:03 -0500 247) if (*buf == '#')
8bd6026e88cb2 (Jim Cromie 2011-12-19 17:13:03 -0500 248) break; /* token starts comment, skip rest of line */
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 249)
07100be7e0495 (Jim Cromie 2011-12-19 17:11:09 -0500 250) /* find `end' of word, whitespace separated or quoted */
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 251) if (*buf == '"' || *buf == '\'') {
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 252) int quote = *buf++;
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 253) for (end = buf; *end && *end != quote; end++)
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 254) ;
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 255) if (!*end) {
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 256) pr_err("unclosed quote: %s\n", buf);
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 257) return -EINVAL; /* unclosed quote */
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 258) }
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 259) } else {
7f6e1f3072b68 (Greg Kroah-Hartman 2020-09-10 18:42:38 +0200 260) for (end = buf; *end && !isspace(*end); end++)
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 261) ;
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 262) BUG_ON(end == buf);
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 263) }
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 264)
07100be7e0495 (Jim Cromie 2011-12-19 17:11:09 -0500 265) /* `buf' is start of word, `end' is one past its end */
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 266) if (nwords == maxwords) {
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 267) pr_err("too many words, legal max <=%d\n", maxwords);
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 268) return -EINVAL; /* ran out of words[] before bytes */
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 269) }
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 270) if (*end)
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 271) *end++ = '\0'; /* terminate the word */
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 272) words[nwords++] = buf;
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 273) buf = end;
9898abb3d2331 (Greg Banks 2009-02-06 12:54:26 +1100 274) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 275)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 276) if (verbose) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 277) int i;
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 278) pr_info("split into words:");
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 279) for (i = 0; i < nwords; i++)
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 280) pr_cont(" \"%s\"", words[i]);
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 281) pr_cont("\n");
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 282) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 283)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 284) return nwords;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 285) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 286)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 287) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 288) * Parse a single line number. Note that the empty string ""
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 289) * is treated as a special case and converted to zero, which
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 290) * is later treated as a "don't care" value.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 291) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 292) static inline int parse_lineno(const char *str, unsigned int *val)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 293) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 294) BUG_ON(str == NULL);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 295) if (*str == '\0') {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 296) *val = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 297) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 298) }
4592599af36f5 (Andrey Ryabinin 2014-01-27 17:06:59 -0800 299) if (kstrtouint(str, 10, val) < 0) {
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 300) pr_err("bad line-number: %s\n", str);
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 301) return -EINVAL;
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 302) }
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 303) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 304) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 305)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 306) static int parse_linerange(struct ddebug_query *query, const char *first)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 307) {
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 308) char *last = strchr(first, '-');
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 309)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 310) if (query->first_lineno || query->last_lineno) {
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 311) pr_err("match-spec: line used 2x\n");
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 312) return -EINVAL;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 313) }
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 314) if (last)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 315) *last++ = '\0';
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 316) if (parse_lineno(first, &query->first_lineno) < 0)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 317) return -EINVAL;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 318) if (last) {
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 319) /* range <first>-<last> */
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 320) if (parse_lineno(last, &query->last_lineno) < 0)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 321) return -EINVAL;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 322)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 323) /* special case for last lineno not specified */
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 324) if (query->last_lineno == 0)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 325) query->last_lineno = UINT_MAX;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 326)
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 327) if (query->last_lineno < query->first_lineno) {
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 328) pr_err("last-line:%d < 1st-line:%d\n",
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 329) query->last_lineno,
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 330) query->first_lineno);
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 331) return -EINVAL;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 332) }
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 333) } else {
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 334) query->last_lineno = query->first_lineno;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 335) }
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 336) vpr_info("parsed line %d-%d\n", query->first_lineno,
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 337) query->last_lineno);
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 338) return 0;
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 339) }
8037072d8139d (Jim Cromie 2020-07-19 17:10:52 -0600 340)
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 341) static int check_set(const char **dest, char *src, char *name)
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 342) {
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 343) int rc = 0;
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 344)
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 345) if (*dest) {
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 346) rc = -EINVAL;
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 347) pr_err("match-spec:%s val:%s overridden by %s\n",
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 348) name, *dest, src);
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 349) }
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 350) *dest = src;
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 351) return rc;
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 352) }
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 353)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 354) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 355) * Parse words[] as a ddebug query specification, which is a series
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 356) * of (keyword, value) pairs chosen from these possibilities:
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 357) *
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 358) * func <function-name>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 359) * file <full-pathname>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 360) * file <base-filename>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 361) * module <module-name>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 362) * format <escaped-string-to-find-in-format>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 363) * line <lineno>
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 364) * line <first-lineno>-<last-lineno> // where either may be empty
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 365) *
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 366) * Only 1 of each type is allowed.
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 367) * Returns 0 on success, <0 on error.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 368) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 369) static int ddebug_parse_query(char *words[], int nwords,
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 370) struct ddebug_query *query, const char *modname)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 371) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 372) unsigned int i;
bd8c154a62d47 (jbaron@akamai.com 2013-08-27 16:50:03 +0000 373) int rc = 0;
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 374) char *fline;
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 375)
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 376) /* check we have an even number of words */
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 377) if (nwords % 2 != 0) {
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 378) pr_err("expecting pairs of match-spec <value>\n");
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 379) return -EINVAL;
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 380) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 381)
7f6e1f3072b68 (Greg Kroah-Hartman 2020-09-10 18:42:38 +0200 382) if (modname)
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 383) /* support $modname.dyndbg=<multiple queries> */
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 384) query->module = modname;
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 385)
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200 386) for (i = 0; i < nwords; i += 2) {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 387) char *keyword = words[i];
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 388) char *arg = words[i+1];
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 389)
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 390) if (!strcmp(keyword, "func")) {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 391) rc = check_set(&query->function, arg, "func");
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 392) } else if (!strcmp(keyword, "file")) {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 393) if (check_set(&query->filename, arg, "file"))
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 394) return -EINVAL;
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 395)
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 396) /* tail :$info is function or line-range */
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 397) fline = strchr(query->filename, ':');
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 398) if (!fline)
7b1ae248279be (Shuo Chen 2021-04-14 14:24:00 -0700 399) continue;
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 400) *fline++ = '\0';
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 401) if (isalpha(*fline) || *fline == '*' || *fline == '?') {
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 402) /* take as function name */
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 403) if (check_set(&query->function, fline, "func"))
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 404) return -EINVAL;
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 405) } else {
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 406) if (parse_linerange(query, fline))
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 407) return -EINVAL;
aaebe329bff0d (Jim Cromie 2020-07-19 17:10:53 -0600 408) }
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 409) } else if (!strcmp(keyword, "module")) {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 410) rc = check_set(&query->module, arg, "module");
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 411) } else if (!strcmp(keyword, "format")) {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 412) string_unescape_inplace(arg, UNESCAPE_SPACE |
d338b1379f96b (Andy Shevchenko 2013-04-30 15:27:32 -0700 413) UNESCAPE_OCTAL |
d338b1379f96b (Andy Shevchenko 2013-04-30 15:27:32 -0700 414) UNESCAPE_SPECIAL);
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 415) rc = check_set(&query->format, arg, "format");
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 416) } else if (!strcmp(keyword, "line")) {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 417) if (parse_linerange(query, arg))
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 418) return -EINVAL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 419) } else {
e5e5fcef600e9 (Jim Cromie 2020-09-21 13:04:33 -0600 420) pr_err("unknown keyword \"%s\"\n", keyword);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 421) return -EINVAL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 422) }
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 423) if (rc)
820874c75ea0d (Jim Cromie 2011-12-19 17:12:49 -0500 424) return rc;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 425) }
574b3725e3275 (Jim Cromie 2011-12-19 17:13:16 -0500 426) vpr_info_dq(query, "parsed");
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 427) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 428) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 429)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 430) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 431) * Parse `str' as a flags specification, format [-+=][p]+.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 432) * Sets up *maskp and *flagsp to be used when changing the
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 433) * flags fields of matched _ddebug's. Returns 0 on success
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 434) * or <0 on error.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 435) */
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 436) static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 437) {
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 438) int op, i;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 439)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 440) switch (*str) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 441) case '+':
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 442) case '-':
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 443) case '=':
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 444) op = *str++;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 445) break;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 446) default:
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 447) pr_err("bad flag-op %c, at start of %s\n", *str, str);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 448) return -EINVAL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 449) }
b8ccd5dee776d (Jim Cromie 2012-04-27 14:30:32 -0600 450) vpr_info("op='%c'\n", op);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 451)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 452) for (; *str ; ++str) {
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 453) for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 454) if (*str == opt_array[i].opt_char) {
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 455) modifiers->flags |= opt_array[i].flag;
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 456) break;
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 457) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 458) }
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 459) if (i < 0) {
0b8f96be9bd41 (Jim Cromie 2020-07-19 17:10:48 -0600 460) pr_err("unknown flag '%c'\n", *str);
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 461) return -EINVAL;
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 462) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 463) }
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 464) vpr_info("flags=0x%x\n", modifiers->flags);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 465)
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 466) /* calculate final flags, mask based upon op */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 467) switch (op) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 468) case '=':
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 469) /* modifiers->flags already set */
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 470) modifiers->mask = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 471) break;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 472) case '+':
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 473) modifiers->mask = ~0U;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 474) break;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 475) case '-':
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 476) modifiers->mask = ~modifiers->flags;
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 477) modifiers->flags = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 478) break;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 479) }
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 480) vpr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 481)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 482) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 483) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 484)
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 485) static int ddebug_exec_query(char *query_string, const char *modname)
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 486) {
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 487) struct flag_settings modifiers = {};
9c9d0acbe2793 (Jim Cromie 2020-07-19 17:10:49 -0600 488) struct ddebug_query query = {};
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 489) #define MAXWORDS 9
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 490) int nwords, nfound;
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 491) char *words[MAXWORDS];
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 492)
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 493) nwords = ddebug_tokenize(query_string, words, MAXWORDS);
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 494) if (nwords <= 0) {
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 495) pr_err("tokenize failed\n");
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 496) return -EINVAL;
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 497) }
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 498) /* check flags 1st (last arg) so query is pairs of spec,val */
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 499) if (ddebug_parse_flags(words[nwords-1], &modifiers)) {
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 500) pr_err("flags parse failed\n");
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 501) return -EINVAL;
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 502) }
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 503) if (ddebug_parse_query(words, nwords-1, &query, modname)) {
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 504) pr_err("query parse failed\n");
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 505) return -EINVAL;
18c216c53b29f (Jim Cromie 2012-12-05 16:48:27 -0500 506) }
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 507) /* actually go and implement the change */
84da83a6ffc0b (Jim Cromie 2020-07-19 17:10:55 -0600 508) nfound = ddebug_change(&query, &modifiers);
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 509) vpr_info_dq(&query, nfound ? "applied" : "no-match");
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 510)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 511) return nfound;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 512) }
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 513)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 514) /* handle multiple queries in query string, continue on error, return
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 515) last error or number of matching callsites. Module name is either
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 516) in param (for boot arg) or perhaps in query string.
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 517) */
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 518) static int ddebug_exec_queries(char *query, const char *modname)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 519) {
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 520) char *split;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 521) int i, errs = 0, exitcode = 0, rc, nfound = 0;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 522)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 523) for (i = 0; query; query = split) {
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 524) split = strpbrk(query, ";\n");
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 525) if (split)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 526) *split++ = '\0';
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 527)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 528) query = skip_spaces(query);
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 529) if (!query || !*query || *query == '#')
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 530) continue;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 531)
b8ccd5dee776d (Jim Cromie 2012-04-27 14:30:32 -0600 532) vpr_info("query %d: \"%s\"\n", i, query);
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 533)
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 534) rc = ddebug_exec_query(query, modname);
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 535) if (rc < 0) {
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 536) errs++;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 537) exitcode = rc;
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 538) } else {
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 539) nfound += rc;
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 540) }
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 541) i++;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 542) }
b8ccd5dee776d (Jim Cromie 2012-04-27 14:30:32 -0600 543) vpr_info("processed %d queries, with %d matches, %d errs\n",
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 544) i, nfound, errs);
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 545)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 546) if (exitcode)
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 547) return exitcode;
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 548) return nfound;
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 549) }
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 550)
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 551) /**
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 552) * dynamic_debug_exec_queries - select and change dynamic-debug prints
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 553) * @query: query-string described in admin-guide/dynamic-debug-howto
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 554) * @modname: string containing module name, usually &module.mod_name
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 555) *
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 556) * This uses the >/proc/dynamic_debug/control reader, allowing module
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 557) * authors to modify their dynamic-debug callsites. The modname is
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 558) * canonically struct module.mod_name, but can also be null or a
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 559) * module-wildcard, for example: "drm*".
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 560) */
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 561) int dynamic_debug_exec_queries(const char *query, const char *modname)
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 562) {
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 563) int rc;
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 564) char *qry; /* writable copy of query */
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 565)
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 566) if (!query) {
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 567) pr_err("non-null query/command string expected\n");
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 568) return -EINVAL;
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 569) }
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 570) qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
3577afb0052fc (Jim Cromie 2020-12-09 11:36:25 -0700 571) if (!qry)
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 572) return -ENOMEM;
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 573)
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 574) rc = ddebug_exec_queries(qry, modname);
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 575) kfree(qry);
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 576) return rc;
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 577) }
a2d375eda771a (Jim Cromie 2020-08-31 12:22:09 -0600 578) EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 579)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 580) #define PREFIX_SIZE 64
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 581)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 582) static int remaining(int wrote)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 583) {
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 584) if (PREFIX_SIZE - wrote > 0)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 585) return PREFIX_SIZE - wrote;
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 586) return 0;
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 587) }
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 588)
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 589) static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 590) {
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 591) int pos_after_tid;
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 592) int pos = 0;
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 593)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 594) if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 595) if (in_interrupt())
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 596) pos += snprintf(buf + pos, remaining(pos), "<intr> ");
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 597) else
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 598) pos += snprintf(buf + pos, remaining(pos), "[%d] ",
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 599) task_pid_vnr(current));
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 600) }
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 601) pos_after_tid = pos;
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 602) if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 603) pos += snprintf(buf + pos, remaining(pos), "%s:",
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 604) desc->modname);
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 605) if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 606) pos += snprintf(buf + pos, remaining(pos), "%s:",
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 607) desc->function);
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 608) if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
07100be7e0495 (Jim Cromie 2011-12-19 17:11:09 -0500 609) pos += snprintf(buf + pos, remaining(pos), "%d:",
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 610) desc->lineno);
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 611) if (pos - pos_after_tid)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 612) pos += snprintf(buf + pos, remaining(pos), " ");
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 613) if (pos >= PREFIX_SIZE)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 614) buf[PREFIX_SIZE - 1] = '\0';
6c2140ee0ebf9 (Joe Perches 2011-08-11 14:36:25 -0400 615)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 616) return buf;
6c2140ee0ebf9 (Joe Perches 2011-08-11 14:36:25 -0400 617) }
6c2140ee0ebf9 (Joe Perches 2011-08-11 14:36:25 -0400 618)
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 619) static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 620) {
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 621) if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 622) return __dynamic_emit_prefix(desc, buf);
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 623) return buf;
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 624) }
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 625)
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 626) void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 627) {
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 628) va_list args;
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 629) struct va_format vaf;
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 630) char buf[PREFIX_SIZE] = "";
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 631)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 632) BUG_ON(!descriptor);
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 633) BUG_ON(!fmt);
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 634)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 635) va_start(args, fmt);
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 636)
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 637) vaf.fmt = fmt;
431625dac14de (Jason Baron 2011-10-04 14:13:19 -0700 638) vaf.va = &args;
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 639)
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 640) printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 641)
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 642) va_end(args);
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 643) }
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 644) EXPORT_SYMBOL(__dynamic_pr_debug);
8ba6ebf583f12 (Bart Van Assche 2011-01-23 17:17:24 +0100 645)
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 646) void __dynamic_dev_dbg(struct _ddebug *descriptor,
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 647) const struct device *dev, const char *fmt, ...)
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 648) {
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 649) struct va_format vaf;
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 650) va_list args;
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 651)
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 652) BUG_ON(!descriptor);
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 653) BUG_ON(!fmt);
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 654)
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 655) va_start(args, fmt);
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 656)
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 657) vaf.fmt = fmt;
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 658) vaf.va = &args;
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 659)
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 660) if (!dev) {
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 661) printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 662) } else {
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 663) char buf[PREFIX_SIZE] = "";
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 664)
a39d4a857d4bb (Joe Perches 2014-12-10 15:50:15 -0800 665) dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 666) dynamic_emit_prefix(descriptor, buf),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 667) dev_driver_string(dev), dev_name(dev),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 668) &vaf);
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 669) }
798efc60e4276 (Joe Perches 2012-09-12 20:11:29 -0700 670)
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 671) va_end(args);
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 672) }
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 673) EXPORT_SYMBOL(__dynamic_dev_dbg);
cbc4663552ee4 (Joe Perches 2011-08-11 14:36:21 -0400 674)
0feefd97861f9 (Jason Baron 2011-10-04 14:13:22 -0700 675) #ifdef CONFIG_NET
0feefd97861f9 (Jason Baron 2011-10-04 14:13:22 -0700 676)
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 677) void __dynamic_netdev_dbg(struct _ddebug *descriptor,
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 678) const struct net_device *dev, const char *fmt, ...)
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 679) {
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 680) struct va_format vaf;
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 681) va_list args;
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 682)
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 683) BUG_ON(!descriptor);
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 684) BUG_ON(!fmt);
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 685)
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 686) va_start(args, fmt);
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 687)
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 688) vaf.fmt = fmt;
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 689) vaf.va = &args;
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 690)
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 691) if (dev && dev->dev.parent) {
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 692) char buf[PREFIX_SIZE] = "";
666f355f3805d (Joe Perches 2012-09-12 20:14:11 -0700 693)
a39d4a857d4bb (Joe Perches 2014-12-10 15:50:15 -0800 694) dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 695) "%s%s %s %s%s: %pV",
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 696) dynamic_emit_prefix(descriptor, buf),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 697) dev_driver_string(dev->dev.parent),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 698) dev_name(dev->dev.parent),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 699) netdev_name(dev), netdev_reg_state(dev),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 700) &vaf);
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 701) } else if (dev) {
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 702) printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 703) netdev_reg_state(dev), &vaf);
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 704) } else {
906d201530f2c (Joe Perches 2014-09-24 11:17:56 -0700 705) printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 706) }
b004ff4972e2a (Joe Perches 2012-09-12 20:12:19 -0700 707)
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 708) va_end(args);
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 709) }
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 710) EXPORT_SYMBOL(__dynamic_netdev_dbg);
ffa10cb47a94c (Jason Baron 2011-08-11 14:36:48 -0400 711)
0feefd97861f9 (Jason Baron 2011-10-04 14:13:22 -0700 712) #endif
0feefd97861f9 (Jason Baron 2011-10-04 14:13:22 -0700 713)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 714) #if IS_ENABLED(CONFIG_INFINIBAND)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 715)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 716) void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 717) const struct ib_device *ibdev, const char *fmt, ...)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 718) {
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 719) struct va_format vaf;
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 720) va_list args;
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 721)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 722) va_start(args, fmt);
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 723)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 724) vaf.fmt = fmt;
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 725) vaf.va = &args;
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 726)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 727) if (ibdev && ibdev->dev.parent) {
640d1eaff2c09 (Jim Cromie 2021-05-04 16:22:34 -0600 728) char buf[PREFIX_SIZE] = "";
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 729)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 730) dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 731) "%s%s %s %s: %pV",
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 732) dynamic_emit_prefix(descriptor, buf),
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 733) dev_driver_string(ibdev->dev.parent),
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 734) dev_name(ibdev->dev.parent),
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 735) dev_name(&ibdev->dev),
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 736) &vaf);
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 737) } else if (ibdev) {
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 738) printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 739) } else {
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 740) printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 741) }
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 742)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 743) va_end(args);
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 744) }
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 745) EXPORT_SYMBOL(__dynamic_ibdev_dbg);
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 746)
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 747) #endif
923abb9d797ba (Gal Pressman 2019-05-01 13:48:13 +0300 748)
bc757f6f5bf4e (Jim Cromie 2011-12-19 17:12:29 -0500 749) #define DDEBUG_STRING_SIZE 1024
bc757f6f5bf4e (Jim Cromie 2011-12-19 17:12:29 -0500 750) static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
bc757f6f5bf4e (Jim Cromie 2011-12-19 17:12:29 -0500 751)
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 752) static __init int ddebug_setup_query(char *str)
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 753) {
bc757f6f5bf4e (Jim Cromie 2011-12-19 17:12:29 -0500 754) if (strlen(str) >= DDEBUG_STRING_SIZE) {
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 755) pr_warn("ddebug boot param string too large\n");
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 756) return 0;
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 757) }
bc757f6f5bf4e (Jim Cromie 2011-12-19 17:12:29 -0500 758) strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 759) return 1;
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 760) }
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 761)
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 762) __setup("ddebug_query=", ddebug_setup_query);
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 763)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 764) /*
231821d4c3fa7 (Masatake YAMATO 2014-12-15 12:04:16 +0900 765) * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 766) * command text from userspace, parses and executes it.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 767) */
7281491c594e7 (Jim Cromie 2011-12-19 17:13:07 -0500 768) #define USER_BUF_PAGE 4096
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 769) static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 770) size_t len, loff_t *offp)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 771) {
7281491c594e7 (Jim Cromie 2011-12-19 17:13:07 -0500 772) char *tmpbuf;
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 773) int ret;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 774)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 775) if (len == 0)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 776) return 0;
7281491c594e7 (Jim Cromie 2011-12-19 17:13:07 -0500 777) if (len > USER_BUF_PAGE - 1) {
7281491c594e7 (Jim Cromie 2011-12-19 17:13:07 -0500 778) pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 779) return -E2BIG;
7281491c594e7 (Jim Cromie 2011-12-19 17:13:07 -0500 780) }
16e5c1fc36040 (Al Viro 2015-12-24 00:06:05 -0500 781) tmpbuf = memdup_user_nul(ubuf, len);
16e5c1fc36040 (Al Viro 2015-12-24 00:06:05 -0500 782) if (IS_ERR(tmpbuf))
16e5c1fc36040 (Al Viro 2015-12-24 00:06:05 -0500 783) return PTR_ERR(tmpbuf);
b8ccd5dee776d (Jim Cromie 2012-04-27 14:30:32 -0600 784) vpr_info("read %d bytes from userspace\n", (int)len);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 785)
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 786) ret = ddebug_exec_queries(tmpbuf, NULL);
7281491c594e7 (Jim Cromie 2011-12-19 17:13:07 -0500 787) kfree(tmpbuf);
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 788) if (ret < 0)
fd89cfb871875 (Thomas Renninger 2010-08-06 16:11:01 +0200 789) return ret;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 790)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 791) *offp += len;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 792) return len;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 793) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 794)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 795) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 796) * Set the iterator to point to the first _ddebug object
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 797) * and return a pointer to that first object. Returns
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 798) * NULL if there are no _ddebugs at all.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 799) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 800) static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 801) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 802) if (list_empty(&ddebug_tables)) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 803) iter->table = NULL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 804) iter->idx = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 805) return NULL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 806) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 807) iter->table = list_entry(ddebug_tables.next,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 808) struct ddebug_table, link);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 809) iter->idx = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 810) return &iter->table->ddebugs[iter->idx];
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 811) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 812)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 813) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 814) * Advance the iterator to point to the next _ddebug
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 815) * object from the one the iterator currently points at,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 816) * and returns a pointer to the new _ddebug. Returns
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 817) * NULL if the iterator has seen all the _ddebugs.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 818) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 819) static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 820) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 821) if (iter->table == NULL)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 822) return NULL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 823) if (++iter->idx == iter->table->num_ddebugs) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 824) /* iterate to next table */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 825) iter->idx = 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 826) if (list_is_last(&iter->table->link, &ddebug_tables)) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 827) iter->table = NULL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 828) return NULL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 829) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 830) iter->table = list_entry(iter->table->link.next,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 831) struct ddebug_table, link);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 832) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 833) return &iter->table->ddebugs[iter->idx];
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 834) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 835)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 836) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 837) * Seq_ops start method. Called at the start of every
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 838) * read() call from userspace. Takes the ddebug_lock and
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 839) * seeks the seq_file's iterator to the given position.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 840) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 841) static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 842) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 843) struct ddebug_iter *iter = m->private;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 844) struct _ddebug *dp;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 845) int n = *pos;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 846)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 847) mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 848)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 849) if (!n)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 850) return SEQ_START_TOKEN;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 851) if (n < 0)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 852) return NULL;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 853) dp = ddebug_iter_first(iter);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 854) while (dp != NULL && --n > 0)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 855) dp = ddebug_iter_next(iter);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 856) return dp;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 857) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 858)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 859) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 860) * Seq_ops next method. Called several times within a read()
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 861) * call from userspace, with ddebug_lock held. Walks to the
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 862) * next _ddebug object with a special case for the header line.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 863) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 864) static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 865) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 866) struct ddebug_iter *iter = m->private;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 867) struct _ddebug *dp;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 868)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 869) if (p == SEQ_START_TOKEN)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 870) dp = ddebug_iter_first(iter);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 871) else
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 872) dp = ddebug_iter_next(iter);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 873) ++*pos;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 874) return dp;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 875) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 876)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 877) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 878) * Seq_ops show method. Called several times within a read()
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 879) * call from userspace, with ddebug_lock held. Formats the
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 880) * current _ddebug as a single human-readable line, with a
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 881) * special case for the header line.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 882) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 883) static int ddebug_proc_show(struct seq_file *m, void *p)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 884) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 885) struct ddebug_iter *iter = m->private;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 886) struct _ddebug *dp = p;
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 887) struct flagsbuf flags;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 888)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 889) if (p == SEQ_START_TOKEN) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 890) seq_puts(m,
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 891) "# filename:lineno [module]function flags format\n");
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 892) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 893) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 894)
5ca7d2a6c5e4f (Jim Cromie 2011-12-19 17:12:44 -0500 895) seq_printf(m, "%s:%u [%s]%s =%s \"",
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 896) trim_prefix(dp->filename), dp->lineno,
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 897) iter->table->mod_name, dp->function,
f678ce8cc3cb2 (Jim Cromie 2020-07-19 17:10:47 -0600 898) ddebug_describe_flags(dp->flags, &flags));
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 899) seq_escape(m, dp->format, "\t\r\n\"");
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 900) seq_puts(m, "\"\n");
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 901)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 902) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 903) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 904)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 905) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 906) * Seq_ops stop method. Called at the end of each read()
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 907) * call from userspace. Drops ddebug_lock.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 908) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 909) static void ddebug_proc_stop(struct seq_file *m, void *p)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 910) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 911) mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 912) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 913)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 914) static const struct seq_operations ddebug_proc_seqops = {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 915) .start = ddebug_proc_start,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 916) .next = ddebug_proc_next,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 917) .show = ddebug_proc_show,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 918) .stop = ddebug_proc_stop
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 919) };
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 920)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 921) static int ddebug_proc_open(struct inode *inode, struct file *file)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 922) {
4bad78c550025 (Rob Jones 2014-10-13 15:51:32 -0700 923) return seq_open_private(file, &ddebug_proc_seqops,
4bad78c550025 (Rob Jones 2014-10-13 15:51:32 -0700 924) sizeof(struct ddebug_iter));
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 925) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 926)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 927) static const struct file_operations ddebug_proc_fops = {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 928) .owner = THIS_MODULE,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 929) .open = ddebug_proc_open,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 930) .read = seq_read,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 931) .llseek = seq_lseek,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 932) .release = seq_release_private,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 933) .write = ddebug_proc_write
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 934) };
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 935)
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 936) static const struct proc_ops proc_fops = {
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 937) .proc_open = ddebug_proc_open,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 938) .proc_read = seq_read,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 939) .proc_lseek = seq_lseek,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 940) .proc_release = seq_release_private,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 941) .proc_write = ddebug_proc_write
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 942) };
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 943)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 944) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 945) * Allocate a new ddebug_table for the given module
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 946) * and add it to the global list.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 947) */
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 948) int ddebug_add_module(struct _ddebug *tab, unsigned int n,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 949) const char *name)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 950) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 951) struct ddebug_table *dt;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 952)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 953) dt = kzalloc(sizeof(*dt), GFP_KERNEL);
513770f54edba (Rasmus Villemoes 2019-03-07 16:27:48 -0800 954) if (dt == NULL) {
513770f54edba (Rasmus Villemoes 2019-03-07 16:27:48 -0800 955) pr_err("error adding module: %s\n", name);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 956) return -ENOMEM;
513770f54edba (Rasmus Villemoes 2019-03-07 16:27:48 -0800 957) }
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 958) /*
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 959) * For built-in modules, name lives in .rodata and is
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 960) * immortal. For loaded modules, name points at the name[]
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 961) * member of struct module, which lives at least as long as
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 962) * this struct ddebug_table.
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 963) */
cdf6d00696865 (Rasmus Villemoes 2019-03-07 16:27:37 -0800 964) dt->mod_name = name;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 965) dt->num_ddebugs = n;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 966) dt->ddebugs = tab;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 967)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 968) mutex_lock(&ddebug_lock);
47e9f5a823296 (Jim Cromie 2020-07-19 17:10:50 -0600 969) list_add(&dt->link, &ddebug_tables);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 970) mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 971)
b52a95eac112f (Jim Cromie 2020-08-31 12:22:08 -0600 972) v2pr_info("%3u debug prints in module %s\n", n, dt->mod_name);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 973) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 974) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 975)
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 976) /* helper for ddebug_dyndbg_(boot|module)_param_cb */
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 977) static int ddebug_dyndbg_param_cb(char *param, char *val,
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 978) const char *modname, int on_err)
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 979) {
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 980) char *sep;
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 981)
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 982) sep = strchr(param, '.');
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 983) if (sep) {
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 984) /* needed only for ddebug_dyndbg_boot_param_cb */
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 985) *sep = '\0';
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 986) modname = param;
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 987) param = sep + 1;
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 988) }
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 989) if (strcmp(param, "dyndbg"))
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 990) return on_err; /* determined by caller */
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 991)
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 992) ddebug_exec_queries((val ? val : "+p"), modname);
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 993)
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 994) return 0; /* query failure shouldnt stop module load */
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 995) }
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 996)
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 997) /* handle both dyndbg and $module.dyndbg params at boot */
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 998) static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
ecc8617053e0a (Luis R. Rodriguez 2015-03-30 16:20:03 -0700 999) const char *unused, void *arg)
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1000) {
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1001) vpr_info("%s=\"%s\"\n", param, val);
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1002) return ddebug_dyndbg_param_cb(param, val, NULL, 0);
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1003) }
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1004)
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1005) /*
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1006) * modprobe foo finds foo.params in boot-args, strips "foo.", and
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1007) * passes them to load_module(). This callback gets unknown params,
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1008) * processes dyndbg params, rejects others.
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1009) */
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1010) int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1011) {
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1012) vpr_info("module: %s %s=\"%s\"\n", module, param, val);
6ab676e96422f (Jim Cromie 2012-04-27 14:30:37 -0600 1013) return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1014) }
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1015)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1016) static void ddebug_table_free(struct ddebug_table *dt)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1017) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1018) list_del_init(&dt->link);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1019) kfree(dt);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1020) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1021)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1022) /*
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1023) * Called in response to a module being unloaded. Removes
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1024) * any ddebug_table's which point at the module.
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1025) */
ff49d74ad383f (Yehuda Sadeh 2010-07-03 13:07:35 +1000 1026) int ddebug_remove_module(const char *mod_name)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1027) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1028) struct ddebug_table *dt, *nextdt;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1029) int ret = -ENOENT;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1030)
481c0e33f1e71 (Jim Cromie 2020-07-19 17:10:44 -0600 1031) v2pr_info("removing module \"%s\"\n", mod_name);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1032)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1033) mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1034) list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
4573fe15437c9 (Rasmus Villemoes 2019-03-07 16:27:41 -0800 1035) if (dt->mod_name == mod_name) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1036) ddebug_table_free(dt);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1037) ret = 0;
4573fe15437c9 (Rasmus Villemoes 2019-03-07 16:27:41 -0800 1038) break;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1039) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1040) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1041) mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1042) return ret;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1043) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1044)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1045) static void ddebug_remove_all_tables(void)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1046) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1047) mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1048) while (!list_empty(&ddebug_tables)) {
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1049) struct ddebug_table *dt = list_entry(ddebug_tables.next,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1050) struct ddebug_table,
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1051) link);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1052) ddebug_table_free(dt);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1053) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1054) mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1055) }
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1056)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1057) static __initdata int ddebug_init_success;
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1058)
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1059) static int __init dynamic_debug_init_control(void)
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1060) {
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1061) struct proc_dir_entry *procfs_dir;
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1062) struct dentry *debugfs_dir;
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1063)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1064) if (!ddebug_init_success)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1065) return -ENODEV;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1066)
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1067) /* Create the control file in debugfs if it is enabled */
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1068) if (debugfs_initialized()) {
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1069) debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1070) debugfs_create_file("control", 0644, debugfs_dir, NULL,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1071) &ddebug_proc_fops);
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1072) }
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1073)
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1074) /* Also create the control file in procfs */
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1075) procfs_dir = proc_mkdir("dynamic_debug", NULL);
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1076) if (procfs_dir)
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1077) proc_create("control", 0644, procfs_dir, &proc_fops);
9fd714cd7f467 (Greg Kroah-Hartman 2019-06-12 17:35:34 +0200 1078)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1079) return 0;
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1080) }
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1081)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1082) static int __init dynamic_debug_init(void)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1083) {
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1084) struct _ddebug *iter, *iter_start;
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1085) const char *modname = NULL;
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1086) char *cmdline;
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1087) int ret = 0;
4107692760db8 (Jim Cromie 2012-04-27 14:30:39 -0600 1088) int n = 0, entries = 0, modct = 0;
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1089)
e5ebffe18e5ad (Jim Cromie 2020-07-19 17:10:45 -0600 1090) if (&__start___dyndbg == &__stop___dyndbg) {
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1091) if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1092) pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1093) return 1;
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1094) }
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1095) pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1096) ddebug_init_success = 1;
ceabef7dd7172 (Orson Zhai 2020-06-07 21:40:14 -0700 1097) return 0;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1098) }
e5ebffe18e5ad (Jim Cromie 2020-07-19 17:10:45 -0600 1099) iter = __start___dyndbg;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1100) modname = iter->modname;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1101) iter_start = iter;
e5ebffe18e5ad (Jim Cromie 2020-07-19 17:10:45 -0600 1102) for (; iter < __stop___dyndbg; iter++) {
4107692760db8 (Jim Cromie 2012-04-27 14:30:39 -0600 1103) entries++;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1104) if (strcmp(modname, iter->modname)) {
4107692760db8 (Jim Cromie 2012-04-27 14:30:39 -0600 1105) modct++;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1106) ret = ddebug_add_module(iter_start, n, modname);
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1107) if (ret)
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1108) goto out_err;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1109) n = 0;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1110) modname = iter->modname;
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1111) iter_start = iter;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1112) }
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1113) n++;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1114) }
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1115) ret = ddebug_add_module(iter_start, n, modname);
b5b78f83854af (Jim Cromie 2011-12-19 17:12:54 -0500 1116) if (ret)
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1117) goto out_err;
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 1118)
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1119) ddebug_init_success = 1;
81d0c2c60942c (Jim Cromie 2020-07-19 17:10:46 -0600 1120) vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in __dyndbg section\n",
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 1121) modct, entries, (int)(modct * sizeof(struct ddebug_table)),
81d0c2c60942c (Jim Cromie 2020-07-19 17:10:46 -0600 1122) (int)(entries * sizeof(struct _ddebug)));
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1123)
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1124) /* apply ddebug_query boot param, dont unload tables on err */
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 1125) if (ddebug_setup_string[0] != '\0') {
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 1126) pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
8e59b5cfb9a6f (Jim Cromie 2012-04-27 14:30:40 -0600 1127) ret = ddebug_exec_queries(ddebug_setup_string, NULL);
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 1128) if (ret < 0)
f657fd21e16e3 (Joe Perches 2012-12-05 16:48:26 -0500 1129) pr_warn("Invalid ddebug boot param %s\n",
4ad275e5cb576 (Joe Perches 2011-08-11 14:36:33 -0400 1130) ddebug_setup_string);
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 1131) else
85f7f6c0edb84 (Jim Cromie 2011-12-19 17:13:21 -0500 1132) pr_info("%d changes by ddebug_query\n", ret);
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 1133) }
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1134) /* now that ddebug tables are loaded, process all boot args
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1135) * again to find and activate queries given in dyndbg params.
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1136) * While this has already been done for known boot params, it
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1137) * ignored the unknown ones (dyndbg in particular). Reusing
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1138) * parse_args avoids ad-hoc parsing. This will also attempt
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1139) * to activate queries for not-yet-loaded modules, which is
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1140) * slightly noisy if verbose, but harmless.
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1141) */
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1142) cmdline = kstrdup(saved_command_line, GFP_KERNEL);
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1143) parse_args("dyndbg params", cmdline, NULL,
ecc8617053e0a (Luis R. Rodriguez 2015-03-30 16:20:03 -0700 1144) 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1145) kfree(cmdline);
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1146) return 0;
a648ec05bb950 (Thomas Renninger 2010-08-06 16:11:02 +0200 1147)
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1148) out_err:
af442399fcf37 (Jim Cromie 2012-04-27 14:30:38 -0600 1149) ddebug_remove_all_tables();
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1150) return 0;
e9d376f0fa66b (Jason Baron 2009-02-05 11:51:38 -0500 1151) }
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1152) /* Allow early initialization for boot messages via boot param */
3ec5652ab70f6 (Jim Cromie 2012-04-27 14:30:42 -0600 1153) early_initcall(dynamic_debug_init);
b48420c1d3019 (Jim Cromie 2012-04-27 14:30:35 -0600 1154)
6a5c083de2f5f (Thomas Renninger 2010-08-06 16:11:03 +0200 1155) /* Debugfs setup must be done later */
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1156) fs_initcall(dynamic_debug_init_control);