Messages in this thread Patch in this message | | | Date | Thu, 28 May 1998 16:08:35 -0400 | From | Bill Hawes <> | Subject | minor patch for 2.1.103 tcp_do_sendmsg |
| |
Hi Dave,
I've attached a small patch that (hopefully) will provide a little performance boost for tcp. In tcp_do_sendmsg when the test is made to see whether additional memory can be allocated for an skb, it's possible that the extra amount would put the socket over its write limit. Then the next skb to be allocated might have to wait for the memory limit to fall.
But if the additional amount requested stays just below the socket's memory limit, then the next skb won't have to wait, and performance should be marginally better. I'm not sure whether this will happen often enough to be worthwhile, but the extra code is minimal, so it's worth a try.
The patch also makes a minor change to sock_kmalloc, to decrement the memory limit if the allocation fails.
Regards, Bill--- linux-2.1.103/net/ipv4/tcp.c.old Tue May 5 11:24:34 1998 +++ linux-2.1.103/net/ipv4/tcp.c Thu May 28 15:49:43 1998 @@ -804,22 +804,33 @@ if(copy > seglen) copy = seglen; - tmp = MAX_HEADER + sk->prot->max_header; + /* + * Calculate the minimum skb size to be allocated. + */ + tmp = MAX_HEADER + sk->prot->max_header + copy; queue_it = 0; + /* + * See if we can allocate more, but don't use up + * all of the space if it wouldn't otherwise. + */ if (copy < min(mss_now, tp->max_window >> 1) && !(flags & MSG_OOB)) { - tmp += min(mss_now, tp->max_window); + int more = min(mss_now, tp->max_window) - copy; + int space = sock_wspace(sk); + if (tmp < space && more >= space - tmp) { +printk("tcp_do_sendmsg: limiting extra %d to %d\n", more, space - tmp - 1); + more = space - tmp - 1; + } + tmp += more; /* What is happening here is that we want to - * tack on later members of the users iovec + * tack on later members of the user's iovec * if possible into a single frame. When we * leave this loop our caller checks to see if * we can send queued frames onto the wire. * See tcp_v[46]_sendmsg() for this. */ - queue_it = 1; - } else { - tmp += copy; + queue_it = (more > 0); } skb = sock_wmalloc(sk, tmp, 0, GFP_KERNEL); --- linux-2.1.103/net/core/sock.c.old Sun May 17 12:19:41 1998 +++ linux-2.1.103/net/core/sock.c Thu May 28 13:51:33 1998 @@ -564,15 +564,18 @@ void *sock_kmalloc(struct sock *sk, int size, int priority) { - void *mem = NULL; if (atomic_read(&sk->omem_alloc)+size < sysctl_optmem_max) { + void *mem; /* First do the add, to avoid the race if kmalloc * might sleep. */ atomic_add(size, &sk->omem_alloc); mem = kmalloc(size, priority); + if (mem) + return mem; + atomic_sub(size, &sk->omem_alloc); } - return mem; + return NULL; } void sock_kfree_s(struct sock *sk, void *mem, int size) | |