FIXED: X much slower in 2.0.24 than in 1.2.13

Kevin Buhr (
06 Nov 1996 17:23:32 -0600 (Alan Cox) writes:
| Interesting. These only change the size of some fields. It may be a field
| size issue. Note that you dont want to run with that sock.h patch reversed
| as it lets people crash your machine..

Well, Alan, when you're right, you're right. ;)

The problem had nothing to do with the size of the "struct sock" or
breaking cache lines or anything of the sort.

Note that:
"unsigned short" - "int"
is a signed operation, while:
"unsigned int" - "int"
is an *unsigned* operation.

We have all sorts of comparisons and other binary operations on
"sk->sndbuf" and "sk->wmem_alloc" all over the place, and the latter
is of type "atomic_t" (which is "int" for the "i386" architecture).

In 2.0.23, these are signed operations, but in 2.0.24, they become
*unsigned*. One result is that "datagram_select" raises many false
alarms for sockets with "sk->prot==NULL", telling the process it can
write when there's actually no room. This is completely consistent
with the kernel profiles we've seen so far.

The most reasonable patch (which follows) seems to be to simply change
the "sndbuf" and "rcvbuf" members to (signed) "int"s. Does this break
anything else?

Kevin <>

* * *

diff -u -r1.1 -r1.1.1.1
--- linux/include/net/sock.h 1996/11/06 15:03:27 1.1
+++ linux/include/net/sock.h 1996/11/06 21:33:57
@@ -252,8 +252,8 @@
unsigned char max_ack_backlog;
unsigned char priority;
unsigned char debug;
- unsigned int rcvbuf;
- unsigned int sndbuf;
+ int rcvbuf;
+ int sndbuf;
unsigned short type;
unsigned char localroute; /* Route locally only */
#ifdef CONFIG_AX25