]> git.hungrycats.org Git - linux/commitdiff
[TCP]: Kill tso_{factor,mss}.
authorDavid S. Miller <davem@nuts.davemloft.net>
Thu, 30 Sep 2004 13:58:53 +0000 (06:58 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Thu, 30 Sep 2004 13:58:53 +0000 (06:58 -0700)
We can just use skb_shinfo(skb)->tso_{segs,size}
directly.  This also allows us to kill the
hack zone code in ip_output.c

The original impetus for thus change was a problem
noted by John Heffner.  We do not abide by the MSS
of the connection for TCP segmentation, we were using
the path MTU instead.  This broke various local
network setups with TSO enabled and is fixed as a side
effect of these changes.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tcp.h
net/ipv4/ip_output.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c

index 90c1142ec5ebfd72c1fef0783e04abec2435260f..586af267dcf1873e944f1f77b6a68f5f5b759a8c 100644 (file)
@@ -1152,8 +1152,6 @@ struct tcp_skb_cb {
 
        __u16           urg_ptr;        /* Valid w/URG flags is set.    */
        __u32           ack_seq;        /* Sequence number ACK'd        */
-       __u16           tso_factor;     /* If > 1, TSO frame            */
-       __u16           tso_mss;        /* MSS that FACTOR's in terms of*/
 };
 
 #define TCP_SKB_CB(__skb)      ((struct tcp_skb_cb *)&((__skb)->cb[0]))
@@ -1165,7 +1163,13 @@ struct tcp_skb_cb {
  */
 static inline int tcp_skb_pcount(struct sk_buff *skb)
 {
-       return TCP_SKB_CB(skb)->tso_factor;
+       return skb_shinfo(skb)->tso_segs;
+}
+
+/* This is valid iff tcp_skb_pcount() > 1. */
+static inline int tcp_skb_psize(struct sk_buff *skb)
+{
+       return skb_shinfo(skb)->tso_size;
 }
 
 static inline void tcp_inc_pcount(tcp_pcount_t *count, struct sk_buff *skb)
@@ -1440,7 +1444,7 @@ tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int n
                  tcp_minshall_check(tp))));
 }
 
-extern void tcp_set_skb_tso_factor(struct sk_buff *, unsigned int);
+extern void tcp_set_skb_tso_segs(struct sk_buff *, unsigned int);
 
 /* This checks if the data bearing packet SKB (usually sk->sk_send_head)
  * should be put on the wire right now.
@@ -1448,11 +1452,11 @@ extern void tcp_set_skb_tso_factor(struct sk_buff *, unsigned int);
 static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
                                   unsigned cur_mss, int nonagle)
 {
-       int pkts = TCP_SKB_CB(skb)->tso_factor;
+       int pkts = tcp_skb_pcount(skb);
 
        if (!pkts) {
-               tcp_set_skb_tso_factor(skb, tp->mss_cache_std);
-               pkts = TCP_SKB_CB(skb)->tso_factor;
+               tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
+               pkts = tcp_skb_pcount(skb);
        }
 
        /*      RFC 1122 - section 4.2.3.4
index fdcc39a347d99fb8b7b8f79d0509e403d221c6c8..8ef2b82630a28a6d8029b3c08c8785e677794bd5 100644 (file)
@@ -305,7 +305,6 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
        struct ip_options *opt = inet->opt;
        struct rtable *rt;
        struct iphdr *iph;
-       u32 mtu;
 
        /* Skip all of this if the packet is already routed,
         * f.e. by something like SCTP.
@@ -366,23 +365,11 @@ packet_routed:
        skb->nh.iph   = iph;
        /* Transport layer set skb->h.foo itself. */
 
