convert dynamic_debug to use jump labels
Subsystems (7)
Jason Baron
maintainerv3 cover convert dynamic_debug to use jump labels
Hi,
Since v2, I found that s390, sparc, and tile could end up with link errors such as:
.exit.text' referenced in section __jump_table' of drivers/built-in.o: defined in discarded section `.exit.text' of drivers/built-in.o
This is due to the fact the '__jump_table' may reference text in an __exit section which is discarded during build/link time. Thus, the sparc, arm and tile patch have been added to address this issue.
In addition, an 'allyesconfig' on arm did not build either due to the usage of -O0 compiler flag. This has been removed in this patch: http://lkml.iu.edu/hypermail/linux/kernel/1606.3/01587.html
So this series depends on that patch to build properly on arm (which I currently see being pulled into linux-next).
-v3:
*added sparc, arm, tile patches for cross section references *re-based on (4c5ea0a locking/static_key: Fix concurrent static_key_slow_inc())
Thanks,
-Jason
Chris Metcalf (1):
tile: support static_key usage in non-module __exit sections
Jason Baron (6):
powerpc: add explicit #include <asm/asm-compat.h> for jump label
s390: add explicit #include <linux/stringify.h> for jump label
sparc: support static_key usage in non-module __exit sections
arm: jump label may reference text in __exit
jump_label: remove bug.h, atomic.h dependencies for HAVE_JUMP_LABEL
dynamic_debug: add jump label support
arch/arm/kernel/vmlinux.lds.S | 2 +- arch/powerpc/include/asm/jump_label.h | 1 + arch/s390/include/asm/jump_label.h | 1 + arch/sparc/kernel/vmlinux.lds.S | 7 ++++ arch/tile/kernel/vmlinux.lds.S | 12 +++++++ include/linux/dynamic_debug.h | 60 +++++++++++++++++++++++++++++++---- include/linux/jump_label.h | 46 +++++++++++++-------------- kernel/jump_label.c | 53 +++++++++++++++++++++++++++++++ lib/dynamic_debug.c | 7 ++++ 9 files changed, 159 insertions(+), 30 deletions(-)
Signature · 1 line
2.6.1
Jason Baron
maintainerPATCH v3 1/7 powerpc: add explicit #include <asm/asm-compat.h> for jump label
The stringify_in_c() macro may not be included. Make the dependency explicit.
--- arch/powerpc/include/asm/jump_label.h | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/include/asm/jump_label.h +1 -0
@@ -14,6 +14,7 @@#include <linux/types.h> #include <asm/feature-fixups.h> +#include <asm/asm-compat.h> #define JUMP_ENTRY_TYPE stringify_in_c(FTR_ENTRY_LONG)#define JUMP_LABEL_NOP_SIZE 4
Signature · 1 line
2.6.1
Re: [v3, 1/7] powerpc: add explicit #include <asm/asm-compat.h> for jump label
Quoted 8 lines · On Wed, 2016-06-07 at 21:42:30 UTC, [email protected] wrote:
The
stringify_in_c()macro may not be included. Make the dependency explicit.Cc Benjamin Herrenschmidt <[email protected]>Cc Paul Mackerras <[email protected]>Cc Michael Ellerman <[email protected]>Signed-off-by Jason Baron <[email protected]>
I didn't test it, but assuming you did:
cheers
Jason Baron
maintainerPATCH v3 2/7 s390: add explicit <linux/stringify.h> for jump label
In reply to Jason BaronEnsure that we always have __stringify().
--- arch/s390/include/asm/jump_label.h | 1 + 1 file changed, 1 insertion(+)
arch/s390/include/asm/jump_label.h +1 -0
@@ -4,6 +4,7 @@#ifndef __ASSEMBLY__#include <linux/types.h> +#include <linux/stringify.h> #define JUMP_LABEL_NOP_SIZE 6#define JUMP_LABEL_NOP_OFFSET 2
Signature · 1 line
2.6.1
Jason Baron
maintainerPATCH v3 3/7 sparc: support static_key usage in non-module __exit sections
In reply to Jason BaronThe jump table can reference text found in an __exit section. Thus, instead of discarding it at build/link time, include EXIT_TEXT as part of __init and release it at system boot time.
Without this patch the link fails with:
.exit.text' referenced in section __jump_table' of xxx.o:
defined in discarded section `.exit.text' of xxx.o
--- arch/sparc/kernel/vmlinux.lds.S | 7 +++++++ 1 file changed, 7 insertions(+)
arch/sparc/kernel/vmlinux.lds.S +7 -0
@@ -150,6 +150,13 @@ SECTIONS } PERCPU_SECTION(SMP_CACHE_BYTES) +#ifdef CONFIG_JUMP_LABEL + . = ALIGN(PAGE_SIZE); + .exit.text : { + EXIT_TEXT + } +#endif + . = ALIGN(PAGE_SIZE); __init_end = .; BSS_SECTION(0, 0, 0)
Signature · 1 line
2.6.1
Re: [PATCH v3 3/7] sparc: support static_key usage in non-module __exit sections
From: Jason Baron <[email protected]>
Date: Wed, 6 Jul 2016 17:42:32 -0400
Quoted 4 lines
The jump table can reference text found in an
__exitsection. Thus, instead of discarding it at build/link time, includeEXIT_TEXTas part of__initand release it at system boot time.
Quoted 8 lines
Without this patch the link fails with:
.exit.text' referenced in section__jump_table' of xxx.o:
defined in discarded section `.exit.text' of xxx.oCc "David S. Miller" <[email protected]>Signed-off-by Jason Baron <[email protected]>
Jason Baron
maintainerPATCH v3 4/7 tile: support static_key usage in non-module __exit sections
In reply to Jason BaronFrom: Chris Metcalf <[email protected]>
Previously, all the __exit sections were just dropped by the link phase. However, if there are static_key (jump label) constructs in __exit sections that are not modules, the link fails with the message:
.exit.text' referenced in section __jump_table' of xxx.o:
defined in discarded section `.exit.text' of xxx.o
Support this usage by keeping the .exit.text sections in the final image if JUMP_LABEL is defined, then discarding them once initialization is complete.
--- arch/tile/kernel/vmlinux.lds.S | 12 ++++++++++++ 1 file changed, 12 insertions(+)
arch/tile/kernel/vmlinux.lds.S +12 -0
@@ -60,6 +60,18 @@ SECTIONS /* "Init" is divided into two areas with very different virtual addresses. */ INIT_TEXT_SECTION(PAGE_SIZE) + /* + * Some things, like the __jump_table, may contain symbol references + * to __exit text, so include such text in the final image if so. + * In that case we also override the _einittext from INIT_TEXT_SECTION. + */ +#ifdef CONFIG_JUMP_LABEL + .exit.text : { + EXIT_TEXT + _einittext = .; + } +#endif + /* Now we skip back to PAGE_OFFSET for the data. */ . = (. - TEXT_OFFSET + PAGE_OFFSET); #undef LOAD_OFFSET
Signature · 1 line
2.6.1
Jason Baron
maintainerPATCH v3 5/7 arm: jump label may reference text in __exit
In reply to Jason BaronThe jump table can reference text found in an __exit section. Thus, instead of discarding it at build time, include EXIT_TEXT as part of __init and it will be released when the system boots.
--- arch/arm/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/kernel/vmlinux.lds.S +1 -1
@@ -44,7 +44,7 @@ #endif #if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \ - defined(CONFIG_GENERIC_BUG) + defined(CONFIG_GENERIC_BUG) || defined(CONFIG_JUMP_LABEL) #define ARM_EXIT_KEEP(x) x #define ARM_EXIT_DISCARD(x) #else
Signature · 1 line
2.6.1
Jason Baron
maintainerPATCH v3 6/7 jump_label: remove bug.h, atomic.h dependencies for HAVE_JUMP_LABEL
In reply to Jason BaronThe current jump_label.h includes bug.h for things such as WARN_ON(). This makes the header problematic for inclusion by kernel.h or any headers that kernel.h includes, since bug.h includes kernel.h (circular dependency). The inclusion of atomic.h is similarly problematic. Thus, this should make jump_label.h 'includable' from most places.
--- include/linux/jump_label.h | 46 ++++++++++++++++++++-------------------- kernel/jump_label.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 23 deletions(-)
include/linux/jump_label.h +23 -23
@@ -76,7 +76,6 @@#include <linux/types.h> #include <linux/compiler.h> -#include <linux/bug.h> extern bool static_key_initialized;
@@ -115,20 +114,8 @@ enum jump_label_type {struct module ; -#include <linux/atomic.h> -#ifdef HAVE_JUMP_LABEL -static inline int static_key_count (struct static_key *key) -{ -/* -* -1 means the first static_key_slow_inc() is in progress. -* static_key_enabled() must return true, so return 1 here. -*/ -int n =atomic_read (&key->enabled); -return n >=0 ? n :1 ; -} -#define JUMP_TYPE_FALSE 0UL#define JUMP_TYPE_TRUE 1UL#define JUMP_TYPE_MASK 1UL
@@ -157,16 +144,29 @@ extern int jump_label_text_reserved(void *start, void *end);extern void static_key_slow_inc (struct static_key *key);extern void static_key_slow_dec (struct static_key *key);extern void jump_label_apply_nops (struct module *mod); +extern int static_key_count (struct static_key *key); +extern void static_key_enable (struct static_key *key); +extern void static_key_disable (struct static_key *key); +/* +* We should be using ATOMIC_INIT() for initializing .enabled, but +* the inclusion of atomic.h is problematic for inclusion of jump_label.h +* in 'low-level' headers. Thus, we are initializing .enabled with a +* raw value, but have added a BUILD_BUG_ON() to catch any issues in +* jump_label_init() see: kernel/jump_label.c. +*/ #define STATIC_KEY_INIT_TRUE \ - { .enabled = ATOMIC_INIT(1), \ + { .enabled = { 1 }, \ .entries = (void *)JUMP_TYPE_TRUE }#define STATIC_KEY_INIT_FALSE \ - { .enabled = ATOMIC_INIT(0), \ + { .enabled = { 0 }, \ .entries = (void *)JUMP_TYPE_FALSE }#else /* !HAVE_JUMP_LABEL */ +#include <linux/atomic.h> +#include <linux/bug.h> +static inline int static_key_count (struct static_key *key) {return atomic_read (&key->enabled);
@@ -216,14 +216,6 @@ static inline int jump_label_apply_nops(struct module *mod)return 0 ; } -#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) } -#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) } - -#endif /* HAVE_JUMP_LABEL */ - -#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE -#define jump_label_enabled static_key_enabled -static inline void static_key_enable (struct static_key *key) {int count =static_key_count (key);
@@ -244,6 +236,14 @@ static inline void static_key_disable(struct static_key *key) static_key_slow_dec(key); } +#define STATIC_KEY_INIT_TRUE { .enabled = ATOMIC_INIT(1) } +#define STATIC_KEY_INIT_FALSE { .enabled = ATOMIC_INIT(0) } + +#endif /* HAVE_JUMP_LABEL */ + +#define STATIC_KEY_INIT STATIC_KEY_INIT_FALSE +#define jump_label_enabled static_key_enabled +/* -------------------------------------------------------------------------- */ /*
kernel/jump_label.c +53 -0
71 lines not on this page · raw message
Signature · 1 line
2.6.1
Jason Baron
maintainerPATCH v3 7/7 dynamic_debug: add jump label support
In reply to Jason BaronAlthough 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
--- include/linux/dynamic_debug.h | 60 ++++++++++++++++++++++++++++++++++++++----- lib/dynamic_debug.c | 7 +++++ 2 files changed, 61 insertions(+), 6 deletions(-)
include/linux/dynamic_debug.h +54 -6
@@ -1,6 +1,10 @@#ifndef _DYNAMIC_DEBUG_H#define _DYNAMIC_DEBUG_H +#if defined(CC_HAVE_ASM_GOTO ) && defined(CONFIG_JUMP_LABEL ) +#include <linux/jump_label.h> +#endif +/* * An instance of this structure is created in a special * ELF section at every dynamic debug callsite. At runtime,
@@ -33,6 +37,12 @@ struct _ddebug {#define _DPRINTK_FLAGS_DEFAULT 0#endif unsigned int flags:8; +#ifdef HAVE_JUMP_LABEL +union { +struct static_key_true dd_key_true; +struct static_key_false dd_key_false; + } key; +#endif } __attribute__((aligned(8)));
@@ -60,7 +70,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,const struct net_device *dev, const char *fmt, ...); -#define DEFINE_DYNAMIC_DEBUG_METADATA (name, fmt) \ +#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY (name, fmt, key, init) \ static struct _ddebug __aligned(8) \ __attribute__((section("__verbose"))) name = { \ .modname = KBUILD_MODNAME, \
@@ -68,13 +78,51 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor, .filename = __FILE__, \ .format = (fmt), \ .lineno = __LINE__, \ - .flags = _DPRINTK_FLAGS_DEFAULT, \ + .flags = _DPRINTK_FLAGS_DEFAULT, \ + dd_key_init(key, init) \ } +#ifdef HAVE_JUMP_LABEL + +#define dd_key_init (key, init) key = (init) + +#ifdef DEBUG +#define DEFINE_DYNAMIC_DEBUG_METADATA (name, fmt) \ + DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_true, \ + (STATIC_KEY_TRUE_INIT)) + +#define DYNAMIC_DEBUG_BRANCH (descriptor) \ + static_branch_likely(&descriptor.key.dd_key_true) +#else +#define DEFINE_DYNAMIC_DEBUG_METADATA (name, fmt) \ + DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \ + (STATIC_KEY_FALSE_INIT)) + +#define DYNAMIC_DEBUG_BRANCH (descriptor) \ + static_branch_unlikely(&descriptor.key.dd_key_false) +#endif + +#else + +#define dd_key_init (key, init) + +#define DEFINE_DYNAMIC_DEBUG_METADATA (name, fmt) \ + DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0) + +#ifdef DEBUG +#define DYNAMIC_DEBUG_BRANCH (descriptor) \ + likely(descriptor.flags & _DPRINTK_FLAGS_PRINT) +#else +#define DYNAMIC_DEBUG_BRANCH (descriptor) \ + unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) +#endif + +#endif +#define dynamic_pr_debug (fmt, ...) \ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ ##__VA_ARGS__); \ } while (0)
@@ -82,7 +130,7 @@ do { \#define dynamic_dev_dbg (dev, fmt, ...) \ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ __dynamic_dev_dbg(&descriptor, dev, fmt, \ ##__VA_ARGS__); \ } while (0)
@@ -90,7 +138,7 @@ do { \#define dynamic_netdev_dbg (dev, fmt, ...) \ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ __dynamic_netdev_dbg(&descriptor, dev, fmt, \ ##__VA_ARGS__); \ } while (0)
@@ -100,7 +148,7 @@ do { \ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \ __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\ - if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ + if (DYNAMIC_DEBUG_BRANCH(descriptor)) \ print_hex_dump(KERN_DEBUG, prefix_str, \ prefix_type, rowsize, groupsize, \ buf, len, ascii); \
lib/dynamic_debug.c +7 -0
@@ -188,6 +188,13 @@ static int ddebug_change(const struct ddebug_query *query, newflags = (dp->flags & mask) | flags;if (newflags == dp->flags)continue ; +#ifdef HAVE_JUMP_LABEL +if (dp->flags & _DPRINTK_FLAGS_PRINT) { +if (!(flags & _DPRINTK_FLAGS_PRINT)) +static_branch_disable (&dp->key.dd_key_true); + }else if (flags & _DPRINTK_FLAGS_PRINT) +static_branch_enable (&dp->key.dd_key_true); +#endif dp->flags = newflags; vpr_info("changed %s:%d [%s]%s =%s\n", trim_prefix(dp->filename), dp->lineno,
Signature · 1 line
2.6.1
Re: [PATCH v3 7/7] dynamic_debug: add jump label support
Quoted 9 lines · Jason Baron
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
Maybe to get some of that space back on the 32 bit builds the 8 byte alignment can be relaxed.
include/linux/dynamic_debug.h
Quoted 1 line
include/linux/dynamic_debug.h +0
-0
[]
include/linux/dynamic_debug.h struct _ddebug { · line 46
Quoted 11 lines
include/linux/dynamic_debug.h +6
-0@@ -33,6 +37,12 @@ struct _ddebug { #define _DPRINTK_FLAGS_DEFAULT 0 #endif unsigned int flags:8; +#ifdef HAVE_JUMP_LABEL +union { +struct static_key_true dd_key_true; +struct static_key_false dd_key_false; + } key; +#endif } __attribute__((aligned(8)));
Couldn't this be:
} __aligned(__alignof__(void *));
Quoted 8 lines
include/linux/dynamic_debug.h +0
-0@@ -60,7 +70,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor, const struct net_device *dev, const char *fmt, ...);include/linux/dynamic_debug.h +1
-1-#define DEFINE_DYNAMIC_DEBUG_METADATA (name, fmt) \ +#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY (name, fmt, key, init) \static struct _ddebug __aligned(8) \
__attribute__((section("__verbose"))) name = { \
And this shouldn't need the __aligned as it's already in the structure definition.
Maybe:
static struct _ddebug __section(__verbose) name = {Quoted 1 line
.modname =
KBUILD_MODNAME, \
Jason Baron
maintainerRe: [PATCH v3 7/7] dynamic_debug: add jump label support
Quoted 44 lines · Joe Perches
Quoted 9 lines · Jason Baron
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.postMaybe to get some of that space back on the 32 bit builds the 8 byte alignment can be relaxed.
include/linux/dynamic_debug.h
Quoted 1 line
include/linux/dynamic_debug.h +0
-0[]
include/linux/dynamic_debug.h struct _ddebug { · line 46
Quoted 11 lines
include/linux/dynamic_debug.h +6
-0@@ -33,6 +37,12 @@ struct _ddebug {#define _DPRINTK_FLAGS_DEFAULT 0#endif unsigned int flags:8; +#ifdef HAVE_JUMP_LABEL +union { +struct static_key_true dd_key_true; +struct static_key_false dd_key_false; + } key; +#endif } __attribute__((aligned(8)));Couldn't this be:
}
__aligned(__alignof__(void *));include/linux/dynamic_debug.h void __dynamic_netdev_dbg(struct _ddebug *descriptor, · line 75
Quoted 8 lines
include/linux/dynamic_debug.h +1
-1@@ -60,7 +70,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,const struct net_device *dev, const char *fmt, ...); -#define DEFINE_DYNAMIC_DEBUG_METADATA (name, fmt) \ +#define DEFINE_DYNAMIC_DEBUG_METADATA_KEY (name, fmt, key, init) \ static struct _ddebug __aligned(8) \ __attribute__((section("__verbose"))) name = { \And this shouldn't need the
__alignedas it's already in the structure definition.
Quoted 6 lines
Maybe:
static struct _ddebug __section(__verbose) name = {Quoted 1 line
include/linux/dynamic_debug.h +0
-0.modname = KBUILD_MODNAME, \
hmmm...dropping that last bit increases the size of 'data', and results in an oops on boot, I think b/c the __verbose section adds gaps that the dynamic debug init code is not expecting. We could revisit this for 32-bit, but this is somewhat fragile...
I think we could reduce the size of 'struct static_key' by removing the 'next' field and using the 'entries' when there are multiple modules associated with a key. This will increase the memory usage slightly when there are multiple modules associated with a key, but this is probably not the common case, and certainly for dynamic debug we only have one patch target for each key. That should reduce the 'data' increase by around ~20% and would reduce the size for other users. I can try something along those lines in a re-post...
Thanks,
-Jason
Andrew Morton
maintainerRe: [PATCH v3 7/7] dynamic_debug: add jump label support
In reply to Jason BaronQuoted 8 lines · On Wed, 6 Jul 2016 17:42:36 -0400 Jason Baron <[email protected]> wrote:
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.
...
include/linux/dynamic_debug.h void __dynamic_netdev_dbg(struct _ddebug *descriptor, · line 108
Quoted 10 lines
include/linux/dynamic_debug.h +7
-0+#ifdef HAVE_JUMP_LABEL + +#define dd_key_init (key, init) key = (init) +#else + +#define dd_key_init (key, init) +
umm, lazy. One is an lval and returns a value and the other does neither. Lack of parenthesization in the first version doubtless exposes various horrors.
Care to do something more robust and conventional here? Presumably use symmetrical do{}while(0) things, neither of which is an lval, both of which don't return anything.
Jason Baron
maintainerRe: [PATCH v3 7/7] dynamic_debug: add jump label support
Quoted 24 lines · Andrew Morton
Quoted 8 lines · On Wed, 6 Jul 2016 17:42:36 -0400 Jason Baron <[email protected]> wrote:
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.
...
include/linux/dynamic_debug.h void __dynamic_netdev_dbg(struct _ddebug *descriptor, · line 108
Quoted 10 lines
include/linux/dynamic_debug.h +7
-0+#ifdef HAVE_JUMP_LABEL + +#define dd_key_init (key, init) key = (init) +#else + +#define dd_key_init (key, init) +umm, lazy. One is an lval and returns a value and the other does neither. Lack of parenthesization in the first version doubtless exposes various horrors.
Quoted 4 lines
Care to do something more robust and conventional here? Presumably use symmetrical do{}while(0) things, neither of which is an lval, both of which don't return anything.
Hi,
The 'dd_key_init()' macro is being used here to help initialize the 'key' field in the 'struct _ddebug', and its not being used as a statement.
In the 'HAVE_JUMP_LABEL' case, we are initializing the 'key' field, while in the not-'HAVE_JUMP_LABEL' case, the 'key' field is simply not present in the structure (to conserve space).
Thanks,
-Jason
Andrew Morton
maintainerRe: [PATCH v3 7/7] dynamic_debug: add jump label support
Quoted 32 lines · On Mon, 11 Jul 2016 09:18:21 -0400 Jason Baron <[email protected]> wrote:
Quoted 24 lines · Andrew Morton
Quoted 8 lines · On Wed, 6 Jul 2016 17:42:36 -0400 Jason Baron <[email protected]> wrote:
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.
...
include/linux/dynamic_debug.h void __dynamic_netdev_dbg(struct _ddebug *descriptor, · line 108
Quoted 10 lines
include/linux/dynamic_debug.h +7
-0+#ifdef HAVE_JUMP_LABEL + +#define dd_key_init (key, init) key = (init) +#else + +#define dd_key_init (key, init) +umm, lazy. One is an lval and returns a value and the other does neither. Lack of parenthesization in the first version doubtless exposes various horrors.
Quoted 4 lines
Care to do something more robust and conventional here? Presumably use symmetrical do{}while(0) things, neither of which is an lval, both of which don't return anything.
Hi,
Quoted 7 lines
The '
dd_key_init()' macro is being used here to help initialize the 'key' field in the 'struct_ddebug', and its not being used as a statement.In the '
HAVE_JUMP_LABEL' case, we are initializing the 'key' field, while in the not-'HAVE_JUMP_LABEL' case, the 'key' field is simply not present in the structure (to conserve space).
Well yeah. And it's doing it wrongly, isn't it?
: @@ -68,13 +78,51 @@ void __dynamic_netdev_dbg(struct _ddebug
: .filename = __FILE__, \ : .format = (fmt), \ : .lineno = __LINE__, \
: - .flags = _DPRINTK_FLAGS_DEFAULT, \
: + .flags = _DPRINTK_FLAGS_DEFAULT, \
: + dd_key_init(key, init) \
: }
:
: +#ifdef HAVE_JUMP_LABEL
: +
: +#define dd_key_init(key, init) key = (init)
Shouldn't it be ".key = (init)"?
Anyway, it's odd-looking. I guess something like
#define DD_KEY_INIT(init) .key = (init)
would be more idiomatic.
Jason Baron
maintainerRe: [PATCH v3 7/7] dynamic_debug: add jump label support
Quoted 55 lines · Andrew Morton
Quoted 31 lines · On Mon, 11 Jul 2016 09:18:21 -0400 Jason Baron <[email protected]> wrote:
Quoted 24 lines · Andrew Morton
Quoted 8 lines · On Wed, 6 Jul 2016 17:42:36 -0400 Jason Baron <[email protected]> wrote:
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.
...
include/linux/dynamic_debug.h void __dynamic_netdev_dbg(struct _ddebug *descriptor, · line 108
Quoted 10 lines
include/linux/dynamic_debug.h +7
-0+#ifdef HAVE_JUMP_LABEL + +#define dd_key_init (key, init) key = (init) +#else + +#define dd_key_init (key, init) +umm, lazy. One is an lval and returns a value and the other does neither. Lack of parenthesization in the first version doubtless exposes various horrors.
Quoted 4 lines
Care to do something more robust and conventional here? Presumably use symmetrical do{}while(0) things, neither of which is an lval, both of which don't return anything.
Hi,
Quoted 7 lines
The '
dd_key_init()' macro is being used here to help initialize the 'key' field in the 'struct_ddebug', and its not being used as a statement.In the '
HAVE_JUMP_LABEL' case, we are initializing the 'key' field, while in the not-'HAVE_JUMP_LABEL' case, the 'key' field is simply not present in the structure (to conserve space).Well yeah. And it's doing it wrongly, isn't it?
: @@ -68,13 +78,51 @@ void __dynamic_netdev_dbg(struct
_ddebug: .filename = __FILE__, \ : .format = (fmt), \ : .lineno = __LINE__, \: - .flags =
_DPRINTK_FLAGS_DEFAULT, \
: + .flags =_DPRINTK_FLAGS_DEFAULT, \
: +dd_key_init(key, init)\
: }
:
: +#ifdefHAVE_JUMP_LABEL
: +
: +#definedd_key_init(key, init)key = (init)
Quoted 7 lines
Shouldn't it be ".key = (init)"?
Anyway, it's odd-looking. I guess something like
#define
DD_KEY_INIT(init).key = (init)would be more idiomatic.
Ok, so the 'key' field is a union and so the patch is effectively calling (after substitution):
dd_key_init(.key.dd_key_true, STATIC_KEY_TRUE_INIT)
and:
dd_key_init(.key.dd_key_true, STATIC_KEY_FALSE_INIT)
So we could have variations such as:
#define dd_key_true_init() .key.dd_key_true = (STATIC_KEY_TRUE_INIT) #define dd_key_false_init()
and
#define dd_key_true_init()
#define dd_key_false_init() .key.dd_key_false = (STATIC_KEY_FALSE_INIT)
and finally:
#define dd_key_true_init()
#define dd_key_false_init()
and then have both dd_key_true_init() and dd_key_fase_init() in the structure definition. It adds a bunch more definitions and I'm not sure if its more readable, but maybe it would look cleaner?
Thanks,
-Jason