From: Hugh Dickins The current behaviour is that once swapoff has filled memory, other tasks get OOMkilled one by one until swapoff completes, or more likely hangs. It is better that swapoff be the first choice for OOMkill. The patch changes the oom-killer so that it will kill off any currently-swapoff instance before killing any other task. 25-akpm/include/linux/sched.h | 1 + 25-akpm/mm/oom_kill.c | 2 ++ 25-akpm/mm/swapfile.c | 2 ++ 3 files changed, 5 insertions(+) diff -puN include/linux/sched.h~oomkill-swapoff include/linux/sched.h --- 25/include/linux/sched.h~oomkill-swapoff Thu Apr 17 16:23:52 2003 +++ 25-akpm/include/linux/sched.h Thu Apr 17 16:23:52 2003 @@ -472,6 +472,7 @@ do { if (atomic_dec_and_test(&(tsk)->usa #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ +#define PF_SWAPOFF 0x00080000 /* I am in swapoff */ #if CONFIG_SMP extern void set_cpus_allowed(task_t *p, unsigned long new_mask); diff -puN mm/oom_kill.c~oomkill-swapoff mm/oom_kill.c --- 25/mm/oom_kill.c~oomkill-swapoff Thu Apr 17 16:23:52 2003 +++ 25-akpm/mm/oom_kill.c Thu Apr 17 16:23:52 2003 @@ -129,6 +129,8 @@ static struct task_struct * select_bad_p chosen = p; maxpoints = points; } + if (p->flags & PF_SWAPOFF) + return p; } while_each_thread(g, p); return chosen; diff -puN mm/swapfile.c~oomkill-swapoff mm/swapfile.c --- 25/mm/swapfile.c~oomkill-swapoff Thu Apr 17 16:23:52 2003 +++ 25-akpm/mm/swapfile.c Thu Apr 17 16:23:52 2003 @@ -1059,7 +1059,9 @@ asmlinkage long sys_swapoff(const char _ total_swap_pages -= p->pages; p->flags &= ~SWP_WRITEOK; swap_list_unlock(); + current->flags |= PF_SWAPOFF; err = try_to_unuse(type); + current->flags &= ~PF_SWAPOFF; if (err) { /* re-insert swap space back into swap_list */ swap_list_lock(); _