For is_vm_hugetlb_page() in the pagefault oom handler, I think it should
default to killing current as we did previously until that's worked out
(and as some architectures like ia64 and powerpc still do). In fact,
pagefault ooms should probably always default to killing current if its
killable.
That's easy to test in the oom handler, we can default to killing current
but then kill another task if it is unkillable:
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -696,15 +696,23 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
}
/*
- * The pagefault handler calls here because it is out of memory, so kill a
- * memory-hogging task. If a populated zone has ZONE_OOM_LOCKED set, a parallel
- * oom killing is already in progress so do nothing. If a task is found with
- * TIF_MEMDIE set, it has been killed so do nothing and allow it to exit.
+ * The pagefault handler calls here because it is out of memory, so kill current
+ * by default. If it's unkillable, then fallback to killing a memory-hogging
+ * task. If a populated zone has ZONE_OOM_LOCKED set, a parallel oom killing is
+ * already in progress so do nothing. If a task is found with TIF_MEMDIE set,
+ * it has been killed so do nothing and allow it to exit.
*/
void pagefault_out_of_memory(void)
{
+ unsigned long totalpages;
+ int err;
+
if (!try_set_system_oom())
return;
- out_of_memory(NULL, 0, 0, NULL);
+ constrained_alloc(NULL, 0, NULL, &totalpages);
+ err = oom_kill_process(current, 0, 0, 0, totalpages, NULL,
+ "Out of memory (pagefault)"))
+ if (err)
+ out_of_memory(NULL, 0, 0, NULL);
clear_system_oom();
}
We'll need to convert the architectures that still only issue a SIGKILL to
current to use pagefault_out_of_memory() before OOM_DISABLE is fully
respected across the kernel, though.
--