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>
		
	
			
		
			
				
	
	
		
			50 lines
		
	
	
	
		
			962 B
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			50 lines
		
	
	
	
		
			962 B
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * This file is subject to the terms and conditions of the GNU General Public
 | 
						|
 * License.  See the file "COPYING" in the main directory of this archive
 | 
						|
 * for more details.
 | 
						|
 *
 | 
						|
 * Copyright (c) 2010 Cavium Networks, Inc.
 | 
						|
 */
 | 
						|
#ifndef _ASM_MIPS_JUMP_LABEL_H
 | 
						|
#define _ASM_MIPS_JUMP_LABEL_H
 | 
						|
 | 
						|
#include <linux/types.h>
 | 
						|
 | 
						|
#ifdef __KERNEL__
 | 
						|
 | 
						|
#define JUMP_LABEL_NOP_SIZE 4
 | 
						|
 | 
						|
#ifdef CONFIG_64BIT
 | 
						|
#define WORD_INSN ".dword"
 | 
						|
#else
 | 
						|
#define WORD_INSN ".word"
 | 
						|
#endif
 | 
						|
 | 
						|
static __always_inline bool arch_static_branch(struct static_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__ */
 | 
						|
 | 
						|
#ifdef CONFIG_64BIT
 | 
						|
typedef u64 jump_label_t;
 | 
						|
#else
 | 
						|
typedef u32 jump_label_t;
 | 
						|
#endif
 | 
						|
 | 
						|
struct jump_entry {
 | 
						|
	jump_label_t code;
 | 
						|
	jump_label_t target;
 | 
						|
	jump_label_t key;
 | 
						|
};
 | 
						|
 | 
						|
#endif /* _ASM_MIPS_JUMP_LABEL_H */
 |