Re: Perhaps a side effect regarding NMI returns

From: Linus Torvalds
Date: Tue Nov 29 2011 - 15:45:20 EST


On Tue, Nov 29, 2011 at 12:35 PM, Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:
>
> There may be a problem where you are profiling at a high frequency, and
> then hit this and suddenly, your high frequency NMIs are stopped till
> the next interrupt. If you are running at 100HZ, the next interrupt may
> not happen for 10ms, where we don't have an NMI triggered until then.

It could be much worse than that with no-HZ and some CPU-intensive
load with no timers. I don't think "sysret" enables NMI's either, so
return-to-user-mode may well leave NMI blocked.

So I really think this might be a real issue. And the simplest
approach seems to be to just remove the code. Something like the
attached (TOTALLY UNTESTED!) patch.

Hmm?

Linus
arch/x86/kernel/entry_64.S | 32 --------------------------------
1 files changed, 0 insertions(+), 32 deletions(-)

diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index faf8d5e74b0b..3819ea907339 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1489,46 +1489,14 @@ ENTRY(nmi)
movq %rsp,%rdi
movq $-1,%rsi
call do_nmi
-#ifdef CONFIG_TRACE_IRQFLAGS
- /* paranoidexit; without TRACE_IRQS_OFF */
- /* ebx: no swapgs flag */
- DISABLE_INTERRUPTS(CLBR_NONE)
testl %ebx,%ebx /* swapgs needed? */
jnz nmi_restore
- testl $3,CS(%rsp)
- jnz nmi_userspace
nmi_swapgs:
SWAPGS_UNSAFE_STACK
nmi_restore:
RESTORE_ALL 8
jmp irq_return
-nmi_userspace:
- GET_THREAD_INFO(%rcx)
- movl TI_flags(%rcx),%ebx
- andl $_TIF_WORK_MASK,%ebx
- jz nmi_swapgs
- movq %rsp,%rdi /* &pt_regs */
- call sync_regs
- movq %rax,%rsp /* switch stack for scheduling */
- testl $_TIF_NEED_RESCHED,%ebx
- jnz nmi_schedule
- movl %ebx,%edx /* arg3: thread flags */
- ENABLE_INTERRUPTS(CLBR_NONE)
- xorl %esi,%esi /* arg2: oldset */
- movq %rsp,%rdi /* arg1: &pt_regs */
- call do_notify_resume
- DISABLE_INTERRUPTS(CLBR_NONE)
- jmp nmi_userspace
-nmi_schedule:
- ENABLE_INTERRUPTS(CLBR_ANY)
- call schedule
- DISABLE_INTERRUPTS(CLBR_ANY)
- jmp nmi_userspace
CFI_ENDPROC
-#else
- jmp paranoid_exit
- CFI_ENDPROC
-#endif
END(nmi)

ENTRY(ignore_sysret)