-       if(opt && opt->optlen) {
+       if (opt && opt->optlen) {
                iph->ihl += opt->optlen >> 2;
                ip_options_build(skb, opt, inet->daddr, rt, 0);
        }
 
-       mtu = dst_pmtu(&rt->u.dst);
-       if (skb->len > mtu && (sk->sk_route_caps & NETIF_F_TSO)) {
-               unsigned int hlen;
-
-               /* Hack zone: all this must be done by TCP. */
-               hlen = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
-               skb_shinfo(skb)->tso_size = mtu - hlen;
-               skb_shinfo(skb)->tso_segs =
-                       (skb->len - hlen + skb_shinfo(skb)->tso_size - 1)/
-                               skb_shinfo(skb)->tso_size - 1;
-       }
-
        ip_select_ident_more(iph, &rt->u.dst, sk, skb_shinfo(skb)->tso_segs);
 
        /* Add an IP checksum. */
index 74d5b04340d371ca23197310af1f47089a04e07d..e4e1909308a299caa77538e6afe75f0bbe6885f4 100644 (file)
@@ -691,7 +691,7 @@ new_segment:
                skb->ip_summed = CHECKSUM_HW;
                tp->write_seq += copy;
                TCP_SKB_CB(skb)->end_seq += copy;
-               TCP_SKB_CB(skb)->tso_factor = 0;
+               skb_shinfo(skb)->tso_segs = 0;
 
                if (!copied)
                        TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
@@ -938,7 +938,7 @@ new_segment:
 
                        tp->write_seq += copy;
                        TCP_SKB_CB(skb)->end_seq += copy;
-                       TCP_SKB_CB(skb)->tso_factor = 0;
+                       skb_shinfo(skb)->tso_segs = 0;
 
                        from += copy;
                        copied += copy;
index 51ee1e5ccfba26d33bce527f58fc90f173fc20f7..51953e0ab7d4cdfa4edd207d71676426054895c7 100644 (file)
@@ -1035,7 +1035,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                        if(!before(TCP_SKB_CB(skb)->seq, end_seq))
                                break;
 
-                       fack_count += TCP_SKB_CB(skb)->tso_factor;
+                       fack_count += tcp_skb_pcount(skb);
 
                        in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
                                !before(end_seq, TCP_SKB_CB(skb)->end_seq);
@@ -1224,7 +1224,7 @@ static void tcp_enter_frto_loss(struct sock *sk)
        tcp_set_pcount(&tp->fackets_out, 0);
 
        sk_stream_for_retrans_queue(skb, sk) {
-               cnt += TCP_SKB_CB(skb)->tso_factor;;
+               cnt += tcp_skb_pcount(skb);
                TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
                if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) {
 
@@ -1299,7 +1299,7 @@ void tcp_enter_loss(struct sock *sk, int how)
                tp->undo_marker = tp->snd_una;
 
        sk_stream_for_retrans_queue(skb, sk) {
-               cnt += TCP_SKB_CB(skb)->tso_factor;
+               cnt += tcp_skb_pcount(skb);
                if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS)
                        tp->undo_marker = 0;
                TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED;
@@ -1550,7 +1550,7 @@ tcp_mark_head_lost(struct sock *sk, struct tcp_opt *tp, int packets, u32 high_se
        BUG_TRAP(cnt <= tcp_get_pcount(&tp->packets_out));
 
        sk_stream_for_retrans_queue(skb, sk) {
-               cnt -= TCP_SKB_CB(skb)->tso_factor;
+               cnt -= tcp_skb_pcount(skb);
                if (cnt < 0 || after(TCP_SKB_CB(skb)->end_seq, high_seq))
                        break;
                if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
@@ -2369,7 +2369,7 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 {
        struct tcp_opt *tp = tcp_sk(sk);
        struct tcp_skb_cb *scb = TCP_SKB_CB(skb); 
-       __u32 mss = scb->tso_mss;
+       __u32 mss = tcp_skb_psize(skb);
        __u32 snd_una = tp->snd_una;
        __u32 orig_seq, seq;
        __u32 packets_acked = 0;
@@ -2423,7 +2423,7 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
                }
                tcp_dec_pcount_explicit(&tp->packets_out, packets_acked);
 
-               BUG_ON(scb->tso_factor == 0);
+               BUG_ON(tcp_skb_pcount(skb) == 0);
                BUG_ON(!before(scb->seq, scb->end_seq));
        }
 
@@ -2450,7 +2450,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
                 * the other end.
                 */
                if (after(scb->end_seq, tp->snd_una)) {
-                       if (scb->tso_factor > 1)
+                       if (tcp_skb_pcount(skb) > 1)
                                acked |= tcp_tso_acked(sk, skb,
                                                       now, &seq_rtt);
                        break;
index cd67ffb23f0d2b3a46d85bbb59837f167cf39586..39214126cf9efc0af485fd836a58e5ffd00c35f8 100644 (file)
@@ -274,7 +274,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
                int sysctl_flags;
                int err;
 
-               BUG_ON(!TCP_SKB_CB(skb)->tso_factor);
+               BUG_ON(!tcp_skb_pcount(skb));
 
 #define SYSCTL_FLAG_TSTAMPS    0x1
 #define SYSCTL_FLAG_WSCALE     0x2
@@ -428,21 +428,22 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
        }
 }
 
-void tcp_set_skb_tso_factor(struct sk_buff *skb, unsigned int mss_std)
+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std)
 {
        if (skb->len <= mss_std) {
                /* Avoid the costly divide in the normal
                 * non-TSO case.
                 */
-               TCP_SKB_CB(skb)->tso_factor = 1;
+               skb_shinfo(skb)->tso_segs = 1;
+               skb_shinfo(skb)->tso_size = 0;
        } else {
                unsigned int factor;
 
                factor = skb->len + (mss_std - 1);
                factor /= mss_std;
-               TCP_SKB_CB(skb)->tso_factor = factor;
+               skb_shinfo(skb)->tso_segs = factor;
+               skb_shinfo(skb)->tso_size = mss_std;
        }
-       TCP_SKB_CB(skb)->tso_mss = mss_std;
 }
 
 /* Function to create two new TCP segments.  Shrinks the given segment
@@ -508,8 +509,8 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
        }
 
        /* Fix up tso_factor for both original and new SKB.  */
-       tcp_set_skb_tso_factor(skb, tp->mss_cache_std);
-       tcp_set_skb_tso_factor(buff, tp->mss_cache_std);
+       tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
+       tcp_set_skb_tso_segs(buff, tp->mss_cache_std);
 
        if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
                tcp_inc_pcount(&tp->lost_out, skb);
@@ -585,7 +586,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
        /* Any change of skb->len requires recalculation of tso
         * factor and mss.
         */
-       tcp_set_skb_tso_factor(skb, tp->mss_cache_std);
+       tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
 
        return 0;
 }
@@ -914,8 +915,8 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
                    ((skb_size + next_skb_size) > mss_now))
                        return;
 
-               BUG_ON(TCP_SKB_CB(skb)->tso_factor != 1 ||
-                      TCP_SKB_CB(next_skb)->tso_factor != 1);
+               BUG_ON(tcp_skb_pcount(skb) != 1 ||
+                      tcp_skb_pcount(next_skb) != 1);
 
                /* Ok.  We will be able to collapse the packet. */
                __skb_unlink(next_skb, next_skb->list);
@@ -1047,14 +1048,14 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
                return -EAGAIN;
 
        if (skb->len > cur_mss) {
-               int old_factor = TCP_SKB_CB(skb)->tso_factor;
+               int old_factor = tcp_skb_pcount(skb);
                int new_factor;
 
                if (tcp_fragment(sk, skb, cur_mss))
                        return -ENOMEM; /* We'll try again later. */
 
                /* New SKB created, account for it. */
-               new_factor = TCP_SKB_CB(skb)->tso_factor;
+               new_factor = tcp_skb_pcount(skb);
                tcp_dec_pcount_explicit(&tp->packets_out,
                                        old_factor - new_factor);
                tcp_inc_pcount(&tp->packets_out, skb->next);
@@ -1081,7 +1082,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
           tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
                if (!pskb_trim(skb, 0)) {
                        TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
-                       TCP_SKB_CB(skb)->tso_factor = 1;
+                       skb_shinfo(skb)->tso_segs = 1;
+                       skb_shinfo(skb)->tso_size = 0;
                        skb->ip_summed = CHECKSUM_NONE;
                        skb->csum = 0;
                }
@@ -1166,7 +1168,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
                                                tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
                                }
 
-                               packet_cnt -= TCP_SKB_CB(skb)->tso_factor;
+                               packet_cnt -= tcp_skb_pcount(skb);
                                if (packet_cnt <= 0)
                                        break;
                        }
