Latest working kernel version: 2.6.11.12 Earliest failing kernel version: 2.6.25.7 Distribution: debian Hardware Environment: i386 32 bit 8 GB RAM Software Environment: Problem Description: kernel goes OOM with lots of sockets and traffic (latest working / earliest failing might be different, these were the versions I used) I started upgrading a bunch of machines in my nntp server farm to a recent kernel- 2.6.25.x. They were running 2.6.11.12 on 32 bits, and I upgraded them to 2.6.25.x on 64 bits. All went fine until I noticed a few machines didn't have a 64 bit capable processor, so I had to keep them on a 32 bit kernel. These are machines with dual xeons 3 Ghz and 8 GB of RAM. On the 32 bit machines I keep getting the error below, and a flood of these on a 9600 baud serial console essentially kills the machine: diablo invoked oom-killer: gfp_mask=0xd0, order=0, oomkilladj=0 Pid: 4459, comm: diablo Not tainted 2.6.25.7-rc1 #1 [<c0249660>] oom_kill_process+0x120/0x210 [<c0227ff8>] __capable+0x8/0x20 [<c0249898>] badness+0x128/0x1c0 [<c0249b1c>] out_of_memory+0x17c/0x1c0 [<c024bdf4>] __alloc_pages+0x254/0x350 [<c03b75ad>] tcp_sendmsg+0x5cd/0xb50 [<c0381672>] sock_aio_write+0xe2/0x100 [<c02681e7>] do_sync_write+0xc7/0x110 [<c0232f20>] autoremove_wake_function+0x0/0x50 [<c0268af3>] vfs_write+0x133/0x140 [<c0269131>] sys_write+0x41/0x70 [<c0202e5e>] syscall_call+0x7/0xb After some investigation, I found out that the values of /proc/sys/net/ipv4/tcp_mem are quite different between these two versions: 2.6.11.12: $ cat tcp_mem 98304 131072 196608 2.6.25: # cat tcp_mem 804672 1072896 1609344 Somwehere between 2.6.11.12 and 2.6.25, the calculation method of the tcp_mem array was changed. Now 1609344 pages is 6.5 GB, and that will ofcourse never fit in x86_32's low memory .. I posted this bug, and a patch, to the kernel and the netdev mailinglists, but got no reaction. So I'm filing it here. See: [PATCH] tcp.c: calculate tcp_mem based on low memory instead of all memory http://marc.info/?t=121380308200001&r=1&w=2 tcp_mem calculation wrong on x86_32 ? http://marc.info/?l=linux-netdev&m=121362441431941&w=2
Created attachment 16643 [details] tcp.c: calculate tcp_mem based on low memory instead of all memory Somwehere between 2.6.11.12 and 2.6.25, the calculation method of the tcp_mem array was changed. Now 1609344 pages is 6.5 GB, and that will ofcourse never fit in x86_32's low memory .. I am not quite sure what the correct solution is here, I think something like the patch below. Alternatively we could use the existing calculation but limit 'limit' to 3/4 of (totalram_pages - totalhigh_pages) if (totalhigh_pages > 0) ?
Patch has been added to -mm