| From fb8863a66463d0d1928e6115adbfbd62f5188366 Mon Sep 17 00:00:00 2001 |
| From: Andi Kleen <ak@suse.de> |
| Date: Fri, 3 Jul 2009 08:44:12 -0500 |
| Subject: [PATCH] x86: Don't disable preemption in exception handlers without IST |
| |
| commit 4c67d0b3e40f01c4b681994ac64bf8f83e6caad9 in tip. |
| |
| Some of the exception handlers that run on an IST in a normal kernel |
| still disable preemption. This causes might_sleep warning when sending signals |
| for debugging in PREEMPT-RT because sending signals can take a lock. |
| Since the ISTs are disabled now for those don't disable the preemption. |
| |
| This completes the remove IST patch I sent some time ago and fixes |
| another case where using gdb caused warnings. |
| |
| Also it will likely improve latency a little bit. |
| |
| Signed-off-by: Andi Kleen <ak@suse.de> |
| Signed-off-by: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c |
| index 4cfa8fd..30ba8fd 100644 |
| --- a/arch/x86/kernel/traps.c |
| +++ b/arch/x86/kernel/traps.c |
| @@ -88,9 +88,10 @@ static inline void conditional_sti(struct pt_regs *regs) |
| local_irq_enable(); |
| } |
| |
| -static inline void preempt_conditional_sti(struct pt_regs *regs) |
| +static inline void preempt_conditional_sti(struct pt_regs *regs, int stack) |
| { |
| - inc_preempt_count(); |
| + if (stack) |
| + inc_preempt_count(); |
| if (regs->flags & X86_EFLAGS_IF) |
| local_irq_enable(); |
| } |
| @@ -101,11 +102,12 @@ static inline void conditional_cli(struct pt_regs *regs) |
| local_irq_disable(); |
| } |
| |
| -static inline void preempt_conditional_cli(struct pt_regs *regs) |
| +static inline void preempt_conditional_cli(struct pt_regs *regs, int stack) |
| { |
| if (regs->flags & X86_EFLAGS_IF) |
| local_irq_disable(); |
| - dec_preempt_count(); |
| + if (stack) |
| + dec_preempt_count(); |
| } |
| |
| #ifdef CONFIG_X86_32 |
| @@ -232,9 +234,9 @@ dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) |
| if (notify_die(DIE_TRAP, "stack segment", regs, error_code, |
| 12, SIGBUS) == NOTIFY_STOP) |
| return; |
| - preempt_conditional_sti(regs); |
| + preempt_conditional_sti(regs, STACKFAULT_STACK); |
| do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); |
| - preempt_conditional_cli(regs); |
| + preempt_conditional_cli(regs, STACKFAULT_STACK); |
| } |
| |
| dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) |
| @@ -470,9 +472,9 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) |
| return; |
| #endif |
| |
| - preempt_conditional_sti(regs); |
| + preempt_conditional_sti(regs, DEBUG_STACK); |
| do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); |
| - preempt_conditional_cli(regs); |
| + preempt_conditional_cli(regs, DEBUG_STACK); |
| } |
| |
| #ifdef CONFIG_X86_64 |
| @@ -566,7 +568,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) |
| return; |
| |
| /* It's safe to allow irq's after DR6 has been saved */ |
| - preempt_conditional_sti(regs); |
| + preempt_conditional_sti(regs, DEBUG_STACK); |
| |
| if (regs->flags & X86_VM_MASK) { |
| handle_vm86_trap((struct kernel_vm86_regs *) regs, |
| @@ -589,7 +591,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) |
| si_code = get_si_code(tsk->thread.debugreg6); |
| if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) |
| send_sigtrap(tsk, regs, error_code, si_code); |
| - preempt_conditional_cli(regs); |
| + preempt_conditional_cli(regs, DEBUG_STACK); |
| |
| return; |
| } |
| -- |
| 1.7.1.1 |
| |