diff mbox

[5/5] powerpc: use jump label for mmu_has_feature

Message ID 1377414952-15995-6-git-send-email-haokexin@gmail.com (mailing list archive)
State Superseded
Headers show

Commit Message

Kevin Hao Aug. 25, 2013, 7:15 a.m. UTC
The mmu features are fixed once the probe of mmu features are done.
And the function mmu_has_feature() does be used in some hot path.
The checking of the mmu features for each time of invoking of
mmu_has_feature() seems suboptimal. This tries to reduce this
overhead of this check by using jump label. But we can only use
the jump label for this check only after the execution of
jump_label_init(), so we introduce another jump label to
still do the feature check by default before all the mmu
feature jump labels are initialized.

Signed-off-by: Kevin Hao <haokexin@gmail.com>
---
 arch/powerpc/include/asm/mmu.h | 19 +++++++++++++++++++
 arch/powerpc/kernel/cputable.c | 20 ++++++++++++++++++++
 2 files changed, 39 insertions(+)
diff mbox

Patch

diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 691fd8a..163e9b1 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -121,10 +121,29 @@ 
 DECLARE_PER_CPU(int, next_tlbcam_idx);
 #endif
 
+#ifdef CONFIG_JUMP_LABEL
+#include <linux/jump_label_base.h>
+
+#define MAX_MMU_FEATURES	32
+
+extern struct static_key mmu_feat_keys[MAX_MMU_FEATURES];
+extern struct static_key mmu_feat_keys_enabled;
+
+static inline int mmu_has_feature(unsigned long feature)
+{
+	if (static_key_false(&mmu_feat_keys_enabled)) {
+		int i = __builtin_ctzl(feature);
+
+		return static_key_false(&mmu_feat_keys[i]);
+	} else
+		return !!(cur_cpu_spec->mmu_features & feature);
+}
+#else
 static inline int mmu_has_feature(unsigned long feature)
 {
 	return (cur_cpu_spec->mmu_features & feature);
 }
+#endif
 
 static inline void mmu_clear_feature(unsigned long feature)
 {
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 2014ab7..f25eb1d 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2280,4 +2280,24 @@  static __init int cpu_feat_keys_init(void)
 	return 0;
 }
 early_initcall(cpu_feat_keys_init);
+
+struct static_key mmu_feat_keys[MAX_MMU_FEATURES];
+struct static_key mmu_feat_keys_enabled;
+
+static __init int mmu_feat_keys_init(void)
+{
+	int i;
+
+	for (i = 0; i < MAX_MMU_FEATURES; i++) {
+		unsigned long f = 1 << i;
+
+		if (cur_cpu_spec->mmu_features & f)
+			static_key_slow_inc(&mmu_feat_keys[i]);
+	}
+
+	static_key_slow_inc(&mmu_feat_keys_enabled);
+
+	return 0;
+}
+early_initcall(mmu_feat_keys_init);
 #endif