===== net/ipv4/tcp.c 1.88 vs edited ===== --- 1.88/net/ipv4/tcp.c 2005-01-07 10:13:39 +11:00 +++ edited/net/ipv4/tcp.c 2005-01-15 08:31:52 +11:00 @@ -654,23 +654,31 @@ while (psize > 0) { struct sk_buff *skb = sk->sk_write_queue.prev; + int skb_mss; struct page *page = pages[poffset / PAGE_SIZE]; int copy, i; int offset = poffset % PAGE_SIZE; int size = min_t(size_t, psize, PAGE_SIZE - offset); - if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) { + if (!sk->sk_send_head) + goto new_segment; + + skb_mss = skb_netsize(skb) - skb_headroom(skb); + if (mss_now < skb_mss) + skb_mss = mss_now; + if ((copy = skb_mss - skb->len) <= 0) { new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; - skb = sk_stream_alloc_pskb(sk, 0, tp->mss_cache, + skb = sk_stream_alloc_pskb(sk, 0, mss_now, sk->sk_allocation); if (!skb) goto wait_for_memory; skb_entail(sk, tp, skb); copy = mss_now; + skb_mss = mss_now; } if (copy > size) @@ -702,14 +710,14 @@ if (!(psize -= copy)) goto out; - if (skb->len != mss_now || (flags & MSG_OOB)) + if (skb->len < skb_mss || (flags & MSG_OOB)) continue; if (forced_push(tp)) { tcp_mark_push(tp, skb); - __tcp_push_pending_frames(sk, tp, mss_now, TCP_NAGLE_PUSH); + __tcp_push_pending_frames(sk, tp, skb_mss, TCP_NAGLE_PUSH); } else if (skb == sk->sk_send_head) - tcp_push_one(sk, mss_now); + tcp_push_one(sk, skb_mss); continue; wait_for_sndbuf: ===== include/linux/skbuff.h 1.58 vs edited ===== --- 1.58/include/linux/skbuff.h 2004-12-28 16:24:42 +11:00 +++ edited/include/linux/skbuff.h 2005-01-14 22:30:45 +11:00 @@ -1124,6 +1124,11 @@ return buffer; } +static inline int skb_netsize(const struct sk_buff *skb) +{ + return skb->truesize - sizeof(struct sk_buff); +} + extern void skb_init(void); extern void skb_add_mtu(int mtu);