From: Christian Leber Ky box (2.6.9-final) was yesterday completly stalled (mouse movable and stupid loadmeter was still working) after starting mutt and was swapping for half an hour until I sent SIGTERM to all processes. I suspect it was a 2 GB big galeon process that was the problem. I think sysrq needs a key to call oom_kill manually. Signed-off-by: Andrew Morton --- 25-akpm/Documentation/sysrq.txt | 2 ++ 25-akpm/drivers/char/sysrq.c | 16 ++++++++++++++-- 25-akpm/include/linux/swap.h | 1 + 25-akpm/mm/oom_kill.c | 15 +++++++-------- 4 files changed, 24 insertions(+), 10 deletions(-) diff -puN Documentation/sysrq.txt~make-sysrq-f-call-oom_kill Documentation/sysrq.txt --- 25/Documentation/sysrq.txt~make-sysrq-f-call-oom_kill 2004-11-09 01:18:24.053537280 -0800 +++ 25-akpm/Documentation/sysrq.txt 2004-11-09 01:18:24.062535912 -0800 @@ -73,6 +73,8 @@ On all - write a character to /proc/sys it so that only emergency messages like PANICs or OOPSes would make it to your console.) +'f' - Will call oom_kill to kill a memory hog process + 'e' - Send a SIGTERM to all processes, except for init. 'i' - Send a SIGKILL to all processes, except for init. diff -puN drivers/char/sysrq.c~make-sysrq-f-call-oom_kill drivers/char/sysrq.c --- 25/drivers/char/sysrq.c~make-sysrq-f-call-oom_kill 2004-11-09 01:18:24.055536976 -0800 +++ 25-akpm/drivers/char/sysrq.c 2004-11-09 01:18:24.063535760 -0800 @@ -31,7 +31,7 @@ #include #include #include /* for fsync_bdev() */ - +#include #include #include @@ -202,6 +202,18 @@ static struct sysrq_key_op sysrq_term_op .action_msg = "Terminate All Tasks", }; +static void sysrq_handle_moom(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + oom_kill(); +// console_loglevel = 8; +} +static struct sysrq_key_op sysrq_moom_op = { + .handler = sysrq_handle_moom, + .help_msg = "Full", + .action_msg = "Manual OOM execution", +}; + static void sysrq_handle_kill(int key, struct pt_regs *pt_regs, struct tty_struct *tty) { @@ -248,7 +260,7 @@ static struct sysrq_key_op *sysrq_key_ta /* c */ NULL, /* d */ NULL, /* e */ &sysrq_term_op, -/* f */ NULL, +/* f */ &sysrq_moom_op, /* g */ NULL, /* h */ NULL, /* i */ &sysrq_kill_op, diff -puN include/linux/swap.h~make-sysrq-f-call-oom_kill include/linux/swap.h --- 25/include/linux/swap.h~make-sysrq-f-call-oom_kill 2004-11-09 01:18:24.056536824 -0800 +++ 25-akpm/include/linux/swap.h 2004-11-09 01:18:24.063535760 -0800 @@ -149,6 +149,7 @@ struct swap_list_t { /* linux/mm/oom_kill.c */ extern void out_of_memory(int gfp_mask); +void oom_kill(void); /* linux/mm/memory.c */ extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct *); diff -puN mm/oom_kill.c~make-sysrq-f-call-oom_kill mm/oom_kill.c --- 25/mm/oom_kill.c~make-sysrq-f-call-oom_kill 2004-11-09 01:18:24.058536520 -0800 +++ 25-akpm/mm/oom_kill.c 2004-11-09 01:18:24.064535608 -0800 @@ -184,7 +184,7 @@ static struct mm_struct *oom_kill_task(t * OR try to be smart about which process to kill. Note that we * don't have to be perfect here, we just have to be good. */ -static void oom_kill(void) +void oom_kill(void) { struct mm_struct *mm; struct task_struct *g, *p, *q; @@ -214,13 +214,6 @@ retry: printk(KERN_INFO "Fixed up OOM kill of mm-less task\n"); read_unlock(&tasklist_lock); mmput(mm); - - /* - * Make kswapd go out of the way, so "p" has a good chance of - * killing itself before someone else gets the chance to ask - * for more memory. - */ - yield(); return; } @@ -284,6 +277,12 @@ void out_of_memory(int gfp_mask) /* oom_kill() sleeps */ spin_unlock(&oom_lock); oom_kill(); + /* + * Make kswapd go out of the way, so "p" has a good chance of + * killing itself before someone else gets the chance to ask + * for more memory. + */ + yield(); spin_lock(&oom_lock); reset: _