blob: c0c6ea9ea7e3624a7cc0ab6053d94d3adc50015e [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _DYNAMIC_DEBUG_H
3#define _DYNAMIC_DEBUG_H
4
David Brazdil0f672f62019-12-10 10:32:29 +00005#if defined(CONFIG_JUMP_LABEL)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00006#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#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;
David Brazdil0f672f62019-12-10 10:32:29 +000041#ifdef CONFIG_JUMP_LABEL
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000042 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
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000050
Olivier Deprez157378f2022-04-04 15:47:50 +020051#if defined(CONFIG_DYNAMIC_DEBUG_CORE)
52
David Brazdil0f672f62019-12-10 10:32:29 +000053int ddebug_add_module(struct _ddebug *tab, unsigned int n,
54 const char *modname);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000055extern int ddebug_remove_module(const char *mod_name);
56extern __printf(2, 3)
57void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...);
58
59extern int ddebug_dyndbg_module_param_cb(char *param, char *val,
60 const char *modname);
61
62struct device;
63
64extern __printf(3, 4)
65void __dynamic_dev_dbg(struct _ddebug *descriptor, const struct device *dev,
66 const char *fmt, ...);
67
68struct net_device;
69
70extern __printf(3, 4)
71void __dynamic_netdev_dbg(struct _ddebug *descriptor,
72 const struct net_device *dev,
73 const char *fmt, ...);
74
David Brazdil0f672f62019-12-10 10:32:29 +000075struct ib_device;
76
77extern __printf(3, 4)
78void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
79 const struct ib_device *ibdev,
80 const char *fmt, ...);
81
82#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000083 static struct _ddebug __aligned(8) \
Olivier Deprez157378f2022-04-04 15:47:50 +020084 __section("__dyndbg") name = { \
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000085 .modname = KBUILD_MODNAME, \
86 .function = __func__, \
87 .filename = __FILE__, \
88 .format = (fmt), \
89 .lineno = __LINE__, \
90 .flags = _DPRINTK_FLAGS_DEFAULT, \
David Brazdil0f672f62019-12-10 10:32:29 +000091 _DPRINTK_KEY_INIT \
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000092 }
93
David Brazdil0f672f62019-12-10 10:32:29 +000094#ifdef CONFIG_JUMP_LABEL
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000095
96#ifdef DEBUG
David Brazdil0f672f62019-12-10 10:32:29 +000097
98#define _DPRINTK_KEY_INIT .key.dd_key_true = (STATIC_KEY_TRUE_INIT)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000099
100#define DYNAMIC_DEBUG_BRANCH(descriptor) \
101 static_branch_likely(&descriptor.key.dd_key_true)
102#else
David Brazdil0f672f62019-12-10 10:32:29 +0000103#define _DPRINTK_KEY_INIT .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000104
105#define DYNAMIC_DEBUG_BRANCH(descriptor) \
106 static_branch_unlikely(&descriptor.key.dd_key_false)
107#endif
108
Olivier Deprez157378f2022-04-04 15:47:50 +0200109#else /* !CONFIG_JUMP_LABEL */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000110
David Brazdil0f672f62019-12-10 10:32:29 +0000111#define _DPRINTK_KEY_INIT
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000112
113#ifdef DEBUG
114#define DYNAMIC_DEBUG_BRANCH(descriptor) \
115 likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
116#else
117#define DYNAMIC_DEBUG_BRANCH(descriptor) \
118 unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
119#endif
120
Olivier Deprez157378f2022-04-04 15:47:50 +0200121#endif /* CONFIG_JUMP_LABEL */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000122
David Brazdil0f672f62019-12-10 10:32:29 +0000123#define __dynamic_func_call(id, fmt, func, ...) do { \
124 DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
125 if (DYNAMIC_DEBUG_BRANCH(id)) \
126 func(&id, ##__VA_ARGS__); \
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000127} while (0)
128
David Brazdil0f672f62019-12-10 10:32:29 +0000129#define __dynamic_func_call_no_desc(id, fmt, func, ...) do { \
130 DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
131 if (DYNAMIC_DEBUG_BRANCH(id)) \
132 func(__VA_ARGS__); \
133} while (0)
134
135/*
136 * "Factory macro" for generating a call to func, guarded by a
Olivier Deprez157378f2022-04-04 15:47:50 +0200137 * DYNAMIC_DEBUG_BRANCH. The dynamic debug descriptor will be
David Brazdil0f672f62019-12-10 10:32:29 +0000138 * initialized using the fmt argument. The function will be called with
139 * the address of the descriptor as first argument, followed by all
140 * the varargs. Note that fmt is repeated in invocations of this
141 * macro.
142 */
143#define _dynamic_func_call(fmt, func, ...) \
144 __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
145/*
146 * A variant that does the same, except that the descriptor is not
147 * passed as the first argument to the function; it is only called
148 * with precisely the macro's varargs.
149 */
150#define _dynamic_func_call_no_desc(fmt, func, ...) \
151 __dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
152
153#define dynamic_pr_debug(fmt, ...) \
154 _dynamic_func_call(fmt, __dynamic_pr_debug, \
155 pr_fmt(fmt), ##__VA_ARGS__)
156
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000157#define dynamic_dev_dbg(dev, fmt, ...) \
David Brazdil0f672f62019-12-10 10:32:29 +0000158 _dynamic_func_call(fmt,__dynamic_dev_dbg, \
159 dev, fmt, ##__VA_ARGS__)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000160
161#define dynamic_netdev_dbg(dev, fmt, ...) \
David Brazdil0f672f62019-12-10 10:32:29 +0000162 _dynamic_func_call(fmt, __dynamic_netdev_dbg, \
163 dev, fmt, ##__VA_ARGS__)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000164
David Brazdil0f672f62019-12-10 10:32:29 +0000165#define dynamic_ibdev_dbg(dev, fmt, ...) \
166 _dynamic_func_call(fmt, __dynamic_ibdev_dbg, \
167 dev, fmt, ##__VA_ARGS__)
168
169#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
170 groupsize, buf, len, ascii) \
171 _dynamic_func_call_no_desc(__builtin_constant_p(prefix_str) ? prefix_str : "hexdump", \
172 print_hex_dump, \
173 KERN_DEBUG, prefix_str, prefix_type, \
174 rowsize, groupsize, buf, len, ascii)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000175
Olivier Deprez157378f2022-04-04 15:47:50 +0200176#else /* !CONFIG_DYNAMIC_DEBUG_CORE */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000177
178#include <linux/string.h>
179#include <linux/errno.h>
Olivier Deprez157378f2022-04-04 15:47:50 +0200180#include <linux/printk.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000181
David Brazdil0f672f62019-12-10 10:32:29 +0000182static inline int ddebug_add_module(struct _ddebug *tab, unsigned int n,
183 const char *modname)
184{
185 return 0;
186}
187
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000188static inline int ddebug_remove_module(const char *mod)
189{
190 return 0;
191}
192
193static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
194 const char *modname)
195{
Olivier Deprez92d4c212022-12-06 15:05:30 +0100196 if (!strcmp(param, "dyndbg")) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000197 /* avoid pr_warn(), which wants pr_fmt() fully defined */
198 printk(KERN_WARNING "dyndbg param is supported only in "
199 "CONFIG_DYNAMIC_DEBUG builds\n");
200 return 0; /* allow and ignore */
201 }
202 return -EINVAL;
203}
204
205#define dynamic_pr_debug(fmt, ...) \
206 do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
207#define dynamic_dev_dbg(dev, fmt, ...) \
208 do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0)
David Brazdil0f672f62019-12-10 10:32:29 +0000209#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \
210 groupsize, buf, len, ascii) \
211 do { if (0) \
212 print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, \
213 rowsize, groupsize, buf, len, ascii); \
214 } while (0)
Olivier Deprez157378f2022-04-04 15:47:50 +0200215
Olivier Deprez157378f2022-04-04 15:47:50 +0200216#endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000217
218#endif