1 #ifndef _DYNAMIC_DEBUG_H 2 #define _DYNAMIC_DEBUG_H 3 4 #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) 5 #include <linux/jump_label.h> 6 #endif 7 8 /* 9 * An instance of this structure is created in a special 10 * ELF section at every dynamic debug callsite. At runtime, 11 * the special section is treated as an array of these. 12 */ 13 struct _ddebug { 14 /* 15 * These fields are used to drive the user interface 16 * for selecting and displaying debug callsites. 17 */ 18 const char *modname; 19 const char *function; 20 const char *filename; 21 const char *format; 22 unsigned int lineno:18; 23 /* 24 * The flags field controls the behaviour at the callsite. 25 * The bits here are changed dynamically when the user 26 * writes commands to <debugfs>/dynamic_debug/control 27 */ 28 #define _DPRINTK_FLAGS_NONE 0 29 #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ 30 #define _DPRINTK_FLAGS_INCL_MODNAME (1<<1) 31 #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2) 32 #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) 33 #define _DPRINTK_FLAGS_INCL_TID (1<<4) 34 #if defined DEBUG 35 #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT 36 #else 37 #define _DPRINTK_FLAGS_DEFAULT 0 38 #endif 39 unsigned int flags:8; 40 #ifdef HAVE_JUMP_LABEL 41 union { 42 struct static_key_true dd_key_true; 43 struct static_key_false dd_key_false; 44 } key; 45 #endif 46 } __attribute__((aligned(8))); 47 48 49 int ddebug_add_module(struct _ddebug *tab, unsigned int n, 50 const char *modname); 51 52 #if defined(CONFIG_DYNAMIC_DEBUG) 53 extern int ddebug_remove_module(const char *mod_name); 54 extern __printf(2, 3) 55 void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); 56 57 extern int ddebug_dyndbg_module_param_cb(char *param, char *val, 58 const char *modname); 59 60 struct device; 61 62 extern __printf(3, 4) 63 void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev, 64 const char *fmt, ...); 65 66 struct net_device; 67 68 extern __printf(3, 4) 69 void __dynamic_netdev_dbg(struct _ddebug *descriptor, 70 const struct net_device *dev, 71 const char *fmt, ...); 72 73 #define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \ 74 static struct _ddebug __aligned(8) \ 75 __attribute__((section("__verbose"))) name = { \ 76 .modname = KBUILD_MODNAME, \ 77 .function = __func__, \ 78 .filename = __FILE__, \ 79 .format = (fmt), \ 80 .lineno = __LINE__, \ 81 .flags = _DPRINTK_FLAGS_DEFAULT, \ 82 dd_key_init(key, init) \ 83 } 84 85 #ifdef HAVE_JUMP_LABEL 86 87 #define dd_key_init(key, init) key = (init) 88 89 #ifdef DEBUG 90 #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 91 DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \ 92 (STATIC_KEY_TRUE_INIT)) 93 94 #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 95 static_branch_likely(&descriptor.key.dd_key_true) 96 #else 97 #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 98 DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \ 99 (STATIC_KEY_FALSE_INIT)) 100 101 #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 102 static_branch_unlikely(&descriptor.key.dd_key_false) 103 #endif 104 105 #else 106 107 #define dd_key_init(key, init) 108 109 #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 110 DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0) 111 112 #ifdef DEBUG 113 #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 114 likely(descriptor.flags & _DPRINTK_FLAGS_PRINT) 115 #else 116 #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 117 unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) 118 #endif 119 120 #endif 121 122 #define dynamic_pr_debug(fmt, ...) \ 123 do { \ 124 DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 125 if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 126 __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ 127 ##__VA_ARGS__); \ 128 } while (0) 129 130 #define dynamic_dev_dbg(dev, fmt, ...) \ 131 do { \ 132 DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 133 if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 134 __dynamic_dev_dbg(&descriptor, dev, fmt, \ 135 ##__VA_ARGS__); \ 136 } while (0) 137 138 #define dynamic_netdev_dbg(dev, fmt, ...) \ 139 do { \ 140 DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 141 if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 142 __dynamic_netdev_dbg(&descriptor, dev, fmt, \ 143 ##__VA_ARGS__); \ 144 } while (0) 145 146 #define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ 147 groupsize, buf, len, ascii) \ 148 do { \ 149 DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \ 150 __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\ 151 if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 152 print_hex_dump(KERN_DEBUG, prefix_str, \ 153 prefix_type, rowsize, groupsize, \ 154 buf, len, ascii); \ 155 } while (0) 156 157 #else 158 159 #include <linux/string.h> 160 #include <linux/errno.h> 161 162 static inline int ddebug_remove_module(const char *mod) 163 { 164 return 0; 165 } 166 167 static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, 168 const char *modname) 169 { 170 if (strstr(param, "dyndbg")) { 171 /* avoid pr_warn(), which wants pr_fmt() fully defined */ 172 printk(KERN_WARNING "dyndbg param is supported only in " 173 "CONFIG_DYNAMIC_DEBUG builds\n"); 174 return 0; /* allow and ignore */ 175 } 176 return -EINVAL; 177 } 178 179 #define dynamic_pr_debug(fmt, ...) \ 180 do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0) 181 #define dynamic_dev_dbg(dev, fmt, ...) \ 182 do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0) 183 #endif 184 185 #endif 186