tracing: updates and jump label rebase
Subsystems (9)
Steven Rostedt
maintainerIngo,
[ Resend, as due to a cut and paste error, Ingo's and Andrew's email
was chopped off the Cc list ]
This includes minor updates to ftrace as well as the patchset for jump labels. I took out the debug printk patch that had caused earlier conflicts. We can add that one later.
Please pull the latest tip/perf/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/core
Jan Glauber (1):
jump label: Add s390 support
Jason Baron (2):
jump label: Introduce static_branch() interface jump label: Add _ASM_ALIGN for x86 and x86_64
Jiri Olsa (1):
tracing: Avoid soft lockup in trace_pipe
Steven Rostedt (2):
tracing: Convert trace_printk() formats for module to const char *
tracing: Print trace_bprintk() formats for modules too
----
arch/mips/include/asm/jump_label.h | 22 +- arch/s390/Kconfig | 1 + arch/s390/include/asm/jump_label.h | 37 +++ arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/jump_label.c | 59 ++++ arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 27 +- arch/x86/kernel/alternative.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 | 89 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 539 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/trace/trace.c | 15 +- kernel/trace/trace_output.c | 3 + kernel/trace/trace_printk.c | 120 +++++++- kernel/tracepoint.c | 23 +- 22 files changed, 578 insertions(+), 502 deletions(-)
Steven Rostedt
maintainerPATCH 1/6 tracing: Convert trace_printk() formats for module to const char *
From: Steven Rostedt <[email protected]>
The trace_printk() formats for modules do not show up in the debugfs/tracing/printk_formats file. Only the formats that are for trace_printk()s that are in the kernel core.
To facilitate the change to add trace_printk() formats from modules into that file as well, we need to convert the structure that holds the formats from char fmt[], into const char *fmt, and allocate them separately.
--- kernel/trace/trace_printk.c | 17 +++++++++++------ 1 files changed, 11 insertions(+), 6 deletions(-)
kernel/trace/trace_printk.c +11 -6
@@ -32,7 +32,7 @@ static DEFINE_MUTEX(btrace_mutex);struct trace_bprintk_fmt {struct list_head list; -char fmt[0 ]; +const char *fmt; };static inline struct trace_bprintk_fmt *lookup_format (const char *fmt)
@@ -49,6 +49,7 @@ staticvoid hold_module_trace_bprintk_format (const char **start,const char **end) {const char **iter; +char *fmt;mutex_lock (&btrace_mutex);for (iter = start; iter < end; iter++) {
@@ -58,14 +59,18 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)continue ; } - tb_fmt =kmalloc (offsetof(struct trace_bprintk_fmt , fmt) - +strlen (*iter) +1 ,GFP_KERNEL ); -if (tb_fmt) { + tb_fmt =kmalloc (sizeof (*tb_fmt),GFP_KERNEL ); +if (tb_fmt) + fmt =kmalloc (strlen (*iter) +1 ,GFP_KERNEL ); +if (tb_fmt && fmt) {list_add_tail (&tb_fmt->list, &trace_bprintk_fmt_list); -strcpy (tb_fmt->fmt, *iter); +strcpy (fmt, *iter); + tb_fmt->fmt = fmt; *iter = tb_fmt->fmt; - }else + }else { +kfree (tb_fmt); *iter =NULL ; + } }mutex_unlock (&btrace_mutex); }
Signature · 1 line
1.7.2.3
Steven Rostedt
maintainerPATCH 2/6 tracing: Print trace_bprintk() formats for modules too
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The file debugfs/tracing/printk_formats maps the addresses to the formats that are used by trace_bprintk() so that userspace tools can read the buffer and be able to decode trace_bprintk events to get the format saved when reading the ring buffer directly.
This is because trace_bprintk() does not store the format into the buffer, but just the address of the format, which is hidden in the kernel memory.
But currently it only exports trace_bprintk()s from the kernel core and not for modules. The modules need their formats exported as well.
--- kernel/trace/trace_printk.c | 103 ++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 97 insertions(+), 6 deletions(-)
kernel/trace/trace_printk.c +97 -6
@@ -89,6 +89,76 @@ static int module_trace_bprintk_format_notify(struct notifier_block *self, return 0; } +/* +* The debugfs/tracing/printk_formats file maps the addresses with +* the ASCII formats that are used in the bprintk events in the +* buffer. For userspace tools to be able to decode the events from +* the buffer, they need to be able to map the address with the format. +* +* The addresses of the bprintk formats are in their own section +* __trace_printk_fmt. But for modules we copy them into a link list. +* The code to print the formats and their addresses passes around the +* address of the fmt string. If the fmt address passed into the seq +* functions is within the kernel core __trace_printk_fmt section, then +* it simply uses the next pointer in the list. +* +* When the fmt pointer is outside the kernel core __trace_printk_fmt +* section, then we need to read the link list pointers. The trick is +* we pass the address of the string to the seq function just like +* we do for the kernel core formats. To get back the structure that +* holds the format, we simply use containerof() and then go to the +* next format in the list. +*/ +static const char ** +find_next_mod_format (int start_index,void *v,const char **fmt,loff_t *pos) +{ +struct trace_bprintk_fmt *mod_fmt; + +if (list_empty (&trace_bprintk_fmt_list)) +return NULL ; + +/* +* v will point to the address of the fmt record from t_next +* v will be NULL from t_start. +* If this is the first pointer or called from start +* then we need to walk the list. +*/ +if (!v || start_index == *pos) { +struct trace_bprintk_fmt *p; + +/* search the module list */ +list_for_each_entry (p, &trace_bprintk_fmt_list, list) { +if (start_index == *pos) +return &p->fmt; + start_index++; + } +/* pos > index */ +return NULL ; + } + +/* +* v points to the address of the fmt field in the mod list +* structure that holds the module print format. +*/ + mod_fmt =container_of (v,typeof (*mod_fmt), fmt); +if (mod_fmt->list.next == &trace_bprintk_fmt_list) +return NULL ; + + mod_fmt =container_of (mod_fmt->list.next,typeof (*mod_fmt), list); + +return &mod_fmt->fmt; +} + +static void format_mod_start (void ) +{ +mutex_lock (&btrace_mutex); +} + +static void format_mod_stop (void ) +{ +mutex_unlock (&btrace_mutex); +} +#else /* !CONFIG_MODULES */ __init static int module_trace_bprintk_format_notify(struct notifier_block *self,
@@ -96,6 +166,13 @@ module_trace_bprintk_format_notify(struct notifier_block *self, {return 0 ; } +static inline const char ** +find_next_mod_format (int start_index,void *v,const char **fmt,loff_t *pos) +{ +return NULL ; +} +static inline void format_mod_start (void ) { } +static inline void format_mod_stop (void ) { }#endif /* CONFIG_MODULES */
@@ -158,20 +235,33 @@ int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap) }EXPORT_SYMBOL_GPL (__ftrace_vprintk); +static const char **find_next (void *v,loff_t *pos) +{ +const char **fmt = v; +int start_index; + +if (!fmt) + fmt = __start___trace_bprintk_fmt + *pos; + + start_index = __stop___trace_bprintk_fmt - __start___trace_bprintk_fmt; + +if (*pos < start_index) +return fmt; + +return find_next_mod_format (start_index, v, fmt, pos); +} +static void *t_start (struct seq_file *m,loff_t *pos) { -const char **fmt = __start___trace_bprintk_fmt + *pos; - -if ((unsigned long )fmt >= (unsigned long )__stop___trace_bprintk_fmt) -return NULL ; -return fmt; +format_mod_start (); +return find_next (NULL , pos); }static void *t_next (struct seq_file *m,void * v,loff_t *pos) { (*pos)++; -return t_start (m, pos); +return find_next (v, pos); }static int t_show (struct seq_file *m,void *v)
@@ -210,6 +300,7 @@ static int t_show(struct seq_file *m, void *v)static void t_stop (struct seq_file *m,void *p) { +format_mod_stop (); }static const struct seq_operations show_format_seq_ops = {
Signature · 1 line
1.7.2.3
Steven Rostedt
maintainerPATCH 3/6 tracing: Avoid soft lockup in trace_pipe
In reply to Steven RostedtFrom: Jiri Olsa <[email protected]>
running following commands:
# enable the binary option echo 1 > ./options/bin # disable context info option echo 0 > ./options/context-info # tracing only events echo 1 > ./events/enable cat trace_pipe
plus forcing system to generate many tracing events, is causing lockup (in NON preemptive kernels) inside tracing_read_pipe function.
The issue is also easily reproduced by running ltp stress test. (ftrace_stress_test.sh)
The reasons are:
- bin/hex/raw output functions for events are set to trace_nop_print function, which prints nothing and returns TRACE_TYPE_HANDLED value
- LOST EVENT trace do not handle trace_seq overflow
These reasons force the while loop in tracing_read_pipe function never to break.
The attached patch fixies handling of lost event trace, and changes trace_nop_print to print minimal info, which is needed for the correct tracing_read_pipe processing.
v2 changes:
- omit the cond_resched changes by trace_nop_print changes
- WARN changed to WARN_ONCE and added info to be able to find out the culprit
v3 changes:
- make more accurate patch comment
LKML-Reference: <[email protected]>
--- kernel/trace/trace.c | 15 ++++++++++++--- kernel/trace/trace_output.c | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-)
kernel/trace/trace.c +12 -3
@@ -2013,9 +2013,10 @@ enum print_line_t print_trace_line(struct trace_iterator *iter) {enum print_line_t ret; -if (iter->lost_events) -trace_seq_printf (&iter->seq,"CPU:%d [LOST %lu EVENTS]\n" , - iter->cpu, iter->lost_events); +if (iter->lost_events && + !trace_seq_printf (&iter->seq,"CPU:%d [LOST %lu EVENTS]\n" , + iter->cpu, iter->lost_events)) +return TRACE_TYPE_PARTIAL_LINE ;if (iter->trace && iter->trace->print_line) { ret = iter->trace->print_line (iter);
@@ -3229,6 +3230,14 @@ waitagain:if (iter->seq.len >= cnt)break ; + +/* +* Setting the full flag means we reached the trace_seq buffer +* size and we should leave by partial output condition above. +* One of the trace_seq_* functions is not used properly. +*/ +WARN_ONCE (iter->seq.full,"full flag set for trace type %d" , + iter->ent->type); }trace_access_unlock (iter->cpu_file);trace_event_read_unlock ();
kernel/trace/trace_output.c +3 -0
@@ -830,6 +830,9 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_event);enum print_line_t trace_nop_print (struct trace_iterator *iter,int flags,struct trace_event *event) { +if (!trace_seq_printf (&iter->seq,"type: %d\n" , iter->ent->type)) +return TRACE_TYPE_PARTIAL_LINE ; +return TRACE_TYPE_HANDLED ; }
Signature · 1 line
1.7.2.3
Steven Rostedt
maintainerPATCH 4/6 jump label: Introduce static_branch() interface
In reply to Steven RostedtFrom: Jason Baron <[email protected]>
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
LKML-Reference: <[email protected]>
--- arch/mips/include/asm/jump_label.h | 22 +- 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/module.c | 1 + include/asm-generic/vmlinux.lds.h | 14 +- include/linux/dynamic_debug.h | 2 - include/linux/jump_label.h | 89 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +- include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 539 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/tracepoint.c | 23 +- 15 files changed, 356 insertions(+), 486 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/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
@@ -679,7 +679,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/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) = .; \
@@ -589,14 +591,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 +56 -33
129 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>
@@ -1034,7 +1034,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 );
@@ -1063,22 +1063,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
@@ -1086,7 +1085,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 +218 -321
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 ;
@@ -5417,7 +5417,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.2.3
Steven Rostedt
maintainerPATCH 5/6 jump label: Add _ASM_ALIGN for x86 and x86_64
In reply to Steven RostedtFrom: Jason Baron <[email protected]>
The linker should not be adding holes to word size aligned pointers, but out of paranoia we are explicitly specifying that alignment. I have not seen any holes in the jump label section in practice.
LKML-Reference: <e119fbd060c9452c56063ea6148ba1070e7434cc.1300299760.git.jbaron@redhat.com>
--- arch/x86/include/asm/jump_label.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/x86/include/asm/jump_label.h +1 -0
@@ -16,6 +16,7 @@ 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_ALIGN"\n\t" _ASM_PTR"1b, %l[l_yes], %c0 \n\t" ".popsection \n\t" : :"i" (key) : : l_yes);
Signature · 1 line
1.7.2.3
Steven Rostedt
maintainerPATCH 6/6 jump label: Add s390 support
In reply to Steven RostedtFrom: 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.
LKML-Reference: <6935d2c41ce111e1719176ed4bbd3dbe4de80855.1300299760.git.jbaron@redhat.com>
--- arch/s390/Kconfig | 1 + arch/s390/include/asm/jump_label.h | 37 ++++++++++++++++++++++ arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/jump_label.c | 59 ++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletions(-) create mode 100644 arch/s390/include/asm/jump_label.h create mode 100644 arch/s390/kernel/jump_label.c
arch/s390/Kconfig +1 -0
@@ -88,6 +88,7 @@ config S390 select HAVE_KERNEL_XZ 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 +37 -0
@@ -0,0 +1,37 @@ +#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" +#define ASM_ALIGN ".balign 8" +#else +#define ASM_PTR ".long" +#define ASM_ALIGN ".balign 4" +#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_ALIGN "\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 -Iarch/s390/math-emu -w 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
Signature · 1 line
1.7.2.3
Steven Rostedt
maintainerQuoted 5 lines · Steven Rostedt
Ingo,
[ Resend, as due to a cut and paste error, Ingo's and Andrew's email
was chopped off the Cc list ]
Quoted 9 lines
This includes minor updates to ftrace as well as the patchset for jump labels. I took out the debug printk patch that had caused earlier conflicts. We can add that one later.
Please pull the latest tip/perf/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/core
Ping?
-- Steve
Quoted 45 lines · Steven Rostedt
Ingo,
[ Resend, as due to a cut and paste error, Ingo's and Andrew's email
was chopped off the Cc list ]This includes minor updates to ftrace as well as the patchset for jump labels. I took out the debug printk patch that had caused earlier conflicts. We can add that one later.
Please pull the latest tip/perf/core tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/coreJan Glauber (1):
jump label: Add s390 supportJason Baron (2):
jump label: Introducestatic_branch()interface jump label: Add_ASM_ALIGNfor x86 andx86_64Jiri Olsa (1):
tracing: Avoid soft lockup intrace_pipeSteven Rostedt (2):
tracing: Converttrace_printk()formats for module to const char *
tracing: Printtrace_bprintk()formats for modules too----
arch/mips/include/asm/jump_label.h | 22 +- arch/s390/Kconfig | 1 + arch/s390/include/asm/jump_label.h | 37 +++ arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/jump_label.c | 59 ++++ arch/sparc/include/asm/jump_label.h | 25 +- arch/x86/include/asm/alternative.h | 3 +- arch/x86/include/asm/jump_label.h | 27 +- arch/x86/kernel/alternative.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 | 89 ++++--- include/linux/jump_label_ref.h | 44 --- include/linux/perf_event.h | 26 +-
Quoted 8 lines
include/linux/tracepoint.h | 22 +- kernel/jump_label.c | 539 ++++++++++++++--------------------- kernel/perf_event.c | 4 +- kernel/trace/trace.c | 15 +- kernel/trace/trace_output.c | 3 + kernel/trace/trace_printk.c | 120 +++++++- kernel/tracepoint.c | 23 +- 22 files changed, 578 insertions(+), 502 deletions(-)
Pulled, thanks a lot Steve!
Ingo