From: Will Schmidt Date: Tue, 16 Oct 2007 08:24:18 +0000 (-0700) Subject: During VM oom condition, kill all threads in process group X-Git-Tag: v2.6.24-rc1~1240 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=dcca2bde4f86a14d3291660bede8f1844fe2b3df;p=linux-2.6-omap-h63xx.git During VM oom condition, kill all threads in process group We have had complaints where a threaded application is left in a bad state after one of it's threads is killed when we hit a VM: out_of_memory condition. Killing just one of the process threads can leave the application in a bad state, whereas killing the entire process group would allow for the application to restart, or be otherwise handled, and makes it very obvious that something has gone wrong. This change allows the entire process group to be taken down, rather than just the one thread. Signed-off-by: Will Schmidt Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Russell King Cc: Ian Molton Cc: Haavard Skinnemoen Cc: Mikael Starvik Cc: David Howells Cc: Andi Kleen Cc: "Luck, Tony" Cc: Hirokazu Takata Cc: Geert Uytterhoeven Cc: Roman Zippel Cc: Ralf Baechle Cc: Kyle McMartin Cc: Matthew Wilcox Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Paul Mundt Cc: Kazumoto Kojima Cc: Richard Curnow Cc: William Lee Irwin III Cc: "David S. Miller" Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index a0e18da594d..25154df3055 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -197,7 +197,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, current->comm, current->pid); if (!user_mode(regs)) goto no_context; - do_exit(SIGKILL); + do_group_exit(SIGKILL); do_sigbus: /* Send a sigbus, regardless of whether we were in kernel diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 846cce48e2b..59ed1d05b71 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -266,7 +266,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * the page fault gracefully. */ printk("VM: killing process %s\n", tsk->comm); - do_exit(SIGKILL); + do_group_exit(SIGKILL); return 0; } if (fault & VM_FAULT_SIGBUS) { diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index ae2d2c593b2..11472f8701b 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -216,7 +216,7 @@ out_of_memory: } printk("VM: Killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 8672ab7d797..8aab8143069 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -360,7 +360,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c index 6798fa0257b..05093d41d98 100644 --- a/arch/frv/mm/fault.c +++ b/arch/frv/mm/fault.c @@ -259,7 +259,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (user_mode(__frame)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 9150ffaff9e..32f26253c4e 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -281,6 +281,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re } printk(KERN_CRIT "VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; } diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c index 676a1c443d2..70a766aad3e 100644 --- a/arch/m32r/mm/fault.c +++ b/arch/m32r/mm/fault.c @@ -278,7 +278,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (error_code & ACE_USERMODE) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index 578b48f47b9..eaa61868115 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -188,7 +188,7 @@ out_of_memory: printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); no_context: current->thread.signo = SIGBUS; diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 521771b373d..5699c7713e2 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -180,7 +180,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 7899ab87785..1c091b415cd 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -263,6 +263,6 @@ no_context: up_read(&mm->mmap_sem); printk(KERN_CRIT "VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; } diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index b98244e277f..94913ddcf76 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -297,7 +297,7 @@ out_of_memory: } printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); return SIGKILL; do_sigbus: diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 4c1ac341ec8..14c241ccdd4 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -218,7 +218,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code, } printk("VM: killing process %s\n", tsk->comm); if (regs->psw.mask & PSW_MASK_PSTATE) - do_exit(SIGKILL); + do_group_exit(SIGKILL); do_no_context(regs, error_code, address); return 0; } diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 04a39aa7f1f..4729668ce5b 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -214,7 +214,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c index 0d069d82141..dd81c669c79 100644 --- a/arch/sh64/mm/fault.c +++ b/arch/sh64/mm/fault.c @@ -334,7 +334,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index 50747fe4435..e4d9c8e19df 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c @@ -369,7 +369,7 @@ out_of_memory: up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); if (from_user) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 9f7740eee8d..e2027f27c0f 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -463,7 +463,7 @@ out_of_memory: up_read(&mm->mmap_sem); printk("VM: killing process %s\n", current->comm); if (!(regs->tstate & TSTATE_PRIV)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto handle_kernel_fault; intr_or_no_mm: diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index be72c2a5b03..c686ae20fd6 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c @@ -593,7 +593,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (error_code & 4) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index 45d28f217c0..2f842859948 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -152,7 +152,7 @@ out_of_memory: } printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) - do_exit(SIGKILL); + do_group_exit(SIGKILL); bad_page_fault(regs, address, SIGKILL); return;