1e9d376f0SJason Baron #ifndef _DYNAMIC_DEBUG_H 2e9d376f0SJason Baron #define _DYNAMIC_DEBUG_H 3e9d376f0SJason Baron 4*9049fc74SJason Baron #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) 5*9049fc74SJason Baron #include <linux/jump_label.h> 6*9049fc74SJason Baron #endif 7*9049fc74SJason Baron 8e9d376f0SJason Baron /* 9e9d376f0SJason Baron * An instance of this structure is created in a special 10e9d376f0SJason Baron * ELF section at every dynamic debug callsite. At runtime, 11e9d376f0SJason Baron * the special section is treated as an array of these. 12e9d376f0SJason Baron */ 13e9d376f0SJason Baron struct _ddebug { 14e9d376f0SJason Baron /* 15e9d376f0SJason Baron * These fields are used to drive the user interface 16e9d376f0SJason Baron * for selecting and displaying debug callsites. 17e9d376f0SJason Baron */ 18e9d376f0SJason Baron const char *modname; 19e9d376f0SJason Baron const char *function; 20e9d376f0SJason Baron const char *filename; 21e9d376f0SJason Baron const char *format; 22e703ddaeSJim Cromie unsigned int lineno:18; 23e9d376f0SJason Baron /* 24e9d376f0SJason Baron * The flags field controls the behaviour at the callsite. 25e9d376f0SJason Baron * The bits here are changed dynamically when the user 262b2f68b5SFlorian Ragwitz * writes commands to <debugfs>/dynamic_debug/control 27e9d376f0SJason Baron */ 285ca7d2a6SJim Cromie #define _DPRINTK_FLAGS_NONE 0 29e9d376f0SJason Baron #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ 308ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_MODNAME (1<<1) 318ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2) 328ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) 338ba6ebf5SBart Van Assche #define _DPRINTK_FLAGS_INCL_TID (1<<4) 34b558c96fSJim Cromie #if defined DEBUG 35b558c96fSJim Cromie #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT 36b558c96fSJim Cromie #else 37e9d376f0SJason Baron #define _DPRINTK_FLAGS_DEFAULT 0 38b558c96fSJim Cromie #endif 39e9d376f0SJason Baron unsigned int flags:8; 40*9049fc74SJason Baron #ifdef HAVE_JUMP_LABEL 41*9049fc74SJason Baron union { 42*9049fc74SJason Baron struct static_key_true dd_key_true; 43*9049fc74SJason Baron struct static_key_false dd_key_false; 44*9049fc74SJason Baron } key; 45*9049fc74SJason Baron #endif 46e9d376f0SJason Baron } __attribute__((aligned(8))); 47e9d376f0SJason Baron 48e9d376f0SJason Baron 49e9d376f0SJason Baron int ddebug_add_module(struct _ddebug *tab, unsigned int n, 50e9d376f0SJason Baron const char *modname); 51e9d376f0SJason Baron 52e9d376f0SJason Baron #if defined(CONFIG_DYNAMIC_DEBUG) 53ff49d74aSYehuda Sadeh extern int ddebug_remove_module(const char *mod_name); 54b9075fa9SJoe Perches extern __printf(2, 3) 55906d2015SJoe Perches void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); 56e9d376f0SJason Baron 57b48420c1SJim Cromie extern int ddebug_dyndbg_module_param_cb(char *param, char *val, 58b48420c1SJim Cromie const char *modname); 59b48420c1SJim Cromie 60cbc46635SJoe Perches struct device; 61cbc46635SJoe Perches 62b9075fa9SJoe Perches extern __printf(3, 4) 63906d2015SJoe Perches void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev, 64b9075fa9SJoe Perches const char *fmt, ...); 65cbc46635SJoe Perches 66ffa10cb4SJason Baron struct net_device; 67ffa10cb4SJason Baron 68b9075fa9SJoe Perches extern __printf(3, 4) 69906d2015SJoe Perches void __dynamic_netdev_dbg(struct _ddebug *descriptor, 70ffa10cb4SJason Baron const struct net_device *dev, 71b9075fa9SJoe Perches const char *fmt, ...); 72ffa10cb4SJason Baron 73*9049fc74SJason Baron #define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \ 74c0d2af63SJoe Perches static struct _ddebug __aligned(8) \ 7507613b0bSJason Baron __attribute__((section("__verbose"))) name = { \ 7607613b0bSJason Baron .modname = KBUILD_MODNAME, \ 7707613b0bSJason Baron .function = __func__, \ 7807613b0bSJason Baron .filename = __FILE__, \ 7907613b0bSJason Baron .format = (fmt), \ 8007613b0bSJason Baron .lineno = __LINE__, \ 8107613b0bSJason Baron .flags = _DPRINTK_FLAGS_DEFAULT, \ 82*9049fc74SJason Baron dd_key_init(key, init) \ 8307613b0bSJason Baron } 8407613b0bSJason Baron 85*9049fc74SJason Baron #ifdef HAVE_JUMP_LABEL 86*9049fc74SJason Baron 87*9049fc74SJason Baron #define dd_key_init(key, init) key = (init) 88*9049fc74SJason Baron 89*9049fc74SJason Baron #ifdef DEBUG 90*9049fc74SJason Baron #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 91*9049fc74SJason Baron DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \ 92*9049fc74SJason Baron (STATIC_KEY_TRUE_INIT)) 93*9049fc74SJason Baron 94*9049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 95*9049fc74SJason Baron static_branch_likely(&descriptor.key.dd_key_true) 96*9049fc74SJason Baron #else 97*9049fc74SJason Baron #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 98*9049fc74SJason Baron DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \ 99*9049fc74SJason Baron (STATIC_KEY_FALSE_INIT)) 100*9049fc74SJason Baron 101*9049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 102*9049fc74SJason Baron static_branch_unlikely(&descriptor.key.dd_key_false) 103*9049fc74SJason Baron #endif 104*9049fc74SJason Baron 105*9049fc74SJason Baron #else 106*9049fc74SJason Baron 107*9049fc74SJason Baron #define dd_key_init(key, init) 108*9049fc74SJason Baron 109*9049fc74SJason Baron #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 110*9049fc74SJason Baron DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0) 111*9049fc74SJason Baron 112*9049fc74SJason Baron #ifdef DEBUG 113*9049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 114*9049fc74SJason Baron likely(descriptor.flags & _DPRINTK_FLAGS_PRINT) 115*9049fc74SJason Baron #else 116*9049fc74SJason Baron #define DYNAMIC_DEBUG_BRANCH(descriptor) \ 117*9049fc74SJason Baron unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) 118*9049fc74SJason Baron #endif 119*9049fc74SJason Baron 120*9049fc74SJason Baron #endif 121*9049fc74SJason Baron 12207613b0bSJason Baron #define dynamic_pr_debug(fmt, ...) \ 12307613b0bSJason Baron do { \ 12407613b0bSJason Baron DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 125*9049fc74SJason Baron if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 12607613b0bSJason Baron __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ 12707613b0bSJason Baron ##__VA_ARGS__); \ 128e9d376f0SJason Baron } while (0) 129e9d376f0SJason Baron 13007613b0bSJason Baron #define dynamic_dev_dbg(dev, fmt, ...) \ 13107613b0bSJason Baron do { \ 13207613b0bSJason Baron DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 133*9049fc74SJason Baron if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 13407613b0bSJason Baron __dynamic_dev_dbg(&descriptor, dev, fmt, \ 13507613b0bSJason Baron ##__VA_ARGS__); \ 136e9d376f0SJason Baron } while (0) 137e9d376f0SJason Baron 13807613b0bSJason Baron #define dynamic_netdev_dbg(dev, fmt, ...) \ 13907613b0bSJason Baron do { \ 14007613b0bSJason Baron DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 141*9049fc74SJason Baron if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 14207613b0bSJason Baron __dynamic_netdev_dbg(&descriptor, dev, fmt, \ 14307613b0bSJason Baron ##__VA_ARGS__); \ 144ffa10cb4SJason Baron } while (0) 145ffa10cb4SJason Baron 1467a555613SVladimir Kondratiev #define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ 1477a555613SVladimir Kondratiev groupsize, buf, len, ascii) \ 1487a555613SVladimir Kondratiev do { \ 1497a555613SVladimir Kondratiev DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \ 1507a555613SVladimir Kondratiev __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\ 151*9049fc74SJason Baron if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ 1527a555613SVladimir Kondratiev print_hex_dump(KERN_DEBUG, prefix_str, \ 1537a555613SVladimir Kondratiev prefix_type, rowsize, groupsize, \ 1547a555613SVladimir Kondratiev buf, len, ascii); \ 1557a555613SVladimir Kondratiev } while (0) 1567a555613SVladimir Kondratiev 157e9d376f0SJason Baron #else 158e9d376f0SJason Baron 159b48420c1SJim Cromie #include <linux/string.h> 160b48420c1SJim Cromie #include <linux/errno.h> 161b48420c1SJim Cromie 162ff49d74aSYehuda Sadeh static inline int ddebug_remove_module(const char *mod) 163e9d376f0SJason Baron { 164e9d376f0SJason Baron return 0; 165e9d376f0SJason Baron } 166e9d376f0SJason Baron 167b48420c1SJim Cromie static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, 168b48420c1SJim Cromie const char *modname) 169b48420c1SJim Cromie { 170b48420c1SJim Cromie if (strstr(param, "dyndbg")) { 171516cf1beSJim Cromie /* avoid pr_warn(), which wants pr_fmt() fully defined */ 172516cf1beSJim Cromie printk(KERN_WARNING "dyndbg param is supported only in " 173b48420c1SJim Cromie "CONFIG_DYNAMIC_DEBUG builds\n"); 174b48420c1SJim Cromie return 0; /* allow and ignore */ 175b48420c1SJim Cromie } 176b48420c1SJim Cromie return -EINVAL; 177b48420c1SJim Cromie } 178b48420c1SJim Cromie 17900b55864SJoe Perches #define dynamic_pr_debug(fmt, ...) \ 18000b55864SJoe Perches do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0) 181be70e267SPhilipp Reisner #define dynamic_dev_dbg(dev, fmt, ...) \ 18200b55864SJoe Perches do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0) 183e9d376f0SJason Baron #endif 184e9d376f0SJason Baron 185e9d376f0SJason Baron #endif 186