at v4.14-rc5 5.2 kB view raw
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 */ 13struct _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 49int ddebug_add_module(struct _ddebug *tab, unsigned int n, 50 const char *modname); 51 52#if defined(CONFIG_DYNAMIC_DEBUG) 53extern int ddebug_remove_module(const char *mod_name); 54extern __printf(2, 3) 55void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); 56 57extern int ddebug_dyndbg_module_param_cb(char *param, char *val, 58 const char *modname); 59 60struct device; 61 62extern __printf(3, 4) 63void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev, 64 const char *fmt, ...); 65 66struct net_device; 67 68extern __printf(3, 4) 69void __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, ...) \ 123do { \ 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, ...) \ 131do { \ 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, ...) \ 139do { \ 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) \ 148do { \ 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 162static inline int ddebug_remove_module(const char *mod) 163{ 164 return 0; 165} 166 167static 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