mm, arch: Complete pagefault_disable abstraction
Subsystems (19)
Peter Zijlstra
maintainerPATCH 1/1 mm, arch: Complete pagefault_disable abstraction
Subject: mm, arch: Complete pagefault_disable abstraction
From: Peter Zijlstra <[email protected]>
Date: Wed Oct 05 14:22:37 CEST 2011
Currently we already have pagefault_{disable,enable}() but they're nothing more than a glorified preempt_{disable,enable}().
For -rt we want to make pagefault_disable() regions preemptible and for that we need to complete the abstraction, replace the current in_atomic() tests that are relevant to pagefault_disable() usage with pagefault_disabled().
--- arch/alpha/mm/fault.c | 2 +- arch/arm/mm/fault.c | 2 +- arch/avr32/mm/fault.c | 2 +- arch/cris/mm/fault.c | 2 +- arch/frv/mm/fault.c | 2 +- arch/ia64/mm/fault.c | 2 +- arch/m32r/mm/fault.c | 2 +- arch/m68k/mm/fault.c | 2 +- arch/microblaze/mm/fault.c | 2 +- arch/mips/mm/fault.c | 2 +- arch/mn10300/mm/fault.c | 2 +- arch/parisc/mm/fault.c | 2 +- arch/powerpc/mm/fault.c | 2 +- arch/s390/mm/fault.c | 6 ++++-- arch/score/mm/fault.c | 2 +- arch/sh/mm/fault_32.c | 2 +- arch/sparc/mm/fault_32.c | 4 ++-- arch/sparc/mm/fault_64.c | 2 +- arch/tile/mm/fault.c | 2 +- arch/um/kernel/trap.c | 2 +- arch/unicore32/mm/fault.c | 2 +- arch/x86/mm/fault.c | 2 +- arch/xtensa/mm/fault.c | 2 +- include/linux/sched.h | 6 ++++++ mm/filemap.c | 2 +- 25 files changed, 34 insertions(+), 26 deletions(-)
arch/alpha/mm/fault.c +1 -1
@@ -107,7 +107,7 @@ do_page_fault(unsigned long address, uns/* If we're in an interrupt context, or have no user context, we must not take the fault. */ -if (!mm ||in_atomic ()) +if (!mm ||pagefault_disabled ()) goto no_context;#ifdef CONFIG_ALPHA_LARGE_VMALLOC
arch/arm/mm/fault.c +1 -1
@@ -293,7 +293,7 @@ do_page_fault(unsigned long addr, unsign* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;/*
arch/avr32/mm/fault.c +1 -1
@@ -81,7 +81,7 @@ asmlinkage void do_page_fault(unsigned l* If we're in an interrupt or have no user context, we must * not take the fault... */ -if (in_atomic () || !mm || regs->sr &SYSREG_BIT (GM )) +if (!mm || regs->sr &SYSREG_BIT (GM ) ||pagefault_disabled ()) goto no_context;local_irq_enable ();
arch/cris/mm/fault.c +1 -1
@@ -111,7 +111,7 @@ do_page_fault(unsigned long address, str* user context, we must not take the fault. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;down_read (&mm->mmap_sem);
arch/frv/mm/fault.c +1 -1
@@ -79,7 +79,7 @@ asmlinkage void do_page_fault(int datamm* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;down_read (&mm->mmap_sem);
arch/ia64/mm/fault.c +1 -1
@@ -89,7 +89,7 @@ ia64_do_page_fault (unsigned long addres/* * If we're in an interrupt or have no user context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;#ifdef CONFIG_VIRTUAL_MEM_MAP
arch/m32r/mm/fault.c +1 -1
@@ -115,7 +115,7 @@ asmlinkage void do_page_fault(struct pt_* If we're in an interrupt or have no user context or are running in an * atomic region then we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto bad_area_nosemaphore;/* When running in the kernel we expect faults to occur only to
arch/m68k/mm/fault.c +1 -1
@@ -85,7 +85,7 @@ int do_page_fault(struct pt_regs *regs,* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;down_read (&mm->mmap_sem);
arch/microblaze/mm/fault.c +1 -1
@@ -107,7 +107,7 @@ void do_page_fault(struct pt_regs *regs,if ((error_code &0x13 ) ==0x13 || (error_code &0x11 ) ==0x11 ) is_write =0 ; -if (unlikely (in_atomic () || !mm)) { +if (unlikely (!mm ||pagefault_disabled ())) {if (kernel_mode (regs)) goto bad_area_nosemaphore;
arch/mips/mm/fault.c +1 -1
@@ -88,7 +88,7 @@ asmlinkage void __kprobes do_page_fault(* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto bad_area_nosemaphore;down_read (&mm->mmap_sem);
arch/mn10300/mm/fault.c +1 -1
@@ -168,7 +168,7 @@ asmlinkage void do_page_fault(struct pt_* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;down_read (&mm->mmap_sem);
arch/parisc/mm/fault.c +1 -1
@@ -176,7 +176,7 @@ void do_page_fault(struct pt_regs *regs,unsigned long acc_type;int fault; -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;down_read (&mm->mmap_sem);
arch/powerpc/mm/fault.c +1 -1
@@ -162,7 +162,7 @@ int __kprobes do_page_fault(struct pt_re }#endif -if (in_atomic () || mm ==NULL ) { +if (!mm ||pagefault_disabled ()) {if (!user_mode (regs))return SIGSEGV ;/* in_atomic() in user mode is really bad,
arch/s390/mm/fault.c +4 -2
@@ -295,7 +295,8 @@ static inline int do_exception(struct pt* user context. */ fault =VM_FAULT_BADCONTEXT ; -if (unlikely (!user_space_fault (trans_exc_code) ||in_atomic () || !mm)) +if (unlikely (!user_space_fault (trans_exc_code) || + !mm ||pagefault_disabled ())) goto out; address = trans_exc_code & __FAIL_ADDR_MASK;
@@ -426,7 +427,8 @@ void __kprobes do_asce_exception(structstruct mm_struct *mm = current->mm;struct vm_area_struct *vma; -if (unlikely (!user_space_fault (trans_exc_code) ||in_atomic () || !mm)) +if (unlikely (!user_space_fault (trans_exc_code) || + !mm ||pagefault_disabled ())) goto no_context;down_read (&mm->mmap_sem);
arch/score/mm/fault.c +1 -1
@@ -72,7 +72,7 @@ asmlinkage void do_page_fault(struct pt_* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto bad_area_nosemaphore;down_read (&mm->mmap_sem);
arch/sh/mm/fault_32.c +1 -1
@@ -166,7 +166,7 @@ asmlinkage void __kprobes do_page_fault(* If we're in an interrupt, have no user context or are running * in an atomic region then we must not take the fault: */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;down_read (&mm->mmap_sem);
arch/sparc/mm/fault_32.c +2 -2
@@ -248,8 +248,8 @@ asmlinkage void do_sparc_fault(struct pt* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) - goto no_context; +if (!mm ||pagefault_disabled ()) + goto no_context;perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS ,1 , regs, address);
arch/sparc/mm/fault_64.c +1 -1
@@ -322,7 +322,7 @@ asmlinkage void __kprobes do_sparc64_fau* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto intr_or_no_mm;perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS ,1 , regs, address);
arch/tile/mm/fault.c +1 -1
@@ -346,7 +346,7 @@ static int handle_page_fault(struct pt_r* If we're in an interrupt, have no user context or are running in an * atomic region then we must not take the fault. */ -if (in_atomic () || !mm) { +if (!mm ||pagefault_disabled ()) { vma =NULL ;/* happy compiler */ goto bad_area_nosemaphore; }
arch/um/kernel/trap.c +1 -1
@@ -37,7 +37,7 @@ int handle_page_fault(unsigned long addr* If the fault was during atomic operation, don't take the fault, just * fail. */ -if (in_atomic ()) +if (!mm ||pagefault_disabled ()) goto out_nosemaphore;down_read (&mm->mmap_sem);
arch/unicore32/mm/fault.c +1 -1
@@ -225,7 +225,7 @@ static int do_pf(unsigned long addr, uns* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) +if (!mm ||pagefault_disabled ()) goto no_context;/*
arch/x86/mm/fault.c +1 -1
@@ -1084,7 +1084,7 @@ do_page_fault(struct pt_regs *regs, unsi* If we're in an interrupt, have no user context or are running * in an atomic region then we must not take the fault: */ -if (unlikely (in_atomic () || !mm)) { +if (unlikely (!mm ||pagefault_disabled ())) {bad_area_nosemaphore (regs, error_code, address);return ; }
arch/xtensa/mm/fault.c +1 -1
@@ -57,7 +57,7 @@ void do_page_fault(struct pt_regs *regs)/* If we're in an interrupt or have no user * context, we must not take the fault.. */ -if (in_atomic () || !mm) { +if (!mm ||pagefault_disabled ()) {bad_page_fault (regs, address,SIGSEGV );return ; }
include/linux/sched.h +6 -0
@@ -91,6 +91,7 @@ struct sched_param {#include <linux/latencytop.h> #include <linux/cred.h> #include <linux/llist.h> +#include <linux/hardirq.h> #include <asm/processor.h>
@@ -1575,6 +1576,11 @@ struct task_struct {/* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed (tsk) (&(tsk)->cpus_allowed) +static inline bool pagefault_disabled (void ) +{ +return in_atomic (); +} +/* * Priority of a process goes from 0..MAX_PRIO-1, valid RT * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
mm/filemap.c +1 -1
@@ -2061,7 +2061,7 @@ size_t iov_iter_copy_from_user_atomic(stchar *kaddr;size_t copied; -BUG_ON (!in_atomic ()); +BUG_ON (!pagefault_disabled ()); kaddr =kmap_atomic (page,KM_USER0 );if (likely (i->nr_segs ==1 )) {int left;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerQuoted 2 lines · On Wed, 05 Oct 2011 15:09:29 +0200 Peter Zijlstra <[email protected]> wrote:
Currently we already have pagefault_{disable,enable}() but they're nothing more than a glorified preempt_{disable,enable}().
That's not very accurate or useful. Unlike preempt_disable(), pagefault_disable() will raise the preempt count when CONFIG_PREEMPT=n.