linux/include/linux/dynamic_debug.h
<<
>>
Prefs
   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
 186