From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755212Ab1HOPy2 (ORCPT ); Mon, 15 Aug 2011 11:54:28 -0400 Received: from mail-vw0-f46.google.com ([209.85.212.46]:46598 "EHLO mail-vw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755194Ab1HOPyX (ORCPT ); Mon, 15 Aug 2011 11:54:23 -0400 From: Frederic Weisbecker To: LKML Cc: Frederic Weisbecker , Andrew Morton , Anton Blanchard , Avi Kivity , Ingo Molnar , Lai Jiangshan , "Paul E . McKenney" , Paul Menage , Peter Zijlstra , Stephen Hemminger , Thomas Gleixner , Tim Pepper Subject: [PATCH 30/32] x86: Exception hooks for nohz cpusets Date: Mon, 15 Aug 2011 17:52:27 +0200 Message-Id: <1313423549-27093-31-git-send-email-fweisbec@gmail.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1313423549-27093-1-git-send-email-fweisbec@gmail.com> References: <1313423549-27093-1-git-send-email-fweisbec@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add necessary hooks to x86 exception for nohz cpusets support. It includes traps, page fault, debug exceptions, etc... TODO: handle do_notify_resume(). Not an exception but it's executed at the end of the syscall/irq path so it's beyond our hooks but shouldn't be considered as userspace code. Signed-off-by: Frederic Weisbecker Cc: Andrew Morton Cc: Anton Blanchard Cc: Avi Kivity Cc: Ingo Molnar Cc: Lai Jiangshan Cc: Paul E . McKenney Cc: Paul Menage Cc: Peter Zijlstra Cc: Stephen Hemminger Cc: Thomas Gleixner Cc: Tim Pepper --- arch/x86/Kconfig | 1 + arch/x86/kernel/traps.c | 22 +++++++++++++++------- arch/x86/mm/fault.c | 13 +++++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 67979f4..1b12b1a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -69,6 +69,7 @@ config X86 select IRQ_FORCED_THREADING select USE_GENERIC_SMP_HELPERS if SMP select HAVE_BPF_JIT if (X86_64 && NET) + select HAVE_CPUSETS_NO_HZ config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index b9b6716..d98f2f4 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -456,24 +457,28 @@ void restart_nmi(void) /* May run on IST stack. */ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) { + tick_nohz_enter_exception(regs); + #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) - return; + goto exit; #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */ #ifdef CONFIG_KPROBES if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) - return; + goto exit; #else if (notify_die(DIE_TRAP, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) - return; + goto exit; #endif preempt_conditional_sti(regs); do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); preempt_conditional_cli(regs); +exit: + tick_nohz_exit_exception(regs); } #ifdef CONFIG_X86_64 @@ -534,6 +539,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) unsigned long dr6; int si_code; + tick_nohz_enter_exception(regs); + get_debugreg(dr6, 6); /* Filter out all the reserved bits which are preset to 1 */ @@ -549,7 +556,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) /* Catch kmemcheck conditions first of all! */ if ((dr6 & DR_STEP) && kmemcheck_trap(regs)) - return; + goto exit; /* DR6 may or may not be cleared by the CPU */ set_debugreg(0, 6); @@ -564,7 +571,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code, SIGTRAP) == NOTIFY_STOP) - return; + goto exit; /* It's safe to allow irq's after DR6 has been saved */ preempt_conditional_sti(regs); @@ -573,7 +580,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); preempt_conditional_cli(regs); - return; + goto exit; } /* @@ -593,7 +600,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) send_sigtrap(tsk, regs, error_code, si_code); preempt_conditional_cli(regs); - return; +exit: + tick_nohz_exit_exception(regs); } /* diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 4d09df0..aa2e2e3 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -13,6 +13,7 @@ #include /* perf_sw_event */ #include /* hstate_index_to_shift */ #include /* prefetchw */ +#include #include /* dotraplinkage, ... */ #include /* pgd_*(), ... */ @@ -971,8 +972,8 @@ static int fault_in_kernel_space(unsigned long address) * and the problem, and then passes it off to one of the appropriate * routines. */ -dotraplinkage void __kprobes -do_page_fault(struct pt_regs *regs, unsigned long error_code) +static void __kprobes +__do_page_fault(struct pt_regs *regs, unsigned long error_code) { struct vm_area_struct *vma; struct task_struct *tsk; @@ -1180,3 +1181,11 @@ good_area: up_read(&mm->mmap_sem); } + +dotraplinkage void __kprobes +do_page_fault(struct pt_regs *regs, unsigned long error_code) +{ + tick_nohz_enter_exception(regs); + __do_page_fault(regs, error_code); + tick_nohz_exit_exception(regs); +} -- 1.7.5.4