linux/include/linux/dynamic_debug.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _DYNAMIC_DEBUG_H
   3#define _DYNAMIC_DEBUG_H
   4
   5#if defined(CONFIG_JUMP_LABEL)
   6#include <linux/jump_label.h>
   7#endif
   8
   9/*
  10 * An instance of this structure is created in a special
  11 * ELF section at every dynamic debug callsite.  At runtime,
  12 * the special section is treated as an array of these.
  13 */
  14struct _ddebug {
  15        /*
  16         * These fields are used to drive the user interface
  17         * for selecting and displaying debug callsites.
  18         */
  19        const char *modname;
  20        const char *function;
  21        const char *filename;
  22        const char *format;
  23        unsigned int lineno:18;
  24        /*
  25         * The flags field controls the behaviour at the callsite.
  26         * The bits here are changed dynamically when the user
  27         * writes commands to <debugfs>/dynamic_debug/control
  28         */
  29#define _DPRINTK_FLAGS_NONE     0
  30#define _DPRINTK_FLAGS_PRINT    (1<<0) /* printk() a message using the format */
  31#define _DPRINTK_FLAGS_INCL_MODNAME     (1<<1)
  32#define _DPRINTK_FLAGS_INCL_FUNCNAME    (1<<2)
  33#define _DPRINTK_FLAGS_INCL_LINENO      (1<<3)
  34#define _DPRINTK_FLAGS_INCL_TID         (1<<4)
  35
  36#define _DPRINTK_FLAGS_INCL_ANY         \
  37        (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
  38         _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
  39
  40#if defined DEBUG
  41#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
  42#else
  43#define _DPRINTK_FLAGS_DEFAULT 0
  44#endif
  45        unsigned int flags:8;
  46#ifdef CONFIG_JUMP_LABEL
  47        union {
  48                struct static_key_true dd_key_true;
  49                struct static_key_false dd_key_false;
  50        } key;
  51#endif
  52} __attribute__((aligned(8)));
  53
  54
  55
  56#if defined(CONFIG_DYNAMIC_DEBUG_CORE)
  57
  58/* exported for module authors to exercise >control */
  59int dynamic_debug_exec_queries(const char *query, const char *modname);
  60
  61int ddebug_add_module(struct _ddebug *tab, unsigned int n,
  62                                const char *modname);
  63extern int ddebug_remove_module(const char *mod_name);
  64extern __printf(2, 3)
  65void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
  66
  67extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
  68                                        const char *modname);
  69
  70struct device;
  71
  72extern __printf(3, 4)
  73void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev,
  74                       const char *fmt, ...);
  75
  76struct net_device;
  77
  78extern __printf(3, 4)
  79void __dynamic_netdev_dbg(struct _ddebug *descriptor,
  80                          const struct net_device *dev,
  81                          const char *fmt, ...);
  82
  83struct ib_device;
  84
  85extern __printf(3, 4)
  86void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
  87                         const struct ib_device *ibdev,
  88                         const char *fmt, ...);
  89
  90#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)                \
  91        static struct _ddebug  __aligned(8)                     \
  92        __section("__dyndbg") name = {                          \
  93                .modname = KBUILD_MODNAME,                      \
  94                .function = __func__,                           \
  95                .filename = __FILE__,                           \
  96                .format = (fmt),                                \
  97                .lineno = __LINE__,                             \
  98                .flags = _DPRINTK_FLAGS_DEFAULT,                \
  99                _DPRINTK_KEY_INIT                               \
 100        }
 101
 102#ifdef CONFIG_JUMP_LABEL
 103
 104#ifdef DEBUG
 105
 106#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)
 107
 108#define DYNAMIC_DEBUG_BRANCH(descriptor) \
 109        static_branch_likely(&descriptor.key.dd_key_true)
 110#else
 111#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
 112
 113#define DYNAMIC_DEBUG_BRANCH(descriptor) \
 114        static_branch_unlikely(&descriptor.key.dd_key_false)
 115#endif
 116
 117#else /* !CONFIG_JUMP_LABEL */
 118
 119#define _DPRINTK_KEY_INIT
 120
 121#ifdef DEBUG
 122#define DYNAMIC_DEBUG_BRANCH(descriptor) \
 123        likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
 124#else
 125#define DYNAMIC_DEBUG_BRANCH(descriptor) \
 126        unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
 127#endif
 128
 129#endif /* CONFIG_JUMP_LABEL */
 130
 131#define __dynamic_func_call(id, fmt, func, ...) do {    \
 132        DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt);         \
 133        if (DYNAMIC_DEBUG_BRANCH(id))                   \
 134                func(&id, ##__VA_ARGS__);               \
 135} while (0)
 136
 137#define __dynamic_func_call_no_desc(id, fmt, func, ...) do {    \
 138        DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt);                 \
 139        if (DYNAMIC_DEBUG_BRANCH(id))                           \
 140                func(__VA_ARGS__);                              \
 141} while (0)
 142
 143/*
 144 * "Factory macro" for generating a call to func, guarded by a
 145 * DYNAMIC_DEBUG_BRANCH. The dynamic debug descriptor will be
 146 * initialized using the fmt argument. The function will be called with
 147 * the address of the descriptor as first argument, followed by all
 148 * the varargs. Note that fmt is repeated in invocations of this
 149 * macro.
 150 */
 151#define _dynamic_func_call(fmt, func, ...)                              \
 152        __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
 153/*
 154 * A variant that does the same, except that the descriptor is not
 155 * passed as the first argument to the function; it is only called
 156 * with precisely the macro's varargs.
 157 */
 158#define _dynamic_func_call_no_desc(fmt, func, ...)      \
 159        __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
 160
 161#define dynamic_pr_debug(fmt, ...)                              \
 162        _dynamic_func_call(fmt, __dynamic_pr_debug,             \
 163                           pr_fmt(fmt), ##__VA_ARGS__)
 164
 165#define dynamic_dev_dbg(dev, fmt, ...)                          \
 166        _dynamic_func_call(fmt,__dynamic_dev_dbg,               \
 167                           dev, fmt, ##__VA_ARGS__)
 168
 169#define dynamic_netdev_dbg(dev, fmt, ...)                       \
 170        _dynamic_func_call(fmt, __dynamic_netdev_dbg,           \
 171                           dev, fmt, ##__VA_ARGS__)
 172
 173#define dynamic_ibdev_dbg(dev, fmt, ...)                        \
 174        _dynamic_func_call(fmt, __dynamic_ibdev_dbg,            \
 175                           dev, fmt, ##__VA_ARGS__)
 176
 177#define dynamic_hex_dump(prefix_str, prefix_type, rowsize,              \
 178                         groupsize, buf, len, ascii)                    \
 179        _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
 180                                   print_hex_dump,                      \
 181                                   KERN_DEBUG, prefix_str, prefix_type, \
 182                                   rowsize, groupsize, buf, len, ascii)
 183
 184#else /* !CONFIG_DYNAMIC_DEBUG_CORE */
 185
 186#include <linux/string.h>
 187#include <linux/errno.h>
 188#include <linux/printk.h>
 189
 190static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
 191                                    const char *modname)
 192{
 193        return 0;
 194}
 195
 196static inline int ddebug_remove_module(const char *mod)
 197{
 198        return 0;
 199}
 200
 201static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
 202                                                const char *modname)
 203{
 204        if (strstr(param, "dyndbg")) {
 205                /* avoid pr_warn(), which wants pr_fmt() fully defined */
 206                printk(KERN_WARNING "dyndbg param is supported only in "
 207                        "CONFIG_DYNAMIC_DEBUG builds\n");
 208                return 0; /* allow and ignore */
 209        }
 210        return -EINVAL;
 211}
 212
 213#define dynamic_pr_debug(fmt, ...)                                      \
 214        do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
 215#define dynamic_dev_dbg(dev, fmt, ...)                                  \
 216        do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0)
 217#define dynamic_hex_dump(prefix_str, prefix_type, rowsize,              \
 218                         groupsize, buf, len, ascii)                    \
 219        do { if (0)                                                     \
 220                print_hex_dump(KERN_DEBUG, prefix_str, prefix_type,     \
 221                                rowsize, groupsize, buf, len, ascii);   \
 222        } while (0)
 223
 224static inline int dynamic_debug_exec_queries(const char *query, const char *modname)
 225{
 226        pr_warn("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n");
 227        return 0;
 228}
 229
 230#endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
 231
 232#endif
 233