jump label: update for .39
Subsystems (10)
cover jump label: update for .39
Hi,
Re-fresh of updates against latest -tip tree.
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures). I've got a prototype patch to address this issue but its somewhat invasive, and thus I'd like to leave it as a follow-up item. I have to date, not seen this issue in practice.
thanks,
-Jason
Jason Baron (2):
jump label: introduce static_branch() interface
dynamic debug: add jump label support
arch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +- arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/jump_label.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 44 +++- include/linux/jump_label.h | 86 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 537 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- lib/dynamic_debug.c | 4 +- 18 files changed, 391 insertions(+), 496 deletions(-) delete mode 100644 include/linux/jump_label_ref.h
PATCH 1/2 jump label: introduce static_branch() interface
Introduce:
static __always_inline bool static_branch(struct jump_label_key *key);
instead of the old JUMP_LABEL(key, label) macro.
In this way, jump labels become really easy to use:
Define:
struct jump_label_key jump_key;
Can be used as:
if (static_branch(&jump_key))
do unlikely code
enable/disale via:
jump_label_inc(&jump_key);
jump_label_dec(&jump_key);that's it!
For the jump labels disabled case, the static_branch() becomes an atomic_read(), and jump_label_inc()/dec() are simply atomic_inc(), atomic_dec() operations. We show testing results for this change below.
Thanks to H. Peter Anvin for suggesting the 'static_branch()' construct.
Since we now require a 'struct jump_label_key *key', we can store a pointer into the jump table addresses. In this way, we can enable/disable jump labels, in basically constant time. This change allows us to completely remove the previous hashtable scheme. Thanks to Peter Zijlstra for this re-write.
Testing:
I ran a series of 'tbench 20' runs 5 times (with reboots) for 3 configurations, where tracepoints were disabled.
jump label configured in
avg: 815.6
jump label *not* configured in (using atomic reads)
avg: 800.1
jump label *not* configured in (regular reads)
avg: 803.4
thanks,
-Jason
--- arch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +- arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/jump_label.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 2 - include/linux/jump_label.h | 86 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 537 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- 17 files changed, 352 insertions(+), 489 deletions(-) delete mode 100644 include/linux/jump_label_ref.h
arch/mips/include/asm/jump_label.h +12 -10
@@ -20,16 +20,18 @@#define WORD_INSN ".word"#endif -#define JUMP_LABEL (key, label) \ - do { \ - asm goto("1:\tnop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t" \ - WORD_INSN " 1b, %l[" #label "], %0\n\t" \ - ".popsection\n\t" \ - : : "i" (key) : : label); \ - } while (0) - +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\tnop\n\t" +"nop\n\t" +".pushsection __jump_table, \"aw\"\n\t" +WORD_INSN " 1b, %l[l_yes], %0\n\t" +".popsection\n\t" + : :"i" (key) : : l_yes); +return false; +l_yes: +return true; +}#endif /* __KERNEL__ */
arch/mips/kernel/jump_label.c +1 -1
@@ -6,11 +6,11 @@* Copyright (c) 2010 Cavium Networks, Inc. */ -#include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/memory.h> #include <linux/mutex.h> #include <linux/types.h> +#include <linux/jump_label.h> #include <linux/cpu.h> #include <asm/cacheflush.h>
arch/sparc/include/asm/jump_label.h +14 -11
@@ -7,17 +7,20 @@#define JUMP_LABEL_NOP_SIZE 4 -#define JUMP_LABEL (key, label) \ - do { \ - asm goto("1:\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t"\ - ".align 4\n\t" \ - ".word 1b, %l[" #label "], %c0\n\t" \ - ".popsection \n\t" \ - : : "i" (key) : : label);\ - } while (0) +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\n\t" +"nop\n\t" +"nop\n\t" +".pushsection __jump_table, \"aw\"\n\t" +".align 4\n\t" +".word 1b, %l[l_yes], %c0\n\t" +".popsection \n\t" + : :"i" (key) : : l_yes); +return false; +l_yes: +return true; +}#endif /* __KERNEL__ */
arch/x86/include/asm/alternative.h +1 -2
@@ -4,7 +4,6 @@#include <linux/types.h> #include <linux/stddef.h> #include <linux/stringify.h> -#include <linux/jump_label.h> #include <asm/asm.h> /*
@@ -191,7 +190,7 @@ extern void *text_poke(void *addr, const void *opcode, size_t len);extern void *text_poke_smp (void *addr,const void *opcode,size_t len);extern void text_poke_smp_batch (struct text_poke_param *params,int n); -#if defined(CONFIG_DYNAMIC_FTRACE ) || defined(HAVE_JUMP_LABEL ) +#if defined(CONFIG_DYNAMIC_FTRACE ) || defined(CONFIG_JUMP_LABEL )#define IDEAL_NOP_SIZE_5 5extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5 ];extern void arch_init_ideal_nop5 (void );
arch/x86/include/asm/jump_label.h +15 -11
@@ -5,20 +5,24 @@#include <linux/types.h> #include <asm/nops.h> +#include <asm/asm.h> #define JUMP_LABEL_NOP_SIZE 5 -# define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" - -# define JUMP_LABEL (key, label) \ - do { \ - asm goto("1:" \ - JUMP_LABEL_INITIAL_NOP \ - ".pushsection __jump_table, \"aw\" \n\t"\ - _ASM_PTR "1b, %l[" #label "], %c0 \n\t" \ - ".popsection \n\t" \ - : : "i" (key) : : label); \ - } while (0) +#define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" + +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:" +JUMP_LABEL_INITIAL_NOP +".pushsection __jump_table, \"aw\" \n\t" + _ASM_PTR"1b, %l[l_yes], %c0 \n\t" +".popsection \n\t" + : :"i" (key) : : l_yes); +return false; +l_yes: +return true; +}#endif /* __KERNEL__ */
arch/x86/kernel/alternative.c +1 -1
@@ -674,7 +674,7 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n)__stop_machine (stop_machine_text_poke, (void *)&tpp,NULL ); } -#if defined(CONFIG_DYNAMIC_FTRACE ) || defined(HAVE_JUMP_LABEL ) +#if defined(CONFIG_DYNAMIC_FTRACE ) || defined(CONFIG_JUMP_LABEL )#ifdef CONFIG_X86_64 unsigned char ideal_nop5[5 ] = {0x66 ,0x66 ,0x66 ,0x66 ,0x90 };
arch/x86/kernel/jump_label.c +1 -1
@@ -4,13 +4,13 @@* Copyright (C) 2009 Jason Baron <[email protected]> * */ -#include <linux/jump_label.h> #include <linux/memory.h> #include <linux/uaccess.h> #include <linux/module.h> #include <linux/list.h> #include <linux/jhash.h> #include <linux/cpu.h> +#include <linux/jump_label.h> #include <asm/kprobes.h> #include <asm/alternative.h>
arch/x86/kernel/module.c +1 -0
@@ -24,6 +24,7 @@#include <linux/bug.h> #include <linux/mm.h> #include <linux/gfp.h> +#include <linux/jump_label.h> #include <asm/system.h> #include <asm/page.h>
include/asm-generic/vmlinux.lds.h +4 -10
@@ -170,6 +170,10 @@STRUCT_ALIGN (); \ *(__tracepoints) \/* implement dynamic printk debug */ \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___jump_table) = .; \ + *(__jump_table ) \ + VMLINUX_SYMBOL(__stop___jump_table) = .; \ . = ALIGN(8); \ VMLINUX_SYMBOL(__start___verbose) = .; \ *(__verbose) \
@@ -228,8 +232,6 @@ \ BUG_TABLE \ \ - JUMP_TABLE \ - \ /* PCI quirks */ \ .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \
@@ -583,14 +585,6 @@#define BUG_TABLE #endif -#define JUMP_TABLE \ - . = ALIGN(8); \ - __jump_table : AT(ADDR(__jump_table) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start___jump_table) = .; \ - *(__jump_table) \ - VMLINUX_SYMBOL(__stop___jump_table) = .; \ - } -#ifdef CONFIG_PM_TRACE #define TRACEDATA \ . = ALIGN(4); \
include/linux/dynamic_debug.h +0 -2
@@ -1,8 +1,6 @@#ifndef _DYNAMIC_DEBUG_H#define _DYNAMIC_DEBUG_H -#include <linux/jump_label.h> -/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They * use independent hash functions, to reduce the chance of false positives.
include/linux/jump_label.h +53 -33
125 lines not on this page · raw message
include/linux/jump_label_ref.h deleted +0 -44
44 lines not on this page · raw message
include/linux/perf_event.h +13 -13
@@ -505,7 +505,7 @@ struct perf_guest_info_callbacks {#include <linux/ftrace.h> #include <linux/cpu.h> #include <linux/irq_work.h> -#include <linux/jump_label_ref.h> +#include <linux/jump_label.h> #include <asm/atomic.h> #include <asm/local.h>
@@ -1036,7 +1036,7 @@ static inline int is_software_event(struct perf_event *event)return event->pmu->task_ctx_nr == perf_sw_context; } -extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX ]; +extern struct jump_label_key perf_swevent_enabled[PERF_COUNT_SW_MAX ];extern void __perf_sw_event (u32 ,u64 ,int ,struct pt_regs *,u64 );
@@ -1065,22 +1065,21 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr) {struct pt_regs hot_regs; -JUMP_LABEL (&perf_swevent_enabled[event_id], have_event); -return ; - -have_event: -if (!regs) { -perf_fetch_caller_regs (&hot_regs); - regs = &hot_regs; +if (static_branch (&perf_swevent_enabled[event_id])) { +if (!regs) { +perf_fetch_caller_regs (&hot_regs); + regs = &hot_regs; + } +__perf_sw_event (event_id, nr, nmi, regs, addr); } -__perf_sw_event (event_id, nr, nmi, regs, addr); } -extern atomic_t perf_sched_events; +extern struct jump_label_key perf_sched_events;static inline void perf_event_task_sched_in (struct task_struct *task) { -COND_STMT (&perf_sched_events,__perf_event_task_sched_in (task)); +if (static_branch (&perf_sched_events)) +__perf_event_task_sched_in (task); } static inline
@@ -1088,7 +1087,8 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex {perf_sw_event (PERF_COUNT_SW_CONTEXT_SWITCHES ,1 ,1 ,NULL ,0 ); -COND_STMT (&perf_sched_events,__perf_event_task_sched_out (task, next)); +if (static_branch (&perf_sched_events)) +__perf_event_task_sched_out (task, next); }extern void perf_event_mmap (struct vm_area_struct *vma);
include/linux/tracepoint.h +10 -12
@@ -29,7 +29,7 @@ struct tracepoint_func {struct tracepoint {const char *name;/* Tracepoint name */ -int state;/* State. */ +struct jump_label_key key;void (*regfunc)(void );void (*unregfunc)(void );struct tracepoint_func __rcu *funcs;
@@ -146,9 +146,7 @@ void tracepoint_update_probe_range(struct tracepoint * const *begin, extern struct tracepoint __tracepoint_##name; \ static inline void trace_##name(proto) \ { \ - JUMP_LABEL(&__tracepoint_##name.state, do_trace); \ - return; \ -do_trace: \ + if (static_branch(&__tracepoint_##name.key)) \ __DO_TRACE(&__tracepoint_##name, \ TP_PROTO(data_proto), \ TP_ARGS(data_args), \
@@ -176,14 +174,14 @@ do_trace: \* structures, so we create an array of pointers that will be used for iteration * on the tracepoints. */ -#define DEFINE_TRACE_FN (name, reg, unreg) \ - static const char __tpstrtab_##name[] \ - __attribute__((section("__tracepoints_strings"))) = #name; \ - struct tracepoint __tracepoint_##name \ - __attribute__((section("__tracepoints"))) = \ - { __tpstrtab_##name, 0, reg, unreg, NULL }; \ - static struct tracepoint * const __tracepoint_ptr_##name __used \ - __attribute__((section("__tracepoints_ptrs"))) = \ +#define DEFINE_TRACE_FN (name, reg, unreg) \ + static const char __tpstrtab_##name[] \ + __attribute__((section("__tracepoints_strings"))) = #name; \ + struct tracepoint __tracepoint_##name \ + __attribute__((section("__tracepoints"))) = \ + { __tpstrtab_##name, JUMP_LABEL_INIT, reg, unreg, NULL };\ + static struct tracepoint * const __tracepoint_ptr_##name __used \ + __attribute__((section("__tracepoints_ptrs"))) = \ &__tracepoint_##name;#define DEFINE_TRACE (name) \
kernel/jump_label.c +215 -322
670 lines not on this page · raw message
kernel/perf_event.c +2 -2
@@ -125,7 +125,7 @@ enum event_type_t {* perf_sched_events : >0 events exist * perf_cgroup_events: >0 per-cpu cgroup events exist on this cpu */ -atomic_t perf_sched_events__read_mostly ; +struct jump_label_key perf_sched_events__read_mostly ; static DEFINE_PER_CPU(atomic_t, perf_cgroup_events);static atomic_t nr_mmap_events__read_mostly ;
@@ -5406,7 +5406,7 @@ fail:return err; } -atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX ]; +struct jump_label_key perf_swevent_enabled[PERF_COUNT_SW_MAX ];static void sw_perf_event_destroy (struct perf_event *event) {
kernel/tracepoint.c +9 -14
@@ -251,9 +251,9 @@ static void set_tracepoint(struct tracepoint_entry **entry, {WARN_ON (strcmp ((*entry)->name, elem->name) !=0 ); -if (elem->regfunc && !elem->state && active) +if (elem->regfunc && !jump_label_enabled (&elem->key) && active) elem->regfunc (); -else if (elem->unregfunc && elem->state && !active) +else if (elem->unregfunc &&jump_label_enabled (&elem->key) && !active) elem->unregfunc ();/*
@@ -264,13 +264,10 @@ static void set_tracepoint(struct tracepoint_entry **entry,* is used. */ rcu_assign_pointer (elem->funcs, (*entry)->funcs); -if (!elem->state && active) { -jump_label_enable (&elem->state); - elem->state = active; - }else if (elem->state && !active) { -jump_label_disable (&elem->state); - elem->state = active; - } +if (active && !jump_label_enabled (&elem->key)) +jump_label_inc (&elem->key); +else if (!active &&jump_label_enabled (&elem->key)) +jump_label_dec (&elem->key); }/*
@@ -281,13 +278,11 @@ static void set_tracepoint(struct tracepoint_entry **entry,*/ static void disable_tracepoint (struct tracepoint *elem) { -if (elem->unregfunc && elem->state) +if (elem->unregfunc &&jump_label_enabled (&elem->key)) elem->unregfunc (); -if (elem->state) { -jump_label_disable (&elem->state); - elem->state =0 ; - } +if (jump_label_enabled (&elem->key)) +jump_label_dec (&elem->key);rcu_assign_pointer (elem->funcs,NULL ); }
Signature · 1 line
1.7.1
Steven Rostedt
maintainerRe: [PATCH 1/2] jump label: introduce static_branch() interface
Quoted 48 lines · Jason Baron
arch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +- arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/jump_label.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 2 - include/linux/jump_label.h | 86 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 537 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- 17 files changed, 352 insertions(+), 489 deletions(-) delete mode 100644 include/linux/jump_label_ref.harch/sparc/include/asm/jump_label.h +7
-11@@ -7,17 +7,20 @@#define JUMP_LABEL_NOP_SIZE 4 -#define JUMP_LABEL (key, label) \ - do { \ - asm goto("1:\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t"\ - ".align 4\n\t" \ - ".word 1b, %l[" #label "], %c0\n\t" \ - ".popsection \n\t" \ - : : "i" (key) : : label);\ - } while (0) +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\n\t" +"nop\n\t" +"nop\n\t" +".pushsection __jump_table, \"aw\"\n\t" + ".align 4\n\t"
arch/sparc/include/asm/jump_label.h line 26
Quoted 10 lines
arch/sparc/include/asm/jump_label.h +7
-0+ ".word 1b, %l[l_yes], %c0\n\t" + ".popsection \n\t" + : : "i" (key) : : l_yes); +return false; +l_yes: + return true; +}#endif /* __KERNEL__ */
Hi David,
Can I get your Acked-by for this patch.
Thanks,
-- Steve
Steven Rostedt
maintainerRe: [PATCH 1/2] jump label: introduce static_branch() interface
In reply to Jason BaronQuoted 60 lines · Jason Baron
arch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +- arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/jump_label.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 2 - include/linux/jump_label.h | 86 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 537 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- 17 files changed, 352 insertions(+), 489 deletions(-) delete mode 100644 include/linux/jump_label_ref.harch/mips/include/asm/jump_label.h +12
-10@@ -20,16 +20,18 @@#define WORD_INSN ".word"#endif -#define JUMP_LABEL (key, label) \ - do { \ - asm goto("1:\tnop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t" \ - WORD_INSN " 1b, %l[" #label "], %0\n\t" \ - ".popsection\n\t" \ - : : "i" (key) : : label); \ - } while (0) - +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\tnop\n\t" +"nop\n\t" +".pushsection __jump_table, \"aw\"\n\t" +WORD_INSN " 1b, %l[l_yes], %0\n\t" +".popsection\n\t" + : :"i" (key) : : l_yes); +return false; +l_yes: +return true; +}#endif /* __KERNEL__ */ arch/mips/kernel/jump_label.c +0
-0@@ -6,11 +6,11 @@* Copyright (c) 2010 Cavium Networks, Inc. */
arch/mips/kernel/jump_label.c line 16
Quoted 10 lines
arch/mips/kernel/jump_label.c +1
-1-#include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/memory.h> #include <linux/mutex.h> #include <linux/types.h> +#include <linux/jump_label.h> #include <linux/cpu.h> #include <asm/cacheflush.h>
Hi Ralf,
Can I get your Acked-by on this patch.
Thanks,
-- Steve
Ralf Baechle
Acked-byRe: [PATCH 1/2] jump label: introduce static_branch() interface
Quoted 71 lines · Steven Rostedt
Quoted 69 lines · Jason Baron
arch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +- arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/jump_label.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 2 - include/linux/jump_label.h | 86 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 537 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- 17 files changed, 352 insertions(+), 489 deletions(-) delete mode 100644 include/linux/jump_label_ref.harch/mips/include/asm/jump_label.h +12
-10@@ -20,16 +20,18 @@#define WORD_INSN ".word"#endif -#define JUMP_LABEL (key, label) \ - do { \ - asm goto("1:\tnop\n\t" \ - "nop\n\t" \ - ".pushsection __jump_table, \"a\"\n\t" \ - WORD_INSN " 1b, %l[" #label "], %0\n\t" \ - ".popsection\n\t" \ - : : "i" (key) : : label); \ - } while (0) - +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\tnop\n\t" +"nop\n\t" +".pushsection __jump_table, \"aw\"\n\t" +WORD_INSN " 1b, %l[l_yes], %0\n\t" +".popsection\n\t" + : :"i" (key) : : l_yes); +return false; +l_yes: +return true; +}#endif /* __KERNEL__ */ arch/mips/kernel/jump_label.c +1
-1@@ -6,11 +6,11 @@* Copyright (c) 2010 Cavium Networks, Inc. */ -#include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/memory.h> #include <linux/mutex.h> #include <linux/types.h> +#include <linux/jump_label.h> #include <linux/cpu.h>
Quoted 5 lines
arch/mips/kernel/jump_label.c line 16
Quoted 1 line
arch/mips/kernel/jump_label.c +0
-0#include <asm/cacheflush.h> Hi Ralf,
Can I get your Acked-by on this patch.
You could have gotten it quicker if I had been on cc ...
I'm happy with the change to arch/mips/include/asm/jump_label.h and assuming that the change to arch/mips/kernel/jump_label.c will be dropped
Ralf
Steven Rostedt
maintainerRe: [PATCH 1/2] jump label: introduce static_branch() interface
Quoted 2 lines · Ralf Baechle
I'm happy with the change to
arch/mips/include/asm/jump_label.hand assuming that the change toarch/mips/kernel/jump_label.cwill be dropped
Noted.
Quoted 2 lines
Acked-by Ralf Baechle <[email protected]>
Jason,
Could you respin the patchset and send it out again with the comments that were made. And please Cc Ralf on any patch that touches the mips arch.
Thanks,
-- Steve
Steven Rostedt
maintainerRe: [PATCH 1/2] jump label: introduce static_branch() interface
In reply to Jason Baronarch/x86/kernel/module.c
Quoted 20 lines · Jason Baron
arch/x86/kernel/jump_label.c +1
-1@@ -4,13 +4,13 @@* Copyright (C) 2009 Jason Baron <[email protected]> * */ -#include <linux/jump_label.h> #include <linux/memory.h> #include <linux/uaccess.h> #include <linux/module.h> #include <linux/list.h> #include <linux/jhash.h> #include <linux/cpu.h> +#include <linux/jump_label.h> #include <asm/kprobes.h> #include <asm/alternative.h> arch/x86/kernel/module.c +0
-0
Jason,
I'm curious, is there a reason for this header change? Clean up? Maybe it could go into a separate patch. If anything, just to make this one slightly smaller.
-- Steve
Re: [PATCH 1/2] jump label: introduce static_branch() interface
Quoted 21 lines · Steven Rostedt
Quoted 19 lines · Jason Baron
arch/x86/kernel/jump_label.c +1
-1@@ -4,13 +4,13 @@* Copyright (C) 2009 Jason Baron <[email protected]> * */ -#include <linux/jump_label.h> #include <linux/memory.h> #include <linux/uaccess.h> #include <linux/module.h> #include <linux/list.h> #include <linux/jhash.h> #include <linux/cpu.h> +#include <linux/jump_label.h> #include <asm/kprobes.h> #include <asm/alternative.h>
Quoted 8 lines
arch/x86/kernel/module.c
Quoted 1 line
arch/x86/kernel/module.c +0
-0Jason,
I'm curious, is there a reason for this header change? Clean up? Maybe it could go into a separate patch. If anything, just to make this one slightly smaller.
hmm...I did that to get types.h for the new atomic_t usage.
However, now that I look at it again its bogus. The right fix is to explicitly include <linux/types.h> from jump_label.h.
-Jason
Re: [PATCH 1/2] jump label: introduce static_branch() interface
Quoted 9 lines · Jason Baron
Quoted 4 lines
I'm curious, is there a reason for this header change? Clean up? Maybe it could go into a separate patch. If anything, just to make this one slightly smaller.
hmm...I did that to get
types.hfor the newatomic_tusage.However, now that I look at it again its bogus. The right fix is to explicitly include <
linux/types.h> fromjump_label.h.
And <linux/compiler.h> for unlikely().
Ralf
PATCH 2/2 dynamic debug: add jump label support
In reply to Jason BaronSince jump labels make use of atomic_read(), and dynamic_debug.h gets included by kernel.h, the inclusion of atomic.h in dynamic_debug.h (to get atomic_read()), would cause a circular dependency since atomic.h requires kernel.h. Thus, for dynamic debug I am explicitly including jump_label.h when jump labels are configured, and making use of a regular reads (non-atomic), when jump labels are disabled.
--- include/linux/dynamic_debug.h | 46 ++++++++++++++++++++++++++++++++++------ lib/dynamic_debug.c | 4 +- 2 files changed, 41 insertions(+), 9 deletions(-)
include/linux/dynamic_debug.h +39 -7
@@ -1,6 +1,26 @@#ifndef _DYNAMIC_DEBUG_H#define _DYNAMIC_DEBUG_H +/* +* When jump labels are disabled, they make use of atomic_read(). Since +* dynamic_debug.h gets included by kernel.h, the inclusion of jump_label.h by +* dynamic_debug.h and thus atomic.h (to get atomic_read()), would cause a +* circular dependency since atomic.h requires kernel.h. Thus, for dynamic debug +* we are explicitly including jump_label.h when jump labels are configured, and +* making use of a regular reads (non-atomic), when jump labels are disabled. +*/ +#if defined(CC_HAVE_ASM_GOTO ) && defined(CONFIG_JUMP_LABEL ) +#include <linux/jump_label.h> +#endif + +#ifdef HAVE_JUMP_LABEL +#define dd_enable (dp) do { jump_label_inc(&dp->enabled); } while (0) +#define dd_disable (dp) do { jump_label_dec(&dp->enabled); } while (0) +#else +#define dd_enable (dp) do { dp->enabled = 1; } while (0) +#define dd_disable (dp) do { dp->enabled = 0; } while (0) +#endif +/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They * use independent hash functions, to reduce the chance of false positives.
@@ -31,7 +51,11 @@ struct _ddebug {#define _DPRINTK_FLAGS_PRINT (1<<0)/* printk() a message using the format */ #define _DPRINTK_FLAGS_DEFAULT 0 unsigned int flags:8; -char enabled; +#ifdef HAVE_JUMP_LABEL +struct jump_label_key enabled; +#else +int enabled; +#endif } __attribute__((aligned(8)));
@@ -41,14 +65,22 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,#if defined(CONFIG_DYNAMIC_DEBUG )extern int ddebug_remove_module (const char *mod_name); +#ifdef HAVE_JUMP_LABEL +# define DDEBUG_INIT JUMP_LABEL_INIT +# define DDEBUG_BRANCH (enabled) static_branch(&enabled) +#else +# define DDEBUG_INIT 0 +# define DDEBUG_BRANCH (enabled) unlikely(enabled) +#endif +#define dynamic_pr_debug (fmt, ...) do { \ static struct _ddebug descriptor \ __used \ __attribute__((section("__verbose"), aligned(8))) = \ { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ - _DPRINTK_FLAGS_DEFAULT }; \ - if (unlikely(descriptor.enabled)) \ - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ + _DPRINTK_FLAGS_DEFAULT, DDEBUG_INIT }; \ + if (DDEBUG_BRANCH(descriptor.enabled)) \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ } while (0)
@@ -57,9 +89,9 @@ extern int ddebug_remove_module(const char *mod_name);__used \ __attribute__((section("__verbose"), aligned(8))) = \ {KBUILD_MODNAME , __func__, __FILE__, fmt, __LINE__, \ - _DPRINTK_FLAGS_DEFAULT }; \ -if (unlikely (descriptor.enabled)) \ - dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ + _DPRINTK_FLAGS_DEFAULT,DDEBUG_INIT }; \ +if (DDEBUG_BRANCH (descriptor.enabled)) \ + dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ } while (0) #else
lib/dynamic_debug.c +2 -2
@@ -142,9 +142,9 @@ static void ddebug_change(const struct ddebug_query *query, dt->num_enabled++; dp->flags = newflags;if (newflags) - dp->enabled =1 ; +dd_enable (dp);else - dp->enabled =0 ; +dd_disable (dp);if (verbose) printk(KERN_INFO "ddebug: changed %s:%d [%s]%s %s\n",
Signature · 1 line
1.7.1
Steven Rostedt
maintainerQuoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 9 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
Quoted 9 lines
I've got a prototype patch to address this issue but its somewhat
invasive, and thus I'd like to leave it as a follow-up item. I have to date, not seen this issue in practice.thanks,
-Jason
Quoted 6 lines
Jason Baron (2):
jump label: introducestatic_branch()interface
dynamic debug: add jump label supportarch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +-
Could we get Ralf's acked-by for the mips code.
Quoted 1 line
arch/sparc/include/asm/jump_label.h | 25 +-
Could we get David Miller's Acked-by for sparc.
Thanks,
-- Steve
Quoted 17 lines
arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 26 +- arch/x86/kernel/alternative.c | 2 +- arch/x86/kernel/jump_label.c | 2 +- arch/x86/kernel/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 44 +++- include/linux/jump_label.h | 86 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 537 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- lib/dynamic_debug.c | 4 +- 18 files changed, 391 insertions(+), 496 deletions(-) delete mode 100644 include/linux/jump_label_ref.h
Quoted 15 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 5 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
Quoted 9 lines
Quoted 4 lines
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
Hi Steven,
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ? Also, could you point out what would refrain the linker from aligning the start of object sections on the next 32-bytes (thus power of two) address multiple ?
I think we need to be a bit more strict in our interpretation of what guarantee gcc/ld provide and don't provide with respect to section and structure alignment.
As it stands now, the section alignment of jump labels looks half-broken on most architectures, and this *is* a big deal. I would really like to see a patch for this (it can be a separate patch) going in for .39.
Thank you,
Mathieu
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
Quoted 14 lines · Steven Rostedt
Quoted 3 lines
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 5 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
Quoted 9 lines
Quoted 4 lines
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
yes:
<address to patch>
<address to jump to (when enabled)>
<key value (which is a pointer address)>
Quoted 18 lines
Quoted 9 lines
I've got a prototype patch to address this issue but its somewhat
invasive, and thus I'd like to leave it as a follow-up item. I have to date, not seen this issue in practice.thanks,
-Jason
Quoted 6 lines
Jason Baron (2):
jump label: introducestatic_branch()interface
dynamic debug: add jump label supportarch/mips/include/asm/jump_label.h | 22 +- arch/mips/kernel/jump_label.c | 2 +-Could we get Ralf's acked-by for the mips code.
Quoted 8 lines
Quoted 1 line
arch/sparc/include/asm/jump_label.h | 25 +-Could we get David Miller's Acked-by for sparc.
Thanks,
-- Steve
Ok, I'll ping them.
thanks,
-Jason
A message that is not in the archive (sent off-list or not yet received): [email protected]
Steven Rostedt
maintainerQuoted 26 lines · Mathieu Desnoyers
Quoted 15 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 5 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
Quoted 9 lines
Quoted 4 lines
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
Quoted 7 lines
Hi Steven,
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ? Also, could you point out what would refrain the linker from aligning the start of object sections on the next 32-bytes (thus power of two) address multiple ?
Maybe it would be just easier to add another long ;)
Seriously, it would. Then it would be 32 bytes on 64bit and 16 bytes on 32bit. Then I guess we can have our guarantee without doing a large change to have this indirect pointer and still waste sizeof(long) bytes in having it.
Just insert a long "Reserved" word.
-- Steve
Quoted 13 lines
I think we need to be a bit more strict in our interpretation of what guarantee gcc/ld provide and don't provide with respect to section and structure alignment.
As it stands now, the section alignment of jump labels looks half-broken on most architectures, and this *is* a big deal. I would really like to see a patch for this (it can be a separate patch) going in for .39.
Thank you,
Mathieu
Quoted 27 lines · Steven Rostedt
Quoted 26 lines · Mathieu Desnoyers
Quoted 24 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 9 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
Quoted 4 lines
Quoted 4 lines
Hi Steven,
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ?
I can:
http://www.x86-64.org/documentation/abi.pdf Section 3.1.2:
Aggregates and Unions
Structures and unions assume the alignment of their most strictly aligned component. Each member is assigned to the lowest available offset with the appropriate alignment. The size of any object is always a multiple of the object‘s alignment.
An array uses the same alignment as its elements, except that a local or global array variable of length at least 16 bytes or a C99 variable-length array variable always has alignment of at least 16 bytes.
Structure and union objects can require padding to meet size and alignment constraints. The contents of any padding is undefined.
I don't think it is explicitly stated, but it is also true that the size is the smallest value that meets the above constraints.
Quoted 5 lines
Quoted 4 lines
Also, could
you point out what would refrain the linker from aligning the start of object sections on the next 32-bytes (thus power of two) address multiple ?
The rules of the ABI are quite specific. It would be a toolchain bug if this were messed up.
Quoted 1 line
Maybe it would be just easier to add another long ;)
Maybe we should audit all the data structures in the entire kernel and add manual padding to power of 2 boundaries.
Quoted 8 lines
Seriously, it would. Then it would be 32 bytes on 64bit and 16 bytes on 32bit. Then I guess we can have our guarantee without doing a large change to have this indirect pointer and still waste sizeof(long) bytes in having it.
Just insert a long "Reserved" word.
I disagree. Wasting memory to work around non-existent hypothetical bugs seems wrong to me.
David Daney
Steven Rostedt
maintainerQuoted 10 lines · David Daney
Quoted 2 lines · Steven Rostedt
Quoted 2 lines
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ?
I can:
http://www.x86-64.org/documentation/abi.pdf Section 3.1.2:
Aggregates and Unions
Note, we are not dealing with C or arrays, but with inline assembly, and the linker.
+static __always_inline bool arch_static_branch(struct jump_label_key *key) +{
+ asm goto("1:\tnop\n\t"
+ "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + WORD_INSN " 1b, %l[l_yes], %0\n\t" + ".popsection\n\t" + : : "i" (key) : : l_yes);
+ return false;
+l_yes:
+ return true;
+}
That push/pop section part creates the structure we are talking about. It's made up of three pointers. The address of the nop, the address of the label l_yes and the address of the key.
Now its up to the linker to decide where to place that element. Can we guarantee that it will always be on an 8 byte boundery? Hmm, I wonder if we could add a .ALIGN sizeof(long) before that?
Now if we have two object files where there's a list of these jump labels, and then when the linker concatenates them we have something like:
.long f1-a, .long f1-b, .long f1-c
[ the above is 24 bytes ] so
.long [ pad 8 bytes]
.long f2-a, .long f2-b, .long f2-c ...
Where f1 is object file 1 and f2 is object file 2. File 1 has a jump label table that holds a total of 24 bytes, and when the linker added the next jump label it padded it with 8 bytes into that section. The question remains, is that OK for the linker to do that, even though we specified in vmlinux.ld:
/* implement dynamic printk debug */ \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___jump_table) = .; \ + *(__jump_table) \ + VMLINUX_SYMBOL(__stop___jump_table) = .; \
But then again, maybe it will break on 32 bit, where the above file 1 would have a total of 12 bytes, it may pad it with 4 bytes to keep that 8 byte alignment.
Quoted 10 lines
Structures and unions assume the alignment of their most strictly aligned component. Each member is assigned to the lowest available offset with the appropriate alignment. The size of any object is always a multiple of the object‘s alignment.
An array uses the same alignment as its elements, except that a local or global array variable of length at least 16 bytes or a C99 variable-length array variable always has alignment of at least 16 bytes.
Quoted 5 lines
Structure and union objects can require padding to meet size and alignment constraints. The contents of any padding is undefined.
I don't think it is explicitly stated, but it is also true that the size is the smallest value that meets the above constraints.
Could be true, but gcc has no idea that this data is an array. It's really up to the linker.
Quoted 13 lines
Quoted 7 lines
Quoted 6 lines
Also, could
you point out what would refrain the linker from aligning the start of object sections on the next 32-bytes (thus power of two) address multiple ?The rules of the ABI are quite specific. It would be a toolchain bug if this were messed up.
Quoted 4 lines
Quoted 1 line
Maybe it would be just easier to add another long ;)
Maybe we should audit all the data structures in the entire kernel and add manual padding to power of 2 boundaries.
We are not worried about normal C data structures, we are worried about data structures that are created by inline assembly and the linker. As we did have a bug with the trace_events code. But that dealt with a structure that was not strictly naturally word aligned. It had "int" as well as pointers.
Quoted 7 lines
Quoted 7 lines
Seriously, it would. Then it would be 32 bytes on 64bit and 16 bytes on 32bit. Then I guess we can have our guarantee without doing a large change to have this indirect pointer and still waste sizeof(long) bytes in having it.
Quoted 5 lines
Quoted 2 lines
Just insert a long "Reserved" word.
I disagree. Wasting memory to work around non-existent hypothetical bugs seems wrong to me.
The linker may never cause the issue. I haven't seen any problems with things that were naturally word aligned. But then, all the places that we do this has been naturally word aligned as well as a power of 2 (extables for example).
Thus, if we do "waste" space, I rather just add the 'Reserved' word and which makes it a power of 2 and be done with it.
-- Steve
Quoted 29 lines · Steven Rostedt
Quoted 10 lines · David Daney
Quoted 2 lines · Steven Rostedt
Quoted 2 lines
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ?
I can:
http://www.x86-64.org/documentation/abi.pdf Section 3.1.2:
Aggregates and Unions
Note, we are not dealing with C or arrays, but with inline assembly, and the linker.
(quoted diff) +12
-0+static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\tnop\n\t" + "nop\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + WORD_INSN " 1b, %l[l_yes], %0\n\t" + ".popsection\n\t" + : : "i" (key) : : l_yes); + return false; +l_yes: + return true; +}
Quoted 8 lines
That push/pop section part creates the structure we are talking about. It's made up of three pointers. The address of the nop, the address of the label
l_yesand the address of the key.Now its up to the linker to decide where to place that element. Can we guarantee that it will always be on an 8 byte boundery? Hmm, I wonder if we could add a .ALIGN sizeof(long) before that?
we can. Sparc does it, see: arch/sparc/include/asm/jump_label.h.
So I guess it would be .align 8 for 64-bit and .align 4 for 32-bit...
-Jason
Steven Rostedt
maintainerQuoted 9 lines · Jason Baron
On Thu, Mar 10, 2011 at 01:04:01PM -0500, Steven Rostedt wrote:
Now its up to the linker to decide where to place that element. Can weQuoted 3 lines
guarantee that it will always be on an 8 byte boundery? Hmm, I wonder if we could add a .ALIGN sizeof(long) before that?
we can. Sparc does it, see:
arch/sparc/include/asm/jump_label.h.So I guess it would be .align 8 for 64-bit and .align 4 for 32-bit...
Now what about the vmlinux.ld? That has a align 8. Is that a one time short (align to 8 bytes here), or will it carry through aligning the rest of the section. If not, perhaps we may be OK.
-- Steve
Quoted 7 lines · Steven Rostedt
Quoted 6 lines · Jason Baron
On Thu, Mar 10, 2011 at 01:04:01PM -0500, Steven Rostedt wrote:
Now its up to the linker to decide where to place that element. Can weQuoted 3 lines
guarantee that it will always be on an 8 byte boundery? Hmm, I wonder if we could add a .ALIGN sizeof(long) before that?
Quoted 8 lines
Quoted 3 lines
we can. Sparc does it, see:
arch/sparc/include/asm/jump_label.h.So I guess it would be .align 8 for 64-bit and .align 4 for 32-bit...
Now what about the vmlinux.ld? That has a align 8. Is that a one time short (align to 8 bytes here), or will it carry through aligning the rest of the section. If not, perhaps we may be OK.
That is the alignment of the start of the section in the *output* object. The linker will respect the requested alignment of the various __jump_table sections in the *input* objects. So adding an .align 8 before emitting data into the __jump_table section would not hurt (It could even help.)
I empirically determined that if no .align is specified, the requested alignment defaults to 4 for x86_64.
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
David Daney
Steven Rostedt
maintainerQuoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the trace_events was solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.
It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
-- Steve
Quoted 6 lines · Steven Rostedt
Quoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
Quoted 9 lines
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the
trace_eventswas solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
If the linker put in gratuitous holes, things like __ex_table would break too.
David Daney
Steven Rostedt
maintainerQuoted 12 lines · David Daney
Quoted 11 lines · Steven Rostedt
Quoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the
trace_eventswas solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.
Quoted 7 lines
Quoted 4 lines
It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
If the linker put in gratuitous holes, things like
__ex_tablewould break too.
Again, as I have said (although I said extable not __ex_table), there seems to be no problem when the data is of a power of 2 as well. As __ex_table size is a power of 2. We just don't know if the linker will add holes when the size is something other than power of 2.
-- Steve
Steven Rostedt
maintainerQuoted 18 lines · Steven Rostedt
Quoted 17 lines · David Daney
Quoted 15 lines · Steven Rostedt
Quoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the
trace_eventswas solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
Quoted 7 lines
Quoted 2 lines
If the linker put in gratuitous holes, things like
__ex_tablewould break too.Again, as I have said (although I said extable not
__ex_table), there seems to be no problem when the data is of a power of 2 as well. As__ex_tablesize is a power of 2. We just don't know if the linker will add holes when the size is something other than power of 2.
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
-- Steve
Quoted 22 lines · Steven Rostedt
Quoted 21 lines · Steven Rostedt
Quoted 19 lines · David Daney
Quoted 6 lines · Steven Rostedt
Quoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
Quoted 9 lines
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the
trace_eventswas solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
If the linker put in gratuitous holes, things like
__ex_tablewould break too.
Quoted 9 lines
Quoted 4 lines
Again, as I have said (although I said extable not
__ex_table), there seems to be no problem when the data is of a power of 2 as well. As__ex_tablesize is a power of 2. We just don't know if the linker will add holes when the size is something other than power of 2.Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
agreed. something like the following is all that's needed for x86. Sparc already has this, so mips just needs something similar. Steve, should I re-post the entire series. Or can I just post this patch separately?
thanks,
-Jason
arch/x86/include/asm/jump_label.h +4 -2
@@ -8,6 +8,7 @@#include <asm/asm.h> #define JUMP_LABEL_NOP_SIZE 5 +#define BYTES_PER_LONG (BITS_PER_LONG / 8)#define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t"
@@ -16,9 +17,10 @@ static __always_inline bool arch_static_branch(struct jump_label_key *key) asm goto("1:" JUMP_LABEL_INITIAL_NOP ".pushsection __jump_table, \"aw\" \n\t" - _ASM_PTR"1b, %l[l_yes], %c0 \n\t" +".align %c0\n\t" + _ASM_PTR"1b, %l[l_yes], %c1 \n\t" ".popsection \n\t" - : :"i" (key) : : l_yes); + : : "i" BYTES_PER_LONG, "i" (key) : : l_yes);return false; l_yes:return true;
Steven Rostedt
maintainerQuoted 3 lines · Jason Baron
agreed. something like the following is all that's needed for x86. Sparc already has this, so mips just needs something similar. Steve, should I re-post the entire series. Or can I just post this patch separately?
Nah, I could take this as a PATCH 3/2. Just reply with your SoB.
I still want to analyze the rest of the patch set. I've been doing busy work for now. I'll do that this afternoon.
Thanks,
-- Steve
Quoted 26 lines
arch/x86/include/asm/jump_label.h +4
-2@@ -8,6 +8,7 @@#include <asm/asm.h> #define JUMP_LABEL_NOP_SIZE 5 +#define BYTES_PER_LONG (BITS_PER_LONG / 8)#define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t"@@ -16,9 +17,10 @@ static __always_inline bool arch_static_branch(struct jump_label_key *key) asm goto("1:" JUMP_LABEL_INITIAL_NOP ".pushsection __jump_table, \"aw\" \n\t" - _ASM_PTR"1b, %l[l_yes], %c0 \n\t" +".align %c0\n\t" + _ASM_PTR"1b, %l[l_yes], %c1 \n\t" ".popsection \n\t" - : :"i" (key) : : l_yes); + : : "i" BYTES_PER_LONG, "i" (key) : : l_yes);return false; l_yes:return true;
Quoted 22 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 21 lines · Steven Rostedt
Quoted 19 lines · David Daney
Quoted 6 lines · Steven Rostedt
Quoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
Quoted 9 lines
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the
trace_eventswas solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
If the linker put in gratuitous holes, things like
__ex_tablewould break too.
Quoted 8 lines
Quoted 4 lines
Again, as I have said (although I said extable not
__ex_table), there seems to be no problem when the data is of a power of 2 as well. As__ex_tablesize is a power of 2. We just don't know if the linker will add holes when the size is something other than power of 2.Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
- Add a padding element at the end
or
- use .align 4*sizeof(long) at the beginning
to make sure the linker won't put any holes when it puts objects together ?
Thanks,
Mathieu
Quoted 4 lines
-- Steve
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
Steven Rostedt
maintainerQuoted 6 lines · Mathieu Desnoyers
Quoted 3 lines
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
But we don't have structures. We have data that has been allocated in assembly. Come to think of it, it may be best to keep these as ".align 4".
Quoted 8 lines
- Add a padding element at the end
or
- use .align 4*sizeof(long) at the beginningto make sure the linker won't put any holes when it puts objects together ?
The linker should be dumb and not trying to "optimize", because it has no idea what the content is. If anything, it should try to compact things as best as possible, with the exception of keeping things naturally word aligned. If you added even ".align(4)" on a 64bit system, the linker should be trying to keep everything packed.
If I get time, I could look at the linker code to see exactly what it does, but adding holes into sections that are naturally word align seems more like a bug in the linker than a problem that we need to deal with.
The only issue I could fathom, is if gcc added its own padding in a section. That is, when it created the __jump_table section with one element, it added another 4/8 bytes to make the section size a power of two. Maybe that is a true issue, maybe not. It would seems stupid to do so IMHO, because when you get to bigger numbers, the aligning a power of 2 can get much bigger. But perhaps it does it for small power of 2s?
-- Steve
Quoted 33 lines · Steven Rostedt
Quoted 6 lines · Mathieu Desnoyers
Quoted 3 lines
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
But we don't have structures. We have data that has been allocated in assembly. Come to think of it, it may be best to keep these as ".align 4".
Quoted 8 lines
- Add a padding element at the end
or
- use .align 4*sizeof(long) at the beginningto make sure the linker won't put any holes when it puts objects together ?
The linker should be dumb and not trying to "optimize", because it has no idea what the content is. If anything, it should try to compact things as best as possible, with the exception of keeping things naturally word aligned. If you added even ".align(4)" on a 64bit system, the linker should be trying to keep everything packed.
If I get time, I could look at the linker code to see exactly what it does, but adding holes into sections that are naturally word align seems more like a bug in the linker than a problem that we need to deal with.
Quoted 7 lines
The only issue I could fathom, is if gcc added its own padding in a section. That is, when it created the
__jump_tablesection with one element, it added another 4/8 bytes to make the section size a power of two. Maybe that is a true issue, maybe not. It would seems stupid to do so IMHO, because when you get to bigger numbers, the aligning a power of 2 can get much bigger. But perhaps it does it for small power of 2s?
GCC on x86_64 likes to align its data with .align 16:
-------------------------------
$ cat jl.c
struct foo {
long a;
long b;
long c;
};
struct foo bar = {1,2,3};
$ gcc -O3 -S jl.c $ cat jl.s .file "jl.c" .globl bar .data .align 16 .type bar, @object .size bar, 24 bar: .quad 1 .quad 2 .quad 3 .ident "GCC: (GNU) 4.4.4 20100630 (Red Hat 4.4.4-10)" .section .note.GNU-stack,"",@progbits ----------------------------------
But that shouldn't matter because we only emit data to the __jump_table section from asm().
GCC is getting a reference to that table (array of structures really) from a global variable, I don't see how it can violate the ABI in this case.
David Daney
Steven Rostedt
maintainerQuoted 5 lines · David Daney
But that shouldn't matter because we only emit data to the
__jump_tablesection fromasm().GCC is getting a reference to that table (array of structures really) from a global variable, I don't see how it can violate the ABI in this case.
Right, actually gcc should be completely out of the loop, as it has no idea about that section we created. That's done in the assembly phase, and the linker should not be adding holes.
-- Steve
Quoted 6 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 4 lines · Mathieu Desnoyers
Quoted 3 lines
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
Quoted 6 lines
Quoted 2 lines
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
But we don't have structures. We have data that has been allocated in assembly. Come to think of it, it may be best to keep these as ".align 4".
The .align 4 is certainly not the right answer, because it will trigger unaligned accesses on some 64-bit architectures, as we have faced with trace event.
Mathieu
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
Steven Rostedt
maintainerQuoted 10 lines · Mathieu Desnoyers
Quoted 9 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 6 lines · Mathieu Desnoyers
Quoted 3 lines
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
Quoted 7 lines
Quoted 3 lines
But we don't have structures. We have data that has been allocated in assembly. Come to think of it, it may be best to keep these as ".align 4".
The .align 4 is certainly not the right answer, because it will trigger unaligned accesses on some 64-bit architectures, as we have faced with trace event.
Will it? Seems that sparc does this regardless.
Remember, this is 3 natural word sized objects, and vmlinux.ld starts the section off with .ALIGN 8, hence, the section is already 8 byte aligned, all objects within this section are 8 bytes (for 64bit archs, and 4 bytes for 32bit), why would saying ".align 4" cause the linker to add holes to make it 4 byte aligned when it is already 8 byte aligned. The ".align 4" should work with both 32bit and 64bit archs.
-- Steve
Quoted 19 lines · Steven Rostedt
Quoted 10 lines · Mathieu Desnoyers
Quoted 9 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 6 lines · Mathieu Desnoyers
Quoted 3 lines
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be done with it.
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
Quoted 7 lines
Quoted 3 lines
But we don't have structures. We have data that has been allocated in assembly. Come to think of it, it may be best to keep these as ".align 4".
The .align 4 is certainly not the right answer, because it will trigger unaligned accesses on some 64-bit architectures, as we have faced with trace event.
Quoted 9 lines
Will it? Seems that sparc does this regardless.
Remember, this is 3 natural word sized objects, and vmlinux.ld starts the section off with .ALIGN 8, hence, the section is already 8 byte aligned, all objects within this section are 8 bytes (for 64bit archs, and 4 bytes for 32bit), why would saying ".align 4" cause the linker to add holes to make it 4 byte aligned when it is already 8 byte aligned. The ".align 4" should work with both 32bit and 64bit archs.
It should work, but it hurts my eyes to see the source code forcing a 64-bit word to 32-bit alignment.
David Daney
Quoted 31 lines · David Daney
Quoted 20 lines · Steven Rostedt
Quoted 11 lines · Mathieu Desnoyers
Quoted 10 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 7 lines · Mathieu Desnoyers
Quoted 4 lines
Anyway, I think the best thing for now is to have Jason add the .align(sizeof(long)) in the inline assembly for all locations and be
done with it.You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
Quoted 7 lines
Quoted 3 lines
But we don't have structures. We have data that has been allocated in assembly. Come to think of it, it may be best to keep these as ".align 4".
The .align 4 is certainly not the right answer, because it will trigger unaligned accesses on some 64-bit architectures, as we have faced with trace event.
Quoted 9 lines
Will it? Seems that sparc does this regardless.
Remember, this is 3 natural word sized objects, and vmlinux.ld starts the section off with .ALIGN 8, hence, the section is already 8 byte aligned, all objects within this section are 8 bytes (for 64bit archs, and 4 bytes for 32bit), why would saying ".align 4" cause the linker to add holes to make it 4 byte aligned when it is already 8 byte aligned. The ".align 4" should work with both 32bit and 64bit archs.
Quoted 2 lines
It should work, but it hurts my eyes to see the source code forcing a 64-bit word to 32-bit alignment.
We solved such stuff with macros in other places already.
#ifdef 64bit
# define BLA 8 #else # define BLA 4 #endif
and then use
.aling BLA
Where is the problem?
Thanks,
tglx
Steven Rostedt
maintainerQuoted 11 lines · Thomas Gleixner
Quoted 2 lines
It should work, but it hurts my eyes to see the source code forcing a 64-bit word to 32-bit alignment.
We solved such stuff with macros in other places already.
#ifdef 64bit
# define BLA 8 #else # define BLA 4 #endif
Quoted 5 lines
and then use
.aling BLA
Where is the problem?
That's basically the solution that Jason came up with, and what I expected. What caught my eye was that David Miller had .align 4 for this on sparc which is the one arch that is truly picky about such things. As I understood more about this, I see that would work for both archs.
That doesn't mean I'm against the .align BLA solution.
-- Steve
Quoted 15 lines · Steven Rostedt
Quoted 13 lines · Thomas Gleixner
Quoted 2 lines
It should work, but it hurts my eyes to see the source code forcing a 64-bit word to 32-bit alignment.
We solved such stuff with macros in other places already.
#ifdef 64bit
# define BLA 8 #else # define BLA 4 #endifand then use
Quoted 8 lines
Quoted 3 lines
.aling BLA
Where is the problem?
That's basically the solution that Jason came up with, and what I expected. What caught my eye was that David Miller had .align 4 for this on sparc which is the one arch that is truly picky about such things. As I understood more about this, I see that would work for both archs.
I doubt that sparc will barf when we make this 64/32bit aware. If it does, we have some bigger fish to fry.
Quoted 1 line
That doesn't mean I'm against the .align BLA solution.
As hpa pointed out in some unreadable mail, we have _ASM_ALIGN on x86 already exactly for this purpose.
Thanks,
tglx
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 9 lines · Mathieu Desnoyers
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
- Add a padding element at the end
or
- use .align 4*sizeof(long) at the beginningto make sure the linker won't put any holes when it puts objects together ?
It may only be a technicality but but careful with .align. On some architectures .align x will align to a multiple of x; on other architectures to 2^x. Another reason to stick to C wherever possible.
Ralf
Quoted 9 lines · Ralf Baechle
Quoted 7 lines · Mathieu Desnoyers
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
- Add a padding element at the end
or
- use .align 4*sizeof(long) at the beginning
Quoted 6 lines
Quoted 2 lines
to make sure the linker won't put any holes when it puts objects together ?
It may only be a technicality but but careful with .align. On some architectures .align x will align to a multiple of x; on other architectures to 2^x. Another reason to stick to C wherever possible.
.balign is saner:
http://sourceware.org/binutils/docs-2.21/as/Balign.html
cheers
Quoted 9 lines · * Ralf Baechle ([email protected]) wrote:
Quoted 7 lines · Mathieu Desnoyers
You seem to be contradicting yourself here. I'm concerned about having "structures" of a size not power of two. Can we simply either
- Add a padding element at the end
or
- use .align 4*sizeof(long) at the beginning
Quoted 6 lines
Quoted 2 lines
to make sure the linker won't put any holes when it puts objects together ?
It may only be a technicality but but careful with .align. On some architectures .align x will align to a multiple of x; on other architectures to 2^x. Another reason to stick to C wherever possible.
Thanks for the reminder! Not sure if using C is practical in the case of jump labels though. As Michael pointed out, using .balign might be better here.
Mathieu
Quoted 2 lines
Ralf
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
Quoted 6 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 3 lines · David Daney
The alignment requested by the assembler will have to satisfy *all* the requested alignments, so manually forcing everything to .align 8 (or .align 4 for 32-bit) should ensure that the linker doesn't put in any holes.
Quoted 8 lines
I would agree with the assessment although, I don't know that it is documented anywhere that this is what happens. As the previous "bug" with the
trace_eventswas solved by me adding .align(4) everywhere, I would think that .align(sizeof(long)) would work here too.It may be a good ideal to force this alignment, and not add wasted space. If anything, if this (hypothetical) bug appears, it will most likely show up as a crash on boot up. I'm not too concerned about it.
How can you be so sure it will trigger a crash on boot up ?
The sorting phase only compare key values, so NULL pointers will be thought as valid. Following that, there is the initial no-op'ing phrase that might crash (on the architectures using it). Then a NULL code pointer is considered as the discarded "init" section. A NULL key will just be a non-match, and thus skipped.
So I can very much see scenarios where this bug would silently skip jump labels without a crash. This is what I am concerned about. Using the approach that "a crash will happen" as a safety net to tell us that we missed something seems very risky to me.
Thanks,
Mathieu
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
Quoted 49 lines · * David Daney ([email protected]) wrote:
Quoted 27 lines · Steven Rostedt
Quoted 26 lines · Mathieu Desnoyers
Quoted 24 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 9 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
Quoted 4 lines
Quoted 4 lines
Hi Steven,
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ?
I can:
http://www.x86-64.org/documentation/abi.pdf Section 3.1.2:
Aggregates and Unions
Structures and unions assume the alignment of their most strictly aligned component. Each member is assigned to the lowest available offset with the appropriate alignment. The size of any object is always a multiple of the object‘s alignment.
An array uses the same alignment as its elements, except that a local or global array variable of length at least 16 bytes or a C99 variable-length array variable always has alignment of at least 16 bytes.
Quoted 5 lines
Structure and union objects can require padding to meet size and alignment constraints. The contents of any padding is undefined.
I don't think it is explicitly stated, but it is also true that the size is the smallest value that meets the above constraints.
Your quote seems to apply in this case because:
a) the "structure" is defined in assembly, so the compiler is not deciding the alignment of the structure.
b) the C code that iterates on the section array in jump_label.c see an array of structures, which imply that gcc does not have no freedom in terms of up-aligning these structures.
The problem we faced with trace event and tracepoints was caused by the fact that we did define static structures from within C code, and the compiler mistakenly believed that it was the only one holding references to these structures, so it could up-align them to larger multiples as it wants, because they were each independent objects.
Quoted 10 lines
Quoted 7 lines
Quoted 6 lines
Also, could
you point out what would refrain the linker from aligning the start of object sections on the next 32-bytes (thus power of two) address multiple ?The rules of the ABI are quite specific. It would be a toolchain bug if this were messed up.
The trace event and tracepoint code are doing static structure declarations into specific sections for the linker to create array bounds with, and this last part sadly falls outside of the compiler knowledge, and therefore might be outside of the ABI scope because the compiler believes that these objects are local to the object and never ever exported. Note that up-aligning on larger multiples still meets the local alignment requirements -- it's just not valid to e.g. create an array that assumes that these statically defined structures are next to another without any extra padding.
Quoted 7 lines
Quoted 4 lines
Maybe it would be just easier to add another long ;)
Maybe we should audit all the data structures in the entire kernel and add manual padding to power of 2 boundaries.
Only required when we play games with sections outside of the compiler knowledge, which is really a handful of cases.
Quoted 7 lines
Quoted 7 lines
Seriously, it would. Then it would be 32 bytes on 64bit and 16 bytes on 32bit. Then I guess we can have our guarantee without doing a large change to have this indirect pointer and still waste sizeof(long) bytes in having it.
Quoted 5 lines
Quoted 2 lines
Just insert a long "Reserved" word.
I disagree. Wasting memory to work around non-existent hypothetical bugs seems wrong to me.
This object layout problem has been me with tracepoints in the past, and has bitter Steven with trace event recently. It is therefore very real.
Thanks,
Mathieu
Quoted 2 lines
David Daney
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
Quoted 35 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 26 lines · Mathieu Desnoyers
Quoted 15 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Thanks Jason,
I started looking at them, I should have comments tomorrow (if I have any comments ;)
Quoted 5 lines
I've tried to split this update up somewhat, but I've only succeeded to split out the dynamic debug bits. The interface changes and re-write are quite intertwined.
Quoted 9 lines
Quoted 4 lines
I believe this update should address all the comments from the previous posting except for Mathieu's request for a section of jump label pointers that point to the jump label structures (since the compiler might leave gaps in the jump label structures).
The jump label structures is a list of 3 pointers, correct? I doubt that gcc would place any holes in it as they are all aligned by natural word size.
Quoted 7 lines
Hi Steven,
Can you explain what would prevent gcc from aligning these 3 pointers (total of 24 bytes on 64-bit architectures) on 32-bytes ? Also, could you point out what would refrain the linker from aligning the start of object sections on the next 32-bytes (thus power of two) address multiple ?
Quoted 8 lines
Maybe it would be just easier to add another long ;)
Seriously, it would. Then it would be 32 bytes on 64bit and 16 bytes on 32bit. Then I guess we can have our guarantee without doing a large change to have this indirect pointer and still waste sizeof(long) bytes in having it.
Just insert a long "Reserved" word.
I agree that this solution can work, but it's only because the "object" definition is done in assembly in this case (and not in C, like we did for trace event and tracepoints). Padding to power of 2 multiples should make the linker happy. There should be a nice comment beside these padding elements though.
Thanks,
Mathieu
Quoted 18 lines
-- Steve
Quoted 13 lines
I think we need to be a bit more strict in our interpretation of what guarantee gcc/ld provide and don't provide with respect to section and structure alignment.
As it stands now, the section alignment of jump labels looks half-broken on most architectures, and this *is* a big deal. I would really like to see a patch for this (it can be a separate patch) going in for .39.
Thank you,
Mathieu
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
Steven Rostedt
maintainerQuoted 7 lines · Mathieu Desnoyers
Quoted 1 line
Just insert a long "Reserved" word.
I agree that this solution can work, but it's only because the "object" definition is done in assembly in this case (and not in C, like we did for trace event and tracepoints). Padding to power of 2 multiples should make the linker happy. There should be a nice comment beside these padding elements though.
Rereading what David and even what you wrote just now, I don't think this is even needed. As you said. The issue with us is that we had defined structs in C as static which lost all bets. Not to mention, these structures were not natural word aligned.
The linker should not be adding holes more than natural word alignment. Why waste space?
-- Steve
Quoted 10 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 7 lines · Mathieu Desnoyers
Quoted 1 line
Just insert a long "Reserved" word.
I agree that this solution can work, but it's only because the "object" definition is done in assembly in this case (and not in C, like we did for trace event and tracepoints). Padding to power of 2 multiples should make the linker happy. There should be a nice comment beside these padding elements though.
Quoted 7 lines
Rereading what David and even what you wrote just now, I don't think this is even needed. As you said. The issue with us is that we had defined structs in C as static which lost all bets. Not to mention, these structures were not natural word aligned.
The linker should not be adding holes more than natural word alignment. Why waste space?
Here is what I am concerned about (maybe wongly, we'll see):
if we take a few objects, chosen arbitrarily, which will end up being linked together, e.g.
in kernel/
Sections:
Idx Name Size VMA LMA File off Algn
objdump -h *.o |grep jump
28 __jump_table 000007e0 0000000000000000 0000000000000000 000ba614 2**0 5 __jump_table 00000030 0000000000000000 0000000000000000 0000077c 2**0 6 __jump_table 00000048 0000000000000000 0000000000000000 000027d8 2**0 9 __jump_table 00000048 0000000000000000 0000000000000000 00002788 2**0 3 __jump_table 000000c0 0000000000000000 0000000000000000 00000f60 2**0 3 __jump_table 00000048 0000000000000000 0000000000000000 0000092c 2**0 6 __jump_table 00000018 0000000000000000 0000000000000000 000008db 2**0 8 __jump_table 00000018 0000000000000000 0000000000000000 00002744 2**0 5 __jump_table 00000030 0000000000000000 0000000000000000 000008ea 2**0 6 __jump_table 00000078 0000000000000000 0000000000000000 000066ad 2**0 7 __jump_table 00000018 0000000000000000 0000000000000000 000023f0 2**0 13 __jump_table 00000120 0000000000000000 0000000000000000 00010c9a 2**0 7 __jump_table 00000060 0000000000000000 0000000000000000 00005126 2**0 5 __jump_table 00000138 0000000000000000 0000000000000000 000020f4 2**0 6 __jump_table 00000180 0000000000000000 0000000000000000 000045c6 2**0 10 __jump_table 00000078 0000000000000000 0000000000000000 00005060 2**0
We see here that the section alignment is 2**0 for each object (that is for a 2.6.38-rc7-tip kernel). Now as long as the alignment stays like this, it's OK, because the linker won't add padding between the sections. So my question is: is there any guarantee that the linker will keep this alignment to 2**0, or is there a possibility that it bumps it to an higher value ?
For instance, if we have two objects linked together in a first linking phase, thus generating a resulting object that uses the 8-byte alignment specified by the linker script, and then we have a second link phase that uses this intermediate object and links it into the kernel, this might add such a whole on a 32-bit architecture, no ? (e.g. see the e1000e Makefile, it seems to use this 2-steps method when built as =Y).
Thanks,
Mathieu
Signature · 4 lines
Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com
Quoted 3 lines · Jason Baron
Hi,
Re-fresh of updates against latest -tip tree.
Hi Jason,
here are the s390 bits, tested successfully on top of your patches so it would be nice to have this in .39 too.
The s390 support depends on the JUMP_TABLE being in the RW section which is not the case in .38 and leads to a protection exception there.
--Jan
Subject: [PATCH] jump_label: Add s390 support
From: Jan Glauber <[email protected]>
Implement the architecture backend for jump label support on s390.
For a shared kernel booted from a NSS silently disable jump labels because the NSS is read-only. Therefore jump labels will be disabled in a shared kernel and can't be activated.
--- arch/s390/Kconfig | 1 arch/s390/include/asm/jump_label.h | 34 +++++++++++++++++++++ arch/s390/kernel/Makefile | 2 - arch/s390/kernel/jump_label.c | 59 +++++++++++++++++++++++++++++++++++++ arch/s390/kernel/module.c | 1 5 files changed, 96 insertions(+), 1 deletion(-)
arch/s390/Kconfig +1 -0
@@ -87,6 +87,7 @@ config S390 select HAVE_KERNEL_LZO select HAVE_GET_USER_PAGES_FAST select HAVE_ARCH_MUTEX_CPU_RELAX + select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 select ARCH_INLINE_SPIN_TRYLOCK select ARCH_INLINE_SPIN_TRYLOCK_BH select ARCH_INLINE_SPIN_LOCK
arch/s390/include/asm/jump_label.h new file +34 -0
@@ -0,0 +1,34 @@ +#ifndef _ASM_S390_JUMP_LABEL_H +#define _ASM_S390_JUMP_LABEL_H + +#include <linux/types.h> + +#define JUMP_LABEL_NOP_SIZE 6 + +#ifdef CONFIG_64BIT +#define ASM_PTR ".quad" +#else +#define ASM_PTR ".long" +#endif + +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("0: brcl 0,0\n" +".pushsection __jump_table, \"aw\"\n" +ASM_PTR " 0b, %l[label], %0\n" +".popsection\n" + : :"X" (key) : : label); +return false; +label: +return true; +} + +typedef unsigned long jump_label_t ; + +struct jump_entry { +jump_label_t code; +jump_label_t target; +jump_label_t key; +}; + +#endif
arch/s390/kernel/Makefile +1 -1
@@ -23,7 +23,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu - obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \ processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \ - vdso.o vtime.o sysinfo.o nmi.o sclp.o + vdso.o vtime.o sysinfo.o nmi.o sclp.o jump_label.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
arch/s390/kernel/jump_label.c new file +59 -0
59 lines not on this page · raw message
arch/s390/kernel/module.c +1 -0
@@ -407,6 +407,7 @@ int module_finalize(const Elf_Ehdr *hdr, {vfree (me->arch.syminfo); me->arch.syminfo =NULL ; +jump_label_apply_nops (me);return 0 ; }