x86 entry stuff, maybe for 4.4
Subsystems (4)
Andy Lutomirski
maintainercover x86 entry stuff, maybe for 4.4
The first patch is a bit ugly, but it fixes a bug that could affect lockdep. That bug is very minor and may not be observable at all, but I don't really want to bet on it.
The other three are intended to fix a performance regression in the entry rework that Frédéric objected to. They're much later than I'd like to have sent them for 4.4, but they're kind-of sort-of regression fixes, so maybe they're still okay. They would certainly need careful review, though.
I don't have a great benchmark for them. The biggest impact is likely to be to user page fault latency on CONFIG_CONTEXT_TRACKING=y kernels (i.e. distro kernels) that don't use context tracking (i.e. most users).
Andy Lutomirski (4):
x86/entry/64: Fix irqflag tracing wrt context tracking
context_tracking: Switch to new static_branch API x86/asm: Add asm macros for static keys/jump labels x86/entry/64: Bypass enter_from_user_mode on non-context-tracking
boots
arch/x86/entry/calling.h | 15 ++++++++++ arch/x86/entry/entry_64.S | 19 ++++++++----- arch/x86/include/asm/jump_label.h | 52 ++++++++++++++++++++++++++++------ include/linux/context_tracking_state.h | 4 +-- kernel/context_tracking.c | 4 +-- 5 files changed, 75 insertions(+), 19 deletions(-)
Signature · 1 line
2.4.3
Andy Lutomirski
maintainerPATCH 1/4 x86/entry/64: Fix irqflag tracing wrt context tracking
Paolo pointed out that enter_from_user_mode could be called while irqflags were traced as though IRQs were on.
In principle, this could confuse lockdep. It doesn't cause any problems that I've seen in any configuration, but if I build with CONFIG_DEBUG_LOCKDEP=y, enable a nohz_full CPU, and add code like:
if (irqs_disabled()) {
spin_lock(&something);
spin_unlock(&something);
}to the top of enter_from_user_mode, then lockdep will complain without this fix. It seems that lockdep's irqflags sanity checks are too weak to detect this bug without forcing the issue.
This patch adds one byte to normal kernels, and it's IMO a bit ugly. I haven't spotted a better way to do this yet, though. The issue is that we can't do TRACE_IRQS_OFF until after SWAPGS (if needed), but we're also supposed to do it before calling C code.
An alternative approach would be to call trace_hardirqs_off in enter_from_user_mode. That would be less code and would not bloat normal kernels at all, but it would be harder to see how the code worked.
--- arch/x86/entry/entry_64.S | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
arch/x86/entry/entry_64.S +10 -1
@@ -509,6 +509,14 @@ END(irq_entries_start) * tracking that we're in kernel mode. */ SWAPGS + + /* + * IRQs are off. NB: this trace call is duplicated. That's + * okay -- it's idempotent and it's irrelevant for performance as + * it's a no-op unless CONFIG_DEBUG_LOCKDEP=y. + */ + TRACE_IRQS_OFF + #ifdef CONFIG_CONTEXT_TRACKING call enter_from_user_mode #endif
@@ -1049,12 +1057,13 @@ ENTRY(error_entry) SWAPGS .Lerror_entry_from_usermode_after_swapgs: + TRACE_IRQS_OFF #ifdef CONFIG_CONTEXT_TRACKING call enter_from_user_mode #endif + ret .Lerror_entry_done: - TRACE_IRQS_OFF ret
Signature · 1 line
2.4.3
Andy Lutomirski
maintainerPATCH 3/4 x86/asm: Add asm macros for static keys/jump labels
In reply to Andy LutomirskiUnfortunately, these only work if HAVE_JUMP_LABEL. In principle, we could do some serious surgery on the core jump label infrastructure to keep the patch infrastructure available on x86 on all builds, but that's probably not worth it.
--- arch/x86/include/asm/jump_label.h | 52 +++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-)
arch/x86/include/asm/jump_label.h +44 -8
@@ -1,13 +1,6 @@#ifndef _ASM_X86_JUMP_LABEL_H#define _ASM_X86_JUMP_LABEL_H -#ifndef __ASSEMBLY__ - -#include <linux/stringify.h> -#include <linux/types.h> -#include <asm/nops.h> -#include <asm/asm.h> -#define JUMP_LABEL_NOP_SIZE 5#ifdef CONFIG_X86_64
@@ -16,6 +9,14 @@# define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC#endif +#include <asm/asm.h> +#include <asm/nops.h> + +#ifndef __ASSEMBLY__ + +#include <linux/stringify.h> +#include <linux/types.h> + static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { asm_volatile_goto("1:"
@@ -59,5 +60,40 @@ struct jump_entry {jump_label_t key; }; -#endif /* __ASSEMBLY__ */ +#else /* __ASSEMBLY__ */ + +.macro STATIC_JUMP_IF_TRUE target, key, def +.Lstatic_jump_\@: + .if \def +/* Equivalent to "jmp.d32 \target" */ + .byte 0xe9 + .long \target - .Lstatic_jump_after_\@ +.Lstatic_jump_after_\@: + .else + .byte STATIC_KEY_INIT_NOP + .endif + .pushsection __jump_table, "aw" + _ASM_ALIGN + _ASM_PTR .Lstatic_jump_\@, \target, \key + .popsection +.endm + +.macro STATIC_JUMP_IF_FALSE target, key, def +.Lstatic_jump_\@: + .if \def + .byte STATIC_KEY_INIT_NOP + .else +/* Equivalent to "jmp.d32 \target" */ + .byte 0xe9 + .long \target - .Lstatic_jump_after_\@ +.Lstatic_jump_after_\@: + .endif + .pushsection __jump_table, "aw" + _ASM_ALIGN + _ASM_PTR .Lstatic_jump_\@, \target, \key + 1 + .popsection +.endm + +#endif /* __ASSEMBLY__ */ +#endif
Signature · 1 line
2.4.3
Andy Lutomirski
maintainerPATCH 4/4 x86/entry/64: Bypass enter_from_user_mode on non-context-tracking boots
In reply to Andy LutomirskiOn CONFIG_CONTEXT_TRACKING kernels that have context tracking disabled at runtime (which includes most distro kernels), we still have the overhead of a call to enter_from_user_mode in interrupt and exception entries.
If jump labels are available, this uses the jump label infrastructure to skip the call.
--- arch/x86/entry/calling.h | 15 +++++++++++++++ arch/x86/entry/entry_64.S | 8 ++------ 2 files changed, 17 insertions(+), 6 deletions(-)
arch/x86/entry/calling.h +15 -0
@@ -1,3 +1,5 @@ +#include <linux/jump_label.h> +/* x86 function call convention, 64-bit:
@@ -232,3 +234,16 @@ For 32-bit we have the following conventions - kernel is built with#endif /* CONFIG_X86_64 */ +/* +* This does 'call enter_from_user_mode' unless we can avoid it based on +* kernel config or using the static jump infrastructure. +*/ +.macro CALL_ENTER_FROM_USER_MODE +#ifdef CONFIG_CONTEXT_TRACKING +#ifdef HAVE_JUMP_LABEL + STATIC_JUMP_IF_FALSE .Lafter_call_\@, context_tracking_enabled, def=0 +#endif +call enter_from_user_mode +.Lafter_call_\@: +#endif +.endm
arch/x86/entry/entry_64.S +2 -6
@@ -517,9 +517,7 @@ END(irq_entries_start) */ TRACE_IRQS_OFF -#ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode -#endif + CALL_ENTER_FROM_USER_MODE 1: /*
@@ -1058,9 +1056,7 @@ ENTRY(error_entry) .Lerror_entry_from_usermode_after_swapgs: TRACE_IRQS_OFF -#ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode -#endif + CALL_ENTER_FROM_USER_MODE ret .Lerror_entry_done:
Signature · 1 line
2.4.3
Andy Lutomirski
maintainerPATCH 2/4 context_tracking: Switch to new static_branch API
In reply to Andy LutomirskiThis is much less error-prone than the old code.
--- include/linux/context_tracking_state.h | 4 ++-- kernel/context_tracking.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
include/linux/context_tracking_state.h +2 -2
@@ -22,12 +22,12 @@ struct context_tracking { };#ifdef CONFIG_CONTEXT_TRACKING -extern struct static_key context_tracking_enabled; +extern struct static_key_false context_tracking_enabled; DECLARE_PER_CPU(struct context_tracking, context_tracking);static inline bool context_tracking_is_enabled (void ) { -return static_key_false (&context_tracking_enabled); +return static_branch_unlikely (&context_tracking_enabled); }static inline bool context_tracking_cpu_is_enabled (void )
kernel/context_tracking.c +2 -2
@@ -24,7 +24,7 @@#define CREATE_TRACE_POINTS #include <trace/events/context_tracking.h> -struct static_key context_tracking_enabled =STATIC_KEY_INIT_FALSE ; +DEFINE_STATIC_KEY_FALSE (context_tracking_enabled);EXPORT_SYMBOL_GPL (context_tracking_enabled); DEFINE_PER_CPU(struct context_tracking, context_tracking);
@@ -191,7 +191,7 @@ void __init context_tracking_cpu_set(int cpu)if (!per_cpu (context_tracking.active, cpu)) {per_cpu (context_tracking.active, cpu) = true; -static_key_slow_inc (&context_tracking_enabled); +static_branch_inc (&context_tracking_enabled); }if (initialized)
Signature · 1 line
2.4.3
Re: [PATCH 1/4] x86/entry/64: Fix irqflag tracing wrt context tracking
In reply to Andy LutomirskiQuoted 21 lines · Andy Lutomirski
Paolo pointed out that
enter_from_user_modecould be called while irqflags were traced as though IRQs were on.In principle, this could confuse lockdep. It doesn't cause any problems that I've seen in any configuration, but if I build with
CONFIG_DEBUG_LOCKDEP=y, enable anohz_fullCPU, and add code like:if (irqs_disabled()) { spin_lock(&something); spin_unlock(&something); }to the top of
enter_from_user_mode, then lockdep will complain without this fix. It seems that lockdep's irqflags sanity checks are too weak to detect this bug without forcing the issue.This patch adds one byte to normal kernels, and it's IMO a bit ugly. I haven't spotted a better way to do this yet, though. The issue is that we can't do
TRACE_IRQS_OFFuntil after SWAPGS (if needed), but we're also supposed to do it before calling C code.
Quoted 6 lines
An alternative approach would be to call
trace_hardirqs_offinenter_from_user_mode. That would be less code and would not bloat normal kernels at all, but it would be harder to see how the code worked.Signed-off-by Andy Lutomirski <[email protected]>
Re: [PATCH 2/4] context_tracking: Switch to new static_branch API
In reply to Andy LutomirskiQuoted 3 lines · Andy Lutomirski
This is much less error-prone than the old code.
Signed-off-by Andy Lutomirski <[email protected]>
Borislav Petkov
maintainerRe: [PATCH 1/4] x86/entry/64: Fix irqflag tracing wrt context tracking
In reply to Andy LutomirskiQuoted 12 lines · Andy Lutomirski
Paolo pointed out that
enter_from_user_modecould be called while irqflags were traced as though IRQs were on.In principle, this could confuse lockdep. It doesn't cause any problems that I've seen in any configuration, but if I build with
CONFIG_DEBUG_LOCKDEP=y, enable anohz_fullCPU, and add code like:if (irqs_disabled()) { spin_lock(&something); spin_unlock(&something); }
Quoted 8 lines
to the top of
enter_from_user_mode, then lockdep will complain without this fix. It seems that lockdep's irqflags sanity checks are too weak to detect this bug without forcing the issue.This patch adds one byte to normal kernels, and it's IMO a bit ugly. I haven't spotted a better way to do this yet, though. The issue is that we can't do
TRACE_IRQS_OFFuntil after SWAPGS (if needed), but we're also supposed to do it before calling C code.
I would not mind to have that explanation in the code itself so that people don't scratch heads why the duplicated TRACE_IRQS_OFF call.
Signature · 4 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
In reply to Andy LutomirskiQuoted 4 lines · Andy Lutomirski
Unfortunately, these only work if
HAVE_JUMP_LABEL. In principle, we could do some serious surgery on the core jump label infrastructure to keep the patch infrastructure available on x86 on all builds, but that's probably not worth it.
No, but we can be smarter about it. There is nothing which that asm entry code needs from linux/jump_label.h and asm/jump_label.h execpt STATIC_KEY_INIT_NOP. Something like the patch below should do the trick.
Thanks,
tglx
arch/x86/entry/calling.h +19 -0
@@ -232,3 +232,22 @@ For 32-bit we have the following convent#endif /* CONFIG_X86_64 */ +/* ASM jump label support */ +#if defined(CC_HAVE_ASM_GOTO ) && defined(CONFIG_JUMP_LABEL ) +#include <asm/jump_label.h> + + .macro STATIC_CALL_IF_ENABLED fun, key + 1: + jmp.d32 2f + call fun + .pushsection __jump_table, "aw" + _ASM_ALIGN + _ASM_PTR 1b, 2f, \key + .popsection + 2: + .endm +#else + .macro STATIC_CALL_IF_ENABLED fun, key + call fun + .endm +#endif
arch/x86/entry/entry_64.S +2 -2
@@ -510,7 +510,7 @@ END(irq_entries_start) */ SWAPGS #ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode + STATIC_CALL_IF_ENABLED enter_from_user_mode, context_tracking_enabled #endif 1:
@@ -1050,7 +1050,7 @@ ENTRY(error_entry) .Lerror_entry_from_usermode_after_swapgs: #ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode + STATIC_CALL_IF_ENABLED enter_from_user_mode, context_tracking_enabled #endif .Lerror_entry_done:
arch/x86/include/asm/jump_label.h +5 -4
@@ -1,10 +1,6 @@#ifndef _ASM_X86_JUMP_LABEL_H#define _ASM_X86_JUMP_LABEL_H -#ifndef __ASSEMBLY__ - -#include <linux/stringify.h> -#include <linux/types.h> #include <asm/nops.h> #include <asm/asm.h>
@@ -16,6 +12,11 @@# define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC#endif +#ifndef __ASSEMBLY__ + +#include <linux/stringify.h> +#include <linux/types.h> + static __always_inline bool arch_static_branch(struct static_key *key, bool branch) { asm_volatile_goto("1:"
Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
Quoted 8 lines · Thomas Gleixner
Quoted 4 lines · Andy Lutomirski
Unfortunately, these only work if
HAVE_JUMP_LABEL. In principle, we could do some serious surgery on the core jump label infrastructure to keep the patch infrastructure available on x86 on all builds, but that's probably not worth it.
Quoted 4 lines
No, but we can be smarter about it. There is nothing which that asm entry code needs from
linux/jump_label.handasm/jump_label.hexecptSTATIC_KEY_INIT_NOP. Something like the patch below should do the trick.
I like some bits of this. See below.
Quoted 10 lines
Thanks,
tglx
Index:
tip/arch/x86/entry/calling.h
===================================================================
arch/x86/entry/calling.h For 32-bit we have the following convent · line 239
Quoted 8 lines
arch/x86/entry/calling.h +5
-0@@ -232,3 +232,22 @@ For 32-bit we have the following convent#endif /* CONFIG_X86_64 */ +/* ASM jump label support */ +#if defined(CC_HAVE_ASM_GOTO ) && defined(CONFIG_JUMP_LABEL ) +#include <asm/jump_label.h> + + .macro STATIC_CALL_IF_ENABLED fun, key
I think we still need the "def" parameter. But maybe the "static call" is a good idea. (By giving 'def' a default value or omitting it entirely, it's too easy not to think about it, and that's a huge historical source of breakage and it's a good part of the reason for the new improved C API. At least these days I *think* we'll diagnose the problem on bootup instead of waiting for random breakage later.)
arch/x86/entry/calling.h For 32-bit we have the following convent · line 241
Quoted 2 lines
arch/x86/entry/calling.h +2
-0+ 1: + jmp.d32 2f
Old binutils will choke on this. But maybe no one has jump labels and old binutils.
arch/x86/entry/calling.h For 32-bit we have the following convent · line 252
Quoted 11 lines
arch/x86/entry/calling.h +11
-0+ call fun + .pushsection __jump_table, "aw" + _ASM_ALIGN + _ASM_PTR 1b, 2f, \key + .popsection + 2: + .endm +#else + .macro STATIC_CALL_IF_ENABLED fun, key + call fun + .endm
This could result in errors down the road, since this macro is really "static call if enabled or if the kernel is built without jump labels". enter_from_user_mode is special because it's already a no-op if context tracking is off, but I'm not sure that this oddity should leak into more generic code.
arch/x86/entry/entry_64.S END(irq_entries_start) · line 514
Quoted 12 lines
arch/x86/entry/calling.h +1
-0+#endif Index:
tip/arch/x86/entry/entry_64.S
===================================================================arch/x86/entry/entry_64.S +1
-1@@ -510,7 +510,7 @@ END(irq_entries_start) */ SWAPGS #ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode + STATIC_CALL_IF_ENABLED enter_from_user_mode, context_tracking_enabled #endif
This doesn't get rid of the ifdeffery, which I thought was a nice feature of my patch.
--Andy
Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
Quoted 13 lines · Andy Lutomirski
arch/x86/entry/calling.h For 32-bit we have the following convent · line 239
Quoted 5 lines · Thomas Gleixner
arch/x86/entry/calling.h +5
-0+/* ASM jump label support */ +#if defined(CC_HAVE_ASM_GOTO ) && defined(CONFIG_JUMP_LABEL ) +#include <asm/jump_label.h> + + .macro STATIC_CALL_IF_ENABLED fun, keyI think we still need the "def" parameter. But maybe the "static call" is a good idea. (By giving 'def' a default value or omitting it entirely, it's too easy not to think about it, and that's a huge historical source of breakage and it's a good part of the reason for the new improved C API. At least these days I *think* we'll diagnose the problem on bootup instead of waiting for random breakage later.)
Ok. That's easy to add :)
Quoted 5 lines
arch/x86/entry/calling.h For 32-bit we have the following convent · line 241
Quoted 2 lines
arch/x86/entry/calling.h +2
-0+ 1: + jmp.d32 2fOld binutils will choke on this. But maybe no one has jump labels and old binutils.
Good question.
Quoted 12 lines
arch/x86/entry/calling.h For 32-bit we have the following convent · line 252
Quoted 11 lines
arch/x86/entry/calling.h +11
-0+ call fun + .pushsection __jump_table, "aw" + _ASM_ALIGN + _ASM_PTR 1b, 2f, \key + .popsection + 2: + .endm +#else + .macro STATIC_CALL_IF_ENABLED fun, key + call fun + .endm
Quoted 5 lines
This could result in errors down the road, since this macro is really "static call if enabled or if the kernel is built without jump labels".
enter_from_user_modeis special because it's already a no-op if context tracking is off, but I'm not sure that this oddity should leak into more generic code.
Hmm. Maybe we need a better name for this macro.
Quoted 7 lines
Quoted 7 lines
+#endif
Index:tip/arch/x86/entry/entry_64.S
===================================================================arch/x86/entry/entry_64.S +0
-0@@ -510,7 +510,7 @@ END(irq_entries_start) */
Quoted 8 lines
arch/x86/entry/entry_64.S END(irq_entries_start) · line 514
Quoted 5 lines
arch/x86/entry/entry_64.S +1
-1SWAPGS #ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode + STATIC_CALL_IF_ENABLED enter_from_user_mode, context_tracking_enabled #endifThis doesn't get rid of the ifdeffery, which I thought was a nice feature of my patch.
Right. I was just too lazy to add another macro :)
My main point was to avoid the extra stuff for !HAVE_JUMP_LABEL and hide this in a header file.
Thanks,
tglx
Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
Quoted 61 lines · Thomas Gleixner
Quoted 13 lines · Andy Lutomirski
arch/x86/entry/calling.h For 32-bit we have the following convent · line 239
Quoted 5 lines · Thomas Gleixner
arch/x86/entry/calling.h +5
-0+/* ASM jump label support */ +#if defined(CC_HAVE_ASM_GOTO ) && defined(CONFIG_JUMP_LABEL ) +#include <asm/jump_label.h> + + .macro STATIC_CALL_IF_ENABLED fun, keyI think we still need the "def" parameter. But maybe the "static call" is a good idea. (By giving 'def' a default value or omitting it entirely, it's too easy not to think about it, and that's a huge historical source of breakage and it's a good part of the reason for the new improved C API. At least these days I *think* we'll diagnose the problem on bootup instead of waiting for random breakage later.)
Ok. That's easy to add :)
Quoted 5 lines
arch/x86/entry/calling.h For 32-bit we have the following convent · line 241
Quoted 2 lines
arch/x86/entry/calling.h +2
-0+ 1: + jmp.d32 2fOld binutils will choke on this. But maybe no one has jump labels and old binutils.
Good question.
Quoted 12 lines
arch/x86/entry/calling.h For 32-bit we have the following convent · line 252
Quoted 11 lines
arch/x86/entry/calling.h +11
-0+ call fun + .pushsection __jump_table, "aw" + _ASM_ALIGN + _ASM_PTR 1b, 2f, \key + .popsection + 2: + .endm +#else + .macro STATIC_CALL_IF_ENABLED fun, key + call fun + .endmQuoted 5 lines
This could result in errors down the road, since this macro is really "static call if enabled or if the kernel is built without jump labels".
enter_from_user_modeis special because it's already a no-op if context tracking is off, but I'm not sure that this oddity should leak into more generic code.Hmm. Maybe we need a better name for this macro.
Quoted 7 lines
Quoted 7 lines
+#endif
Index:tip/arch/x86/entry/entry_64.S
===================================================================arch/x86/entry/entry_64.S +0
-0@@ -510,7 +510,7 @@ END(irq_entries_start) */Quoted 8 lines
arch/x86/entry/entry_64.S END(irq_entries_start) · line 514
Quoted 5 lines
arch/x86/entry/entry_64.S +1
-1SWAPGS #ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode + STATIC_CALL_IF_ENABLED enter_from_user_mode, context_tracking_enabled #endifThis doesn't get rid of the ifdeffery, which I thought was a nice feature of my patch.
Quoted 5 lines
Right. I was just too lazy to add another macro :)
My main point was to avoid the extra stuff for !HAVE_JUMP_LABEL and hide this in a header file.
True. But I hid it in a header file, too, but it was just a different header file -- I had it all hidden away as CALL_ENTER_FROM_USER_MODE.
--Andy
Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
Quoted 3 lines · Andy Lutomirski
On Sat, Nov 7, 2015 at 8:58 AM, Thomas Gleixner <[email protected]> wrote:
True. But I hid it in a header file, too, but it was just a different header file -- I had it all hidden away asCALL_ENTER_FROM_USER_MODE.
It probably does not really make a difference :)
I just got triggered by you saying:
Quoted 1 line
Unfortunately, these only work if
HAVE_JUMP_LABEL....
Thanks,
tglx
Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
Quoted 10 lines · Thomas Gleixner
Quoted 3 lines · Andy Lutomirski
On Sat, Nov 7, 2015 at 8:58 AM, Thomas Gleixner <[email protected]> wrote:
True. But I hid it in a header file, too, but it was just a different header file -- I had it all hidden away asCALL_ENTER_FROM_USER_MODE.It probably does not really make a difference :)
I just got triggered by you saying:
Quoted 1 line
Unfortunately, these only work if
HAVE_JUMP_LABEL....
Yeah, I don't really like that either. I think that the real fix would be to compile in the runtime jump label bits unconditionally. Admittedly it would bloat the kernel image a little bit for !CONFIG_JUMP_LABEL or if build with an older gcc, and that's even less appropriate for 4.4 at this point. Peter?
--Andy
Re: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
In reply to Thomas GleixnerQuoted 11 lines · Thomas Gleixner
Quoted 3 lines · Andy Lutomirski
On Sat, Nov 7, 2015 at 8:58 AM, Thomas Gleixner <[email protected]> wrote:
True. But I hid it in a header file, too, but it was just a different header file -- I had it all hidden away asCALL_ENTER_FROM_USER_MODE.It probably does not really make a difference :)
I just got triggered by you saying:
Quoted 1 line
Unfortunately, these only work if
HAVE_JUMP_LABEL....
Looking again, my patch is crappy is one obvious respect: on non-HAVE_JUMP_LABEL kernels, I'm still generating a macro that will compile but do the wrong thing. I'll add better comments and the correct ifdef in v2. That will make it much harder to screw up without causing a compiler error.
--Andy
Re: [PATCH 1/4] x86/entry/64: Fix irqflag tracing wrt context tracking
In reply to Borislav PetkovQuoted 17 lines · Borislav Petkov
Quoted 16 lines · Andy Lutomirski
Paolo pointed out that
enter_from_user_modecould be called while irqflags were traced as though IRQs were on.In principle, this could confuse lockdep. It doesn't cause any problems that I've seen in any configuration, but if I build with
CONFIG_DEBUG_LOCKDEP=y, enable anohz_fullCPU, and add code like:if (irqs_disabled()) { spin_lock(&something); spin_unlock(&something); }to the top of
enter_from_user_mode, then lockdep will complain without this fix. It seems that lockdep's irqflags sanity checks are too weak to detect this bug without forcing the issue.
Quoted 8 lines
Quoted 4 lines
This patch adds one byte to normal kernels, and it's IMO a bit ugly. I haven't spotted a better way to do this yet, though. The issue is that we can't do
TRACE_IRQS_OFFuntil after SWAPGS (if needed), but we're also supposed to do it before calling C code.I would not mind to have that explanation in the code itself so that people don't scratch heads why the duplicated
TRACE_IRQS_OFFcall.
Done for v2.
--Andy
Re: [PATCH 4/4] x86/entry/64: Bypass enter_from_user_mode on non-context-tracking boots
In reply to Andy LutomirskiQuoted 57 lines · Andy Lutomirski
On
CONFIG_CONTEXT_TRACKINGkernels that have context tracking disabled at runtime (which includes most distro kernels), we still have the overhead of a call toenter_from_user_modein interrupt and exception entries.If jump labels are available, this uses the jump label infrastructure to skip the call.
Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/entry/calling.h | 15 +++++++++++++++ arch/x86/entry/entry_64.S | 8 ++------ 2 files changed, 17 insertions(+), 6 deletions(-)arch/x86/entry/calling.h +15
-0@@ -1,3 +1,5 @@ +#include <linux/jump_label.h> +/* x86 function call convention, 64-bit: @@ -232,3 +234,16 @@ For 32-bit we have the following conventions - kernel is built with#endif /* CONFIG_X86_64 */ +/* +* This does 'call enter_from_user_mode' unless we can avoid it based on +* kernel config or using the static jump infrastructure. +*/ +.macro CALL_ENTER_FROM_USER_MODE +#ifdef CONFIG_CONTEXT_TRACKING +#ifdef HAVE_JUMP_LABEL + STATIC_JUMP_IF_FALSE .Lafter_call_\@, context_tracking_enabled, def=0 +#endif +call enter_from_user_mode +.Lafter_call_\@: +#endif +.endmarch/x86/entry/entry_64.S +1
-3@@ -517,9 +517,7 @@ END(irq_entries_start) */ TRACE_IRQS_OFF -#ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode -#endif + CALL_ENTER_FROM_USER_MODE 1: /*
arch/x86/entry/entry_64.S ENTRY(error_entry) · line 1060
Quoted 8 lines
arch/x86/entry/entry_64.S +1
-3@@ -1058,9 +1056,7 @@ ENTRY(error_entry) .Lerror_entry_from_usermode_after_swapgs: TRACE_IRQS_OFF -#ifdef CONFIG_CONTEXT_TRACKING - call enter_from_user_mode -#endif + CALL_ENTER_FROM_USER_MODE ret
Yeah, so I only have a really minor syntactic nit abou tthis: it's OK to capitalize things when doing macros, but here I don't think capitalizing the called function name is good - I think the following would be more obvious:
CALL_enter_from_user_mode
this makes it really, really obvious (to me!) that this macro is a shortcut for:
call enter_from_user_mode
with some glue around it, and I could grep for 'enter_from_user_mode' immediately
- while grepping for ENTER_FROM_USER_MODE would miss the called function.
Thanks,
Ingo
Peter Zijlstra
maintainerRe: [PATCH 3/4] x86/asm: Add asm macros for static keys/jump labels
In reply to Andy LutomirskiQuoted 7 lines · Andy Lutomirski
Quoted 1 line
Quoted 1 line
Unfortunately, these only work if
HAVE_JUMP_LABEL....Yeah, I don't really like that either. I think that the real fix would be to compile in the runtime jump label bits unconditionally. Admittedly it would bloat the kernel image a little bit for !CONFIG_JUMP_LABEL or if build with an older gcc, and that's even less appropriate for 4.4 at this point. Peter?
That is a _lot_ of code for just one user. I'll bet the tiny people won't be happy about that.