tree 5ee3bec452e795d48f380aee4494e06e5aba038e
parent 7f4dd0a9438c73cbb1c240ece31390cf2c57294e
author David S. Miller <[EMAIL PROTECTED]> Wed, 06 Jul 2005 05:20:09 -0700
committer David S. Miller <[EMAIL PROTECTED]> Wed, 06 Jul 2005 05:20:09 -0700
[TCP]: Eliminate redundant computations in tcp_write_xmit().
tcp_snd_test() is run for every packet output by a single
call to tcp_write_xmit(), but this is not necessary.
For one, the congestion window space needs to only be
calculated one time, then used throughout the duration
of the loop.
This cleanup also makes experimenting with different TSO
packetization schemes much easier.
Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
net/ipv4/tcp_output.c | 40 +++++++++++++++++++++++++++++++---------
1 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -887,6 +887,7 @@ static int tcp_write_xmit(struct sock *s
{
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
+ unsigned int tso_segs, cwnd_quota;
int sent_pkts;
/* If we are closed, the bytes will have to remain here.
@@ -896,19 +897,31 @@ static int tcp_write_xmit(struct sock *s
if (unlikely(sk->sk_state == TCP_CLOSE))
return 0;
+ skb = sk->sk_send_head;
+ if (unlikely(!skb))
+ return 0;
+
+ tso_segs = tcp_init_tso_segs(sk, skb);
+ cwnd_quota = tcp_cwnd_test(tp, skb);
sent_pkts = 0;
- while ((skb = sk->sk_send_head) &&
- tcp_snd_test(sk, skb, mss_now,
- tcp_skb_is_last(sk, skb) ? nonagle :
- TCP_NAGLE_PUSH)) {
- if (skb->len > mss_now) {
- if (tcp_fragment(sk, skb, mss_now))
+
+ while (cwnd_quota >= tso_segs) {
+ if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
+ (tcp_skb_is_last(sk, skb) ?
+ nonagle : TCP_NAGLE_PUSH))))
+ break;
+
+ if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
+ break;
+
+ if (unlikely(skb->len > mss_now)) {
+ if (unlikely(tcp_fragment(sk, skb, mss_now)))
break;
}
TCP_SKB_CB(skb)->when = tcp_time_stamp;
tcp_tso_set_push(skb);
- if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))
+ if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
break;
/* Advance the send_head. This one is sent out.
@@ -917,10 +930,19 @@ static int tcp_write_xmit(struct sock *s
update_send_head(sk, tp, skb);
tcp_minshall_update(tp, mss_now, skb);
- sent_pkts = 1;
+ sent_pkts++;
+
+ /* Do not optimize this to use tso_segs. If we chopped up
+ * the packet above, tso_segs will no longer be valid.
+ */
+ cwnd_quota -= tcp_skb_pcount(skb);
+ skb = sk->sk_send_head;
+ if (!skb)
+ break;
+ tso_segs = tcp_init_tso_segs(sk, skb);
}
- if (sent_pkts) {
+ if (likely(sent_pkts)) {
tcp_cwnd_validate(sk, tp);
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html