[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4B251CE4.9080401@gmail.com>
Date: Sun, 13 Dec 2009 17:57:08 +0100
From: Eric Dumazet <eric.dumazet@...il.com>
To: Yinghai Lu <yinghai@...nel.org>
CC: David Miller <davem@...emloft.net>, mingo@...e.hu, sri@...ibm.com,
herbert@...dor.apana.org.au, torvalds@...ux-foundation.org,
sjayaraman@...e.de, linux-kernel@...r.kernel.org,
netdev@...r.kernel.org
Subject: Re: nfs broken in net-next? -- now in mainline -- bisected: d9f5950f90292f7cc42834338dfd5f44dc4cc4ca
Le 13/12/2009 03:41, Yinghai Lu a écrit :
>
>>> cause the problem: nfs mount fail.
>>>
>>> the setup is:
>>> 64bit kernel, have all needed drivers in kernel, and boot with
>>> ip=dhcp, root disk is 256M ramdisk.
>>> then try to mount nfs....
>>>
>>
>> change entries default value from 65536 to 256,
>> nfs mount will work.
>>
> interesting:
>
> m:~/dump # grep UDP dmesg.txt
> [ 28.996034] UDP hash table entries: 65536 (order: 11, 10485760 bytes)
> [ 29.032364] UDP-Lite hash table entries: 65536 (order: 11, 10485760 bytes)
>
> will not work
>
> but 32768 will work.
Thanks a lot for this work Yinghai !
This last bit helped me a lot ...
Hmm, udp_lib_get_port() assumes it can loop at least one time in :
for (last = first + udptable->mask + 1;
first != last;
first++) {
// unit_work
}
but if udptable->mask == 65535, loop is not entered at all (since last == first)
We should convert it to a do { } while(...); construct, or use 32bit variables
and (u16) casts.
Thanks
[PATCH] udp: udp_lib_get_port() fix
Now we can have a large udp hash table, udp_lib_get_port() loop
should be converted to a do {} while (cond) form,
or we dont enter it at all if hash table size is exactly 65536.
Reported-by: Yinghai Lu <yinghai@...nel.org>
Signed-off-by: Eric Dumazet <eric.dumazet@...il.com>
---
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 1f95348..f0126fd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -216,9 +216,8 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
* force rand to be an odd multiple of UDP_HTABLE_SIZE
*/
rand = (rand | 1) * (udptable->mask + 1);
- for (last = first + udptable->mask + 1;
- first != last;
- first++) {
+ last = first + udptable->mask + 1;
+ do {
hslot = udp_hashslot(udptable, net, first);
bitmap_zero(bitmap, PORTS_PER_CHAIN);
spin_lock_bh(&hslot->lock);
@@ -238,7 +237,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
snum += rand;
} while (snum != first);
spin_unlock_bh(&hslot->lock);
- }
+ } while (++first != last);
goto fail;
} else {
hslot = udp_hashslot(udptable, net, snum);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists