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