Branch data Line data Source code
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 : : */
14 : : struct _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 : : #if defined DEBUG
36 : : #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
37 : : #else
38 : : #define _DPRINTK_FLAGS_DEFAULT 0
39 : : #endif
40 : : unsigned int flags:8;
41 : : #ifdef CONFIG_JUMP_LABEL
42 : : union {
43 : : struct static_key_true dd_key_true;
44 : : struct static_key_false dd_key_false;
45 : : } key;
46 : : #endif
47 : : } __attribute__((aligned(8)));
48 : :
49 : :
50 : :
51 : : #if defined(CONFIG_DYNAMIC_DEBUG)
52 : : int ddebug_add_module(struct _ddebug *tab, unsigned int n,
53 : : const char *modname);
54 : : extern int ddebug_remove_module(const char *mod_name);
55 : : extern __printf(2, 3)
56 : : void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
57 : :
58 : : extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
59 : : const char *modname);
60 : :
61 : : struct device;
62 : :
63 : : extern __printf(3, 4)
64 : : void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev,
65 : : const char *fmt, ...);
66 : :
67 : : struct net_device;
68 : :
69 : : extern __printf(3, 4)
70 : : void __dynamic_netdev_dbg(struct _ddebug *descriptor,
71 : : const struct net_device *dev,
72 : : const char *fmt, ...);
73 : :
74 : : struct ib_device;
75 : :
76 : : extern __printf(3, 4)
77 : : void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
78 : : const struct ib_device *ibdev,
79 : : const char *fmt, ...);
80 : :
81 : : #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
82 : : static struct _ddebug __aligned(8) \
83 : : __attribute__((section("__verbose"))) name = { \
84 : : .modname = KBUILD_MODNAME, \
85 : : .function = __func__, \
86 : : .filename = __FILE__, \
87 : : .format = (fmt), \
88 : : .lineno = __LINE__, \
89 : : .flags = _DPRINTK_FLAGS_DEFAULT, \
90 : : _DPRINTK_KEY_INIT \
91 : : }
92 : :
93 : : #ifdef CONFIG_JUMP_LABEL
94 : :
95 : : #ifdef DEBUG
96 : :
97 : : #define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)
98 : :
99 : : #define DYNAMIC_DEBUG_BRANCH(descriptor) \
100 : : static_branch_likely(&descriptor.key.dd_key_true)
101 : : #else
102 : : #define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
103 : :
104 : : #define DYNAMIC_DEBUG_BRANCH(descriptor) \
105 : : static_branch_unlikely(&descriptor.key.dd_key_false)
106 : : #endif
107 : :
108 : : #else /* !HAVE_JUMP_LABEL */
109 : :
110 : : #define _DPRINTK_KEY_INIT
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_func_call(id, fmt, func, ...) do { \
123 : : DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
124 : : if (DYNAMIC_DEBUG_BRANCH(id)) \
125 : : func(&id, ##__VA_ARGS__); \
126 : : } while (0)
127 : :
128 : : #define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
129 : : DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
130 : : if (DYNAMIC_DEBUG_BRANCH(id)) \
131 : : func(__VA_ARGS__); \
132 : : } while (0)
133 : :
134 : : /*
135 : : * "Factory macro" for generating a call to func, guarded by a
136 : : * DYNAMIC_DEBUG_BRANCH. The dynamic debug decriptor will be
137 : : * initialized using the fmt argument. The function will be called with
138 : : * the address of the descriptor as first argument, followed by all
139 : : * the varargs. Note that fmt is repeated in invocations of this
140 : : * macro.
141 : : */
142 : : #define _dynamic_func_call(fmt, func, ...) \
143 : : __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
144 : : /*
145 : : * A variant that does the same, except that the descriptor is not
146 : : * passed as the first argument to the function; it is only called
147 : : * with precisely the macro's varargs.
148 : : */
149 : : #define _dynamic_func_call_no_desc(fmt, func, ...) \
150 : : __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
151 : :
152 : : #define dynamic_pr_debug(fmt, ...) \
153 : : _dynamic_func_call(fmt, __dynamic_pr_debug, \
154 : : pr_fmt(fmt), ##__VA_ARGS__)
155 : :
156 : : #define dynamic_dev_dbg(dev, fmt, ...) \
157 : : _dynamic_func_call(fmt,__dynamic_dev_dbg, \
158 : : dev, fmt, ##__VA_ARGS__)
159 : :
160 : : #define dynamic_netdev_dbg(dev, fmt, ...) \
161 : : _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
162 : : dev, fmt, ##__VA_ARGS__)
163 : :
164 : : #define dynamic_ibdev_dbg(dev, fmt, ...) \
165 : : _dynamic_func_call(fmt, __dynamic_ibdev_dbg, \
166 : : dev, fmt, ##__VA_ARGS__)
167 : :
168 : : #define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
169 : : groupsize, buf, len, ascii) \
170 : : _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
171 : : print_hex_dump, \
172 : : KERN_DEBUG, prefix_str, prefix_type, \
173 : : rowsize, groupsize, buf, len, ascii)
174 : :
175 : : #else
176 : :
177 : : #include <linux/string.h>
178 : : #include <linux/errno.h>
179 : :
180 : : static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
181 : : const char *modname)
182 : : {
183 : : return 0;
184 : : }
185 : :
186 : : static inline int ddebug_remove_module(const char *mod)
187 : : {
188 : : return 0;
189 : : }
190 : :
191 : : static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
192 : : const char *modname)
193 : : {
194 [ # # ]: 0 : if (strstr(param, "dyndbg")) {
195 : : /* avoid pr_warn(), which wants pr_fmt() fully defined */
196 : 0 : printk(KERN_WARNING "dyndbg param is supported only in "
197 : : "CONFIG_DYNAMIC_DEBUG builds\n");
198 : : return 0; /* allow and ignore */
199 : : }
200 : : return -EINVAL;
201 : : }
202 : :
203 : : #define dynamic_pr_debug(fmt, ...) \
204 : : do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
205 : : #define dynamic_dev_dbg(dev, fmt, ...) \
206 : : do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0)
207 : : #define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
208 : : groupsize, buf, len, ascii) \
209 : : do { if (0) \
210 : : print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, \
211 : : rowsize, groupsize, buf, len, ascii); \
212 : : } while (0)
213 : : #endif
214 : :
215 : : #endif
|