(add cc's)I thought for a bit more...
Subject: x86/mm: handle mm_fault_error() in kernel spaceWhy? I don't understand this part.
From: Andrey Vagin<avagin@xxxxxxxxxx>
mm_fault_error() should not execute oom-killer, if page fault occurs in
kernel space. E.g. in copy_from_user/copy_to_user.
It's not first oom, so I perfere don't caThis would happen if we find ourselves in OOM on a copy_to_user(), or aThis depends. OOM can choose another victim, and if it does we shouldn't
copy_from_user() which faults.
Without this patch, the kernels hangs up in copy_from_user, because OOM
killer sends SIG_KILL to current process,
return -EFAULT.
but it can't handle a signalYes. This is buggy.
while in syscall, then the kernel returns to copy_from_user, reexcute
current command and provokes page_fault again.
--- a/arch/x86/mm/fault.c~x86-mm-handle-mm_fault_error-in-kernel-spaceAt first glance, this is not optimal...
+++ a/arch/x86/mm/fault.c
@@ -827,6 +827,13 @@ mm_fault_error(struct pt_regs *regs, uns
unsigned long address, unsigned int fault)
{
if (fault& VM_FAULT_OOM) {
+ /* Kernel mode? Handle exceptions or die: */
+ if (!(error_code& PF_USER)) {
+ up_read(¤t->mm->mmap_sem);
+ no_context(regs, error_code, address);
+ return;
+ }
+
Perhaps I missed something, but afaics it is better to call
out_of_memory() first, then check if current was killed. In this case
no_context() is fine, we are not going to return to the user-mode.
IOW, what do you think about the (untested/uncompiled) patch below?
Oleg.
--- x/arch/x86/mm/fault.c
+++ x/arch/x86/mm/fault.c
@@ -829,6 +829,11 @@ mm_fault_error(struct pt_regs *regs, uns
{
if (fault& VM_FAULT_OOM) {
out_of_memory(regs, error_code, address);
+
+ if (!(error_code& PF_USER)&& fatal_signal_pending(current)) {
+ no_context(regs, error_code, address);
+ return;
+ }
} else {
if (fault& (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
VM_FAULT_HWPOISON_LARGE))