Mem issues in 2.6.9 (ever since 2.6.9-rc3) and possible cause

From: Javier Marcet
Date: Sat Oct 23 2004 - 08:02:29 EST


I've been following quite closely the development of 2.6.9, testing
every -rc release and a lot of -bk's.

Upon changing from 2.6.9-rc2 to 2.6.9-rc3 I began experiencing random
oom kills whenever a high memory i/o load took place.
This happened with plenty of free memory, and with whatever values I
used for vm.overcommit_ratio and vm.overcommit_memory
Doubling the physical RAM didn't change the situation either.

Having traced the problem to 2.6.9-rc3, I took a look at the differences
in memory handling between 2.6.9-rc2 and 2.6.9-rc3 and with the attached
patch I have no more oom kills. Not a single one.

I'm not saying everything within the patch is needed, not even that it's
the right thing to change. Nonetheless, 2.6.9 vanilla was unusable,
while this avoids those memory leaks.

Please, review and see what's wrong there :)


--
A mother takes twenty years to make a man of her boy, and another woman
makes a fool of him in twenty minutes.
a -- Frost

Javier Marcet <javier@xxxxxxxxxxx> --- linux-2.6.9-rc3/mm/highmem.c 2004-10-23 09:31:45.314459000 +0200
+++ linux-2.6.9-rc2/mm/highmem.c 2004-10-23 09:29:30.451961216 +0200
@@ -300,7 +300,6 @@
*/
vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;

- flush_dcache_page(tovec->bv_page);
bounce_copy_vec(tovec, vfrom);
}
}
@@ -407,7 +406,6 @@
if (rw == WRITE) {
char *vto, *vfrom;

- flush_dcache_page(from->bv_page);
vto = page_address(to->bv_page) + to->bv_offset;
vfrom = kmap(from->bv_page) + from->bv_offset;
memcpy(vto, vfrom, to->bv_len);
--- linux-2.6.9-rc3/mm/mempolicy.c 2004-10-23 09:31:45.321457936 +0200
+++ linux-2.6.9-rc2/mm/mempolicy.c 2004-10-23 09:29:30.474957720 +0200
@@ -132,7 +132,6 @@
unsigned long nlongs;
unsigned long endmask;

- --maxnode;
bitmap_zero(nodes, MAX_NUMNODES);
if (maxnode == 0 || !nmask)
return 0;
@@ -146,8 +145,6 @@
/* When the user specified more nodes than supported just check
if the non supported part is all zero. */
if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
- if (nlongs > PAGE_SIZE/sizeof(long))
- return -EINVAL;
for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
unsigned long t;
if (get_user(t, nmask + k))