@@ -1256,8 +1258,8 @@ void tcp_send_fin(struct sock *sk)
                skb->csum = 0;
                TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
                TCP_SKB_CB(skb)->sacked = 0;
-               TCP_SKB_CB(skb)->tso_factor = 1;
-               TCP_SKB_CB(skb)->tso_mss = tp->mss_cache_std;
+               skb_shinfo(skb)->tso_segs = 1;
+               skb_shinfo(skb)->tso_size = 0;
 
                /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
                TCP_SKB_CB(skb)->seq = tp->write_seq;
@@ -1289,8 +1291,8 @@ void tcp_send_active_reset(struct sock *sk, int priority)
        skb->csum = 0;
        TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
        TCP_SKB_CB(skb)->sacked = 0;
-       TCP_SKB_CB(skb)->tso_factor = 1;
-       TCP_SKB_CB(skb)->tso_mss = tp->mss_cache_std;
+       skb_shinfo(skb)->tso_segs = 1;
+       skb_shinfo(skb)->tso_size = 0;
 
        /* Send it off. */
        TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp);
@@ -1371,8 +1373,8 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        TCP_SKB_CB(skb)->seq = req->snt_isn;
        TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
        TCP_SKB_CB(skb)->sacked = 0;
-       TCP_SKB_CB(skb)->tso_factor = 1;
-       TCP_SKB_CB(skb)->tso_mss = tp->mss_cache_std;
+       skb_shinfo(skb)->tso_segs = 1;
+       skb_shinfo(skb)->tso_size = 0;
        th->seq = htonl(TCP_SKB_CB(skb)->seq);
        th->ack_seq = htonl(req->rcv_isn + 1);
        if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
@@ -1474,8 +1476,8 @@ int tcp_connect(struct sock *sk)
        TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
        TCP_ECN_send_syn(sk, tp, buff);
        TCP_SKB_CB(buff)->sacked = 0;
-       TCP_SKB_CB(buff)->tso_factor = 1;
-       TCP_SKB_CB(buff)->tso_mss = tp->mss_cache_std;
+       skb_shinfo(buff)->tso_segs = 1;
+       skb_shinfo(buff)->tso_size = 0;
        buff->csum = 0;
        TCP_SKB_CB(buff)->seq = tp->write_seq++;
        TCP_SKB_CB(buff)->end_seq = tp->write_seq;
@@ -1575,8 +1577,8 @@ void tcp_send_ack(struct sock *sk)
                buff->csum = 0;
                TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
                TCP_SKB_CB(buff)->sacked = 0;
-               TCP_SKB_CB(buff)->tso_factor = 1;
-               TCP_SKB_CB(buff)->tso_mss = tp->mss_cache_std;
+               skb_shinfo(buff)->tso_segs = 1;
+               skb_shinfo(buff)->tso_size = 0;
 
                /* Send it off, this clears delayed acks for us. */
                TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp);
@@ -1611,8 +1613,8 @@ static int tcp_xmit_probe_skb(struct sock *sk, int urgent)
        skb->csum = 0;
        TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
        TCP_SKB_CB(skb)->sacked = urgent;
-       TCP_SKB_CB(skb)->tso_factor = 1;
-       TCP_SKB_CB(skb)->tso_mss = tp->mss_cache_std;
+       skb_shinfo(skb)->tso_segs = 1;
+       skb_shinfo(skb)->tso_size = 0;
 
        /* Use a previous sequence.  This should cause the other
         * end to send an ack.  Don't queue or clone SKB, just
@@ -1656,8 +1658,8 @@ int tcp_write_wakeup(struct sock *sk)
                                        sk->sk_route_caps &= ~NETIF_F_TSO;
                                        tp->mss_cache = tp->mss_cache_std;
                                }
-                       } else if (!TCP_SKB_CB(skb)->tso_factor)
-                               tcp_set_skb_tso_factor(skb, tp->mss_cache_std);
+                       } else if (!tcp_skb_pcount(skb))
+                               tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
 
                        TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
                        TCP_SKB_CB(skb)->when = tcp_time_stamp;