Commit 9049fc745300c5e2236cbfc69f5e8cadb6f1f57c
Committed by
Linus Torvalds
1 parent
1f69bf9c61
Exists in
smarct4x-processor-sdk-04.01.00.06
and in
1 other branch
dynamic_debug: add jump label support
Although dynamic debug is often only used for debug builds, sometimes its enabled for production builds as well. Minimize its impact by using jump labels. This reduces the text section by 7000+ bytes in the kernel image below. It does increase data, but this should only be referenced when changing the direction of the branches, and hence usually not in cache. text data bss dec hex filename 8194852 4879776 925696 14000324 d5a0c4 vmlinux.pre 8187337 4960224 925696 14073257 d6bda9 vmlinux.post Link: http://lkml.kernel.org/r/d165b465e8c89bc582d973758d40be44c33f018b.1467837322.git.jbaron@akamai.com Signed-off-by: Jason Baron <jbaron@akamai.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Joe Perches <joe@perches.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 61 additions and 6 deletions Side-by-side Diff
include/linux/dynamic_debug.h
1 | 1 | #ifndef _DYNAMIC_DEBUG_H |
2 | 2 | #define _DYNAMIC_DEBUG_H |
3 | 3 | |
4 | +#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) | |
5 | +#include <linux/jump_label.h> | |
6 | +#endif | |
7 | + | |
4 | 8 | /* |
5 | 9 | * An instance of this structure is created in a special |
6 | 10 | * ELF section at every dynamic debug callsite. At runtime, |
... | ... | @@ -33,6 +37,12 @@ |
33 | 37 | #define _DPRINTK_FLAGS_DEFAULT 0 |
34 | 38 | #endif |
35 | 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 | |
36 | 46 | } __attribute__((aligned(8))); |
37 | 47 | |
38 | 48 | |
... | ... | @@ -60,7 +70,7 @@ |
60 | 70 | const struct net_device *dev, |
61 | 71 | const char *fmt, ...); |
62 | 72 | |
63 | -#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ | |
73 | +#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init) \ | |
64 | 74 | static struct _ddebug __aligned(8) \ |
65 | 75 | __attribute__((section("__verbose"))) name = { \ |
66 | 76 | .modname = KBUILD_MODNAME, \ |
67 | 77 | |
68 | 78 | |
... | ... | @@ -68,13 +78,51 @@ |
68 | 78 | .filename = __FILE__, \ |
69 | 79 | .format = (fmt), \ |
70 | 80 | .lineno = __LINE__, \ |
71 | - .flags = _DPRINTK_FLAGS_DEFAULT, \ | |
81 | + .flags = _DPRINTK_FLAGS_DEFAULT, \ | |
82 | + dd_key_init(key, init) \ | |
72 | 83 | } |
73 | 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 | + | |
74 | 122 | #define dynamic_pr_debug(fmt, ...) \ |
75 | 123 | do { \ |
76 | 124 | DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ |
77 | - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ | |
125 | + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ | |
78 | 126 | __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ |
79 | 127 | ##__VA_ARGS__); \ |
80 | 128 | } while (0) |
... | ... | @@ -82,7 +130,7 @@ |
82 | 130 | #define dynamic_dev_dbg(dev, fmt, ...) \ |
83 | 131 | do { \ |
84 | 132 | DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ |
85 | - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ | |
133 | + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ | |
86 | 134 | __dynamic_dev_dbg(&descriptor, dev, fmt, \ |
87 | 135 | ##__VA_ARGS__); \ |
88 | 136 | } while (0) |
... | ... | @@ -90,7 +138,7 @@ |
90 | 138 | #define dynamic_netdev_dbg(dev, fmt, ...) \ |
91 | 139 | do { \ |
92 | 140 | DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ |
93 | - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ | |
141 | + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ | |
94 | 142 | __dynamic_netdev_dbg(&descriptor, dev, fmt, \ |
95 | 143 | ##__VA_ARGS__); \ |
96 | 144 | } while (0) |
... | ... | @@ -100,7 +148,7 @@ |
100 | 148 | do { \ |
101 | 149 | DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \ |
102 | 150 | __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\ |
103 | - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ | |
151 | + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ | |
104 | 152 | print_hex_dump(KERN_DEBUG, prefix_str, \ |
105 | 153 | prefix_type, rowsize, groupsize, \ |
106 | 154 | buf, len, ascii); \ |
lib/dynamic_debug.c
... | ... | @@ -188,6 +188,13 @@ |
188 | 188 | newflags = (dp->flags & mask) | flags; |
189 | 189 | if (newflags == dp->flags) |
190 | 190 | continue; |
191 | +#ifdef HAVE_JUMP_LABEL | |
192 | + if (dp->flags & _DPRINTK_FLAGS_PRINT) { | |
193 | + if (!(flags & _DPRINTK_FLAGS_PRINT)) | |
194 | + static_branch_disable(&dp->key.dd_key_true); | |
195 | + } else if (flags & _DPRINTK_FLAGS_PRINT) | |
196 | + static_branch_enable(&dp->key.dd_key_true); | |
197 | +#endif | |
191 | 198 | dp->flags = newflags; |
192 | 199 | vpr_info("changed %s:%d [%s]%s =%s\n", |
193 | 200 | trim_prefix(dp->filename), dp->lineno, |