Re: Allocation of too much memory hangs system, kernel 2.2.*

Andrea Arcangeli (andrea@suse.de)
Tue, 1 Jun 1999 18:04:48 +0200 (CEST)


On Tue, 1 Jun 1999, Urban Widmark wrote:

>I don't remember if I reported it or not, since I thought the "OOM"
>problem was well known and left for future Linux versions.

I thought it was just fine with 2.2.x.

Could you check if the lockup goes away with this patch below against
clean 2.2.9? (... really I never tried it on a clean 2.2.9 but should work
really fine there too :) The problem seems to be only a too high
runtime-complexity of the page-freeing code. This patch will reduce the
swapout complexity of a good bit.

Index: linux//arch/i386/mm/fault.c
===================================================================
RCS file: /var/cvs/linux/arch/i386/mm/fault.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 fault.c
--- linux//arch/i386/mm/fault.c 1999/01/18 01:28:56 1.1.1.1
+++ linux//arch/i386/mm/fault.c 1999/06/01 15:29:48
@@ -265,7 +265,7 @@
tsk->tss.cr2 = address;
tsk->tss.error_code = error_code;
tsk->tss.trap_no = 14;
- force_sig(SIGBUS, tsk);
+ oom(tsk);

/* Kernel mode? Handle exceptions or die */
if (!(error_code & 4))
Index: linux//mm/vmscan.c
===================================================================
RCS file: /var/cvs/linux/mm/vmscan.c,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 vmscan.c
--- linux//mm/vmscan.c 1999/04/28 20:46:48 1.1.1.6
+++ linux//mm/vmscan.c 1999/06/01 15:31:12
@@ -308,7 +308,8 @@
static int swap_out(unsigned int priority, int gfp_mask)
{
struct task_struct * p, * pbest;
- int counter, assign, max_cnt;
+ int assign = 0, counter;
+ unsigned long max_cnt;

/*
* We make one or two passes through the task list, indexed by
@@ -327,11 +328,8 @@
counter = nr_tasks / (priority+1);
if (counter < 1)
counter = 1;
- if (counter > nr_tasks)
- counter = nr_tasks;

for (; counter >= 0; counter--) {
- assign = 0;
max_cnt = 0;
pbest = NULL;
select:
@@ -343,7 +341,7 @@
if (p->mm->rss <= 0)
continue;
/* Refresh swap_cnt? */
- if (assign)
+ if (assign == 1)
p->mm->swap_cnt = p->mm->rss;
if (p->mm->swap_cnt > max_cnt) {
max_cnt = p->mm->swap_cnt;
@@ -361,6 +359,8 @@

if (swap_out_process(pbest, gfp_mask))
return 1;
+ if (assign == 1)
+ assign = 2;
}
out:
return 0;

If there's nothing to swapout in the VM there's no need to continue trying
nr_tasks times on the whole VM. The first part of the patch is nicer
(printk oom task) and will make sure that nobody will trap the sigbus (if
an attacker will register a sigbus handler and then will go oom...).

If the patch above is not enough, I would like to know if you can
reproduce in:

ftp://e-mind.com/pub/andrea/kernel/pre-2.3.4-2_andrea2.bz2

(against pre-2.3.4-2 of course :), since here the shrink_mmap
runtime-complexity is reduced near zero using my pagemap-lru.

BTW, pre-2.3.4-2_andrea2 also seems to fix completly the `cp /dev/zero
/tmp` I/O overload this time without harming too much write performances
and I am quite happy with it now.

Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/