20 Oct, 2013

1 commit

  • Usage of the static key primitives to toggle a branch must not be used
    before jump_label_init() is called from init/main.c. jump_label_init
    reorganizes and wires up the jump_entries so usage before that could
    have unforeseen consequences.

    Following primitives are now checked for correct use:
    * static_key_slow_inc
    * static_key_slow_dec
    * static_key_slow_dec_deferred
    * jump_label_rate_limit

    The x86 architecture already checks this by testing if the default_nop
    was already replaced with an optimal nop or with a branch instruction. It
    will panic then. Other architectures don't check for this.

    Because we need to relax this check for the x86 arch to allow code to
    transition from default_nop to the enabled state and other architectures
    did not check for this at all this patch introduces checking on the
    static_key primitives in a non-arch dependent manner.

    All checked functions are considered slow-path so the additional check
    does no harm to performance.

    The warnings are best observed with earlyprintk.

    Based on a patch from Andi Kleen.

    Cc: Steven Rostedt
    Cc: Peter Zijlstra
    Cc: Andi Kleen
    Signed-off-by: Hannes Frederic Sowa
    Signed-off-by: David S. Miller

    Hannes Frederic Sowa
     

09 Aug, 2013

1 commit

  • Commit b202952075f62603bea9bfb6ebc6b0420db11949 ("perf, core: Rate limit
    perf_sched_events jump_label patching") introduced rate limiting
    for jump label disabling. The changes were made in the jump label code
    in order to be more widely available and to keep things tidier. This is
    all fine, except now jump_label.h includes linux/workqueue.h, which
    makes it impossible to include jump_label.h from anything that
    workqueue.h needs. For example, it's now impossible to include
    jump_label.h from asm/spinlock.h, which is done in proposed
    pv-ticketlock patches. This patch splits out the rate limiting related
    changes from jump_label.h into a new file, jump_label_ratelimit.h, to
    resolve the issue.

    Signed-off-by: Andrew Jones
    Link: http://lkml.kernel.org/r/1376058122-8248-10-git-send-email-raghavendra.kt@linux.vnet.ibm.com
    Reviewed-by: Konrad Rzeszutek Wilk
    Signed-off-by: Raghavendra K T
    Acked-by: Ingo Molnar
    Signed-off-by: H. Peter Anvin

    Andrew Jones
     

07 Aug, 2012

1 commit


29 Feb, 2012

1 commit

  • In the jump label enabled case, calling static_key_enabled()
    results in a function call. The function returns the results of
    a compare, so it really doesn't need the overhead of a full
    function call. Let's make it 'static inline' for both the jump
    label enabled and disabled cases.

    Signed-off-by: Jason Baron
    Cc: a.p.zijlstra@chello.nl
    Cc: rostedt@goodmis.org
    Cc: mathieu.desnoyers@polymtl.ca
    Cc: Andrew Morton
    Cc: Linus Torvalds
    Link: http://lkml.kernel.org/r/201202281849.q1SIn1p2023270@int-mx10.intmail.prod.int.phx2.redhat.com
    Signed-off-by: Ingo Molnar

    Jason Baron
     

24 Feb, 2012

1 commit

  • …_key_slow_[inc|dec]()

    So here's a boot tested patch on top of Jason's series that does
    all the cleanups I talked about and turns jump labels into a
    more intuitive to use facility. It should also address the
    various misconceptions and confusions that surround jump labels.

    Typical usage scenarios:

    #include <linux/static_key.h>

    struct static_key key = STATIC_KEY_INIT_TRUE;

    if (static_key_false(&key))
    do unlikely code
    else
    do likely code

    Or:

    if (static_key_true(&key))
    do likely code
    else
    do unlikely code

    The static key is modified via:

    static_key_slow_inc(&key);
    ...
    static_key_slow_dec(&key);

    The 'slow' prefix makes it abundantly clear that this is an
    expensive operation.

    I've updated all in-kernel code to use this everywhere. Note
    that I (intentionally) have not pushed through the rename
    blindly through to the lowest levels: the actual jump-label
    patching arch facility should be named like that, so we want to
    decouple jump labels from the static-key facility a bit.

    On non-jump-label enabled architectures static keys default to
    likely()/unlikely() branches.

    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Acked-by: Jason Baron <jbaron@redhat.com>
    Acked-by: Steven Rostedt <rostedt@goodmis.org>
    Cc: a.p.zijlstra@chello.nl
    Cc: mathieu.desnoyers@efficios.com
    Cc: davem@davemloft.net
    Cc: ddaney.cavm@gmail.com
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Link: http://lkml.kernel.org/r/20120222085809.GA26397@elte.hu
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

    Ingo Molnar
     

22 Feb, 2012

2 commits

  • While cross-compiling on sparc64, I found:

    kernel/jump_label.c: In function 'jump_label_update':
    kernel/jump_label.c:447:40: warning: cast from pointer to
    integer of different size [-Wpointer-to-int-cast]

    Fix by casting to 'unsigned long'.

    Signed-off-by: Jason Baron
    Cc: rostedt@goodmis.org
    Cc: mathieu.desnoyers@efficios.com
    Cc: davem@davemloft.net
    Cc: ddaney.cavm@gmail.com
    Cc: a.p.zijlstra@chello.nl
    Link: http://lkml.kernel.org/r/08026cbc6df80619cae833ef1ebbbc43efab69ab.1329851692.git.jbaron@redhat.com
    Signed-off-by: Ingo Molnar

    Jason Baron
     
  • The count on a jump label key should never go negative. Add a
    WARN() to check for this condition.

    Signed-off-by: Jason Baron
    Cc: Gleb Natapov
    Cc: rostedt@goodmis.org
    Cc: mathieu.desnoyers@efficios.com
    Cc: davem@davemloft.net
    Cc: ddaney.cavm@gmail.com
    Cc: a.p.zijlstra@chello.nl
    Link: http://lkml.kernel.org/r/3c68556121be4d1920417a3fe367da1ec38246b4.1329851692.git.jbaron@redhat.com
    Signed-off-by: Ingo Molnar

    Jason Baron
     

27 Dec, 2011

2 commits

  • * tip/perf/core: (66 commits)
    perf, x86: Expose perf capability to other modules
    perf, x86: Implement arch event mask as quirk
    x86, perf: Disable non available architectural events
    jump_label: Provide jump_label_key initializers
    jump_label, x86: Fix section mismatch
    perf, core: Rate limit perf_sched_events jump_label patching
    perf: Fix enable_on_exec for sibling events
    perf: Remove superfluous arguments
    perf, x86: Prefer fixed-purpose counters when scheduling
    perf, x86: Fix event scheduler for constraints with overlapping counters
    perf, x86: Implement event scheduler helper functions
    perf: Avoid a useless pmu_disable() in the perf-tick
    x86/tools: Add decoded instruction dump mode
    x86: Update instruction decoder to support new AVX formats
    x86/tools: Fix insn_sanity message outputs
    x86/tools: Fix instruction decoder message output
    x86: Fix instruction decoder to handle grouped AVX instructions
    x86/tools: Fix Makefile to build all test tools
    perf test: Soft errors shouldn't stop the "Validate PERF_RECORD_" test
    perf test: Validate PERF_RECORD_ events and perf_sample fields
    ...

    Signed-off-by: Avi Kivity

    * commit 'b3d9468a8bd218a695e3a0ff112cd4efd27b670a': (66 commits)
    perf, x86: Expose perf capability to other modules
    perf, x86: Implement arch event mask as quirk
    x86, perf: Disable non available architectural events
    jump_label: Provide jump_label_key initializers
    jump_label, x86: Fix section mismatch
    perf, core: Rate limit perf_sched_events jump_label patching
    perf: Fix enable_on_exec for sibling events
    perf: Remove superfluous arguments
    perf, x86: Prefer fixed-purpose counters when scheduling
    perf, x86: Fix event scheduler for constraints with overlapping counters
    perf, x86: Implement event scheduler helper functions
    perf: Avoid a useless pmu_disable() in the perf-tick
    x86/tools: Add decoded instruction dump mode
    x86: Update instruction decoder to support new AVX formats
    x86/tools: Fix insn_sanity message outputs
    x86/tools: Fix instruction decoder message output
    x86: Fix instruction decoder to handle grouped AVX instructions
    x86/tools: Fix Makefile to build all test tools
    perf test: Soft errors shouldn't stop the "Validate PERF_RECORD_" test
    perf test: Validate PERF_RECORD_ events and perf_sample fields
    ...

    Avi Kivity
     
  • Export these two symbols, they will be used by KVM mmu audit

    Signed-off-by: Xiao Guangrong
    Signed-off-by: Avi Kivity

    Xiao Guangrong
     

07 Dec, 2011

2 commits

  • Provide two initializers for jump_label_key that initialize it enabled
    or disabled. Also modify all jump_label code to allow for jump_labels to be
    initialized enabled.

    Signed-off-by: Peter Zijlstra
    Cc: Jason Baron
    Link: http://lkml.kernel.org/n/tip-p40e3yj21b68y03z1yv825e7@git.kernel.org
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     
  • WARNING: arch/x86/kernel/built-in.o(.text+0x4c71): Section mismatch in
    reference from the function arch_jump_label_transform_static() to the
    function .init.text:text_poke_early()
    The function arch_jump_label_transform_static() references
    the function __init text_poke_early().
    This is often because arch_jump_label_transform_static lacks a __init
    annotation or the annotation of text_poke_early is wrong.

    Signed-off-by: Peter Zijlstra
    Cc: Jason Baron
    Link: http://lkml.kernel.org/n/tip-9lefe89mrvurrwpqw5h8xm8z@git.kernel.org
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     

06 Dec, 2011

2 commits

  • jump_lable patching is very expensive operation that involves pausing all
    cpus. The patching of perf_sched_events jump_label is easily controllable
    from userspace by unprivileged user.

    When te user runs a loop like this:

    "while true; do perf stat -e cycles true; done"

    ... the performance of my test application that just increments a counter
    for one second drops by 4%.

    This is on a 16 cpu box with my test application using only one of
    them. An impact on a real server doing real work will be worse.

    Performance of KVM PMU drops nearly 50% due to jump_lable for "perf
    record" since KVM PMU implementation creates and destroys perf event
    frequently.

    This patch introduces a way to rate limit jump_label patching and uses
    it to fix the above problem.

    I believe that as jump_label use will spread the problem will become more
    common and thus solving it in a generic code is appropriate. Also fixing
    it in the perf code would result in moving jump_label accounting logic to
    perf code with all the ifdefs in case of JUMP_LABEL=n kernel. With this
    patch all details are nicely hidden inside jump_label code.

    Signed-off-by: Gleb Natapov
    Acked-by: Jason Baron
    Signed-off-by: Peter Zijlstra
    Link: http://lkml.kernel.org/r/20111127155909.GO2557@redhat.com
    Signed-off-by: Ingo Molnar

    Gleb Natapov
     
  • If cpu A calls jump_label_inc() just after atomic_add_return() is
    called by cpu B, atomic_inc_not_zero() will return value greater then
    zero and jump_label_inc() will return to a caller before jump_label_update()
    finishes its job on cpu B.

    Link: http://lkml.kernel.org/r/20111018175551.GH17571@redhat.com

    Cc: stable@vger.kernel.org
    Cc: Peter Zijlstra
    Acked-by: Jason Baron
    Signed-off-by: Gleb Natapov
    Signed-off-by: Steven Rostedt

    Gleb Natapov
     

11 Nov, 2011

1 commit


08 Nov, 2011

1 commit

  • If cpu A calls jump_label_inc() just after atomic_add_return() is
    called by cpu B, atomic_inc_not_zero() will return value greater then
    zero and jump_label_inc() will return to a caller before jump_label_update()
    finishes its job on cpu B.

    Link: http://lkml.kernel.org/r/20111018175551.GH17571@redhat.com

    Cc: stable@vger.kernel.org
    Cc: Peter Zijlstra
    Acked-by: Jason Baron
    Signed-off-by: Gleb Natapov
    Signed-off-by: Steven Rostedt

    Gleb Natapov
     

26 Oct, 2011

3 commits


29 Jun, 2011

1 commit

  • The jump labels entries for modules do not stop at __stop__jump_table,
    but after mod->jump_entries + mod_num_jump_entries.

    By checking the wrong end point, module trace events never get enabled.

    Cc: Ingo Molnar
    Acked-by: Jason Baron
    Tested-by: Avi Kivity
    Tested-by: Johannes Berg
    Signed-off-by: Xiao Guangrong
    Link: http://lkml.kernel.org/r/4E00038B.2060404@cn.fujitsu.com
    Signed-off-by: Steven Rostedt

    Xiao Guangrong
     

26 May, 2011

1 commit

  • When iterating the jump_label entries array (core or modules),
    the __jump_label_update function peeks over the last entry.

    The reason is that the end of the for loop depends on the key
    value of the processed entry. Thus when going through the
    last array entry, we will touch the memory behind the array
    limit.

    This bug probably will never be triggered, since most likely the
    memory behind the jump_label entries will be accesable and the
    entry->key will be different than the expected value.

    Signed-off-by: Jiri Olsa
    Acked-by: Jason Baron
    Link: http://lkml.kernel.org/r/20110510104346.GC1899@jolsa.brq.redhat.com
    Signed-off-by: Steven Rostedt

    Jiri Olsa
     

05 Apr, 2011

1 commit

  • 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

    Signed-off-by: Peter Zijlstra
    LKML-Reference:
    Signed-off-by: Jason Baron
    Suggested-by: H. Peter Anvin
    Tested-by: David Daney
    Acked-by: Ralf Baechle
    Acked-by: David S. Miller
    Acked-by: Mathieu Desnoyers
    Signed-off-by: Steven Rostedt

    Jason Baron
     

30 Oct, 2010

1 commit


28 Oct, 2010

2 commits

  • register_kprobe() downs the 'text_mutex' and then calls
    jump_label_text_reserved(), which downs the 'jump_label_mutex'.
    However, the jump label code takes those mutexes in the reverse
    order.

    Fix by requiring the caller of jump_label_text_reserved() to do
    the jump label locking via the newly added: jump_label_lock(),
    jump_label_unlock(). Currently, kprobes is the only user
    of jump_label_text_reserved().

    Reported-by: Ingo Molnar
    Acked-by: Masami Hiramatsu
    Signed-off-by: Jason Baron
    LKML-Reference:
    Signed-off-by: Steven Rostedt

    Jason Baron
     
  • Jump label uses is_module_text_address() to ensure that the module
    __init sections are valid before updating them. However, between the
    check for a valid module __init section and the subsequent jump
    label update, the module's __init section could be freed out from under
    us.

    We fix this potential race by adding a notifier callback to the
    MODULE_STATE_LIVE state. This notifier is called *after* the __init
    section has been run but before it is going to be freed. In the
    callback, the jump label code zeros the key value for any __init jump
    code within the module, and we add a check for a non-zero key value when
    we update jump labels. In this way we require no additional data
    structures.

    Thanks to Mathieu Desnoyers for pointing out this race condition.

    Reported-by: Mathieu Desnoyers
    Cc: Masami Hiramatsu
    Signed-off-by: Jason Baron
    LKML-Reference:

    [ Renamed remove_module_init() to remove_jump_label_module_init()
    as suggested by Masami Hiramatsu. ]

    Signed-off-by: Steven Rostedt

    Jason Baron
     

23 Sep, 2010

2 commits

  • Add a jump_label_text_reserved(void *start, void *end), so that other
    pieces of code that want to modify kernel text, can first verify that
    jump label has not reserved the instruction.

    Acked-by: Masami Hiramatsu
    Signed-off-by: Jason Baron
    LKML-Reference:
    Signed-off-by: Steven Rostedt

    Jason Baron
     
  • base patch to implement 'jump labeling'. Based on a new 'asm goto' inline
    assembly gcc mechanism, we can now branch to labels from an 'asm goto'
    statment. This allows us to create a 'no-op' fastpath, which can subsequently
    be patched with a jump to the slowpath code. This is useful for code which
    might be rarely used, but which we'd like to be able to call, if needed.
    Tracepoints are the current usecase that these are being implemented for.

    Acked-by: David S. Miller
    Signed-off-by: Jason Baron
    LKML-Reference:

    [ cleaned up some formating ]

    Signed-off-by: Steven Rostedt

    Jason Baron