aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c89
1 files changed, 63 insertions, 26 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 76b148bcb0dc..2451aeb5ac23 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -661,6 +661,47 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
661 return NULL; 661 return NULL;
662} 662}
663 663
664static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
665 int large_allowed)
666{
667 struct tcp_sock *tp = tcp_sk(sk);
668 u32 xmit_size_goal, old_size_goal;
669
670 xmit_size_goal = mss_now;
671
672 if (large_allowed && sk_can_gso(sk)) {
673 xmit_size_goal = ((sk->sk_gso_max_size - 1) -
674 inet_csk(sk)->icsk_af_ops->net_header_len -
675 inet_csk(sk)->icsk_ext_hdr_len -
676 tp->tcp_header_len);
677
678 xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
679
680 /* We try hard to avoid divides here */
681 old_size_goal = tp->xmit_size_goal_segs * mss_now;
682
683 if (likely(old_size_goal <= xmit_size_goal &&
684 old_size_goal + mss_now > xmit_size_goal)) {
685 xmit_size_goal = old_size_goal;
686 } else {
687 tp->xmit_size_goal_segs = xmit_size_goal / mss_now;
688 xmit_size_goal = tp->xmit_size_goal_segs * mss_now;
689 }
690 }
691
692 return max(xmit_size_goal, mss_now);
693}
694
695static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
696{
697 int mss_now;
698
699 mss_now = tcp_current_mss(sk);
700 *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB));
701
702 return mss_now;
703}
704
664static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, 705static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
665 size_t psize, int flags) 706 size_t psize, int flags)
666{ 707{
@@ -677,13 +718,12 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
677 718
678 clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); 719 clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
679 720
680 mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); 721 mss_now = tcp_send_mss(sk, &size_goal, flags);
681 size_goal = tp->xmit_size_goal;
682 copied = 0; 722 copied = 0;
683 723
684 err = -EPIPE; 724 err = -EPIPE;
685 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) 725 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
686 goto do_error; 726 goto out_err;
687 727
688 while (psize > 0) { 728 while (psize > 0) {
689 struct sk_buff *skb = tcp_write_queue_tail(sk); 729 struct sk_buff *skb = tcp_write_queue_tail(sk);
@@ -761,8 +801,7 @@ wait_for_memory:
761 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) 801 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
762 goto do_error; 802 goto do_error;
763 803
764 mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); 804 mss_now = tcp_send_mss(sk, &size_goal, flags);
765 size_goal = tp->xmit_size_goal;
766 } 805 }
767 806
768out: 807out:
@@ -844,8 +883,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
844 /* This should be in poll */ 883 /* This should be in poll */
845 clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); 884 clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
846 885
847 mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); 886 mss_now = tcp_send_mss(sk, &size_goal, flags);
848 size_goal = tp->xmit_size_goal;
849 887
850 /* Ok commence sending. */ 888 /* Ok commence sending. */
851 iovlen = msg->msg_iovlen; 889 iovlen = msg->msg_iovlen;
@@ -854,7 +892,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
854 892
855 err = -EPIPE; 893 err = -EPIPE;
856 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) 894 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
857 goto do_error; 895 goto out_err;
858 896
859 while (--iovlen >= 0) { 897 while (--iovlen >= 0) {
860 int seglen = iov->iov_len; 898 int seglen = iov->iov_len;
@@ -1007,8 +1045,7 @@ wait_for_memory:
1007 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) 1045 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
1008 goto do_error; 1046 goto do_error;
1009 1047
1010 mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); 1048 mss_now = tcp_send_mss(sk, &size_goal, flags);
1011 size_goal = tp->xmit_size_goal;
1012 } 1049 }
1013 } 1050 }
1014 1051
@@ -1045,8 +1082,7 @@ out_err:
1045 */ 1082 */
1046 1083
1047static int tcp_recv_urg(struct sock *sk, long timeo, 1084static int tcp_recv_urg(struct sock *sk, long timeo,
1048 struct msghdr *msg, int len, int flags, 1085 struct msghdr *msg, int len, int flags)
1049 int *addr_len)
1050{ 1086{
1051 struct tcp_sock *tp = tcp_sk(sk); 1087 struct tcp_sock *tp = tcp_sk(sk);
1052 1088
@@ -1661,7 +1697,7 @@ out:
1661 return err; 1697 return err;
1662 1698
1663recv_urg: 1699recv_urg:
1664 err = tcp_recv_urg(sk, timeo, msg, len, flags, addr_len); 1700 err = tcp_recv_urg(sk, timeo, msg, len, flags);
1665 goto out; 1701 goto out;
1666} 1702}
1667 1703
@@ -2478,23 +2514,23 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2478 struct tcphdr *th2; 2514 struct tcphdr *th2;
2479 unsigned int thlen; 2515 unsigned int thlen;
2480 unsigned int flags; 2516 unsigned int flags;
2481 unsigned int total;
2482 unsigned int mss = 1; 2517 unsigned int mss = 1;
2483 int flush = 1; 2518 int flush = 1;
2519 int i;
2484 2520
2485 if (!pskb_may_pull(skb, sizeof(*th))) 2521 th = skb_gro_header(skb, sizeof(*th));
2522 if (unlikely(!th))
2486 goto out; 2523 goto out;
2487 2524
2488 th = tcp_hdr(skb);
2489 thlen = th->doff * 4; 2525 thlen = th->doff * 4;
2490 if (thlen < sizeof(*th)) 2526 if (thlen < sizeof(*th))
2491 goto out; 2527 goto out;
2492 2528
2493 if (!pskb_may_pull(skb, thlen)) 2529 th = skb_gro_header(skb, thlen);
2530 if (unlikely(!th))
2494 goto out; 2531 goto out;
2495 2532
2496 th = tcp_hdr(skb); 2533 skb_gro_pull(skb, thlen);
2497 __skb_pull(skb, thlen);
2498 2534
2499 flags = tcp_flag_word(th); 2535 flags = tcp_flag_word(th);
2500 2536
@@ -2504,7 +2540,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2504 2540
2505 th2 = tcp_hdr(p); 2541 th2 = tcp_hdr(p);
2506 2542
2507 if (th->source != th2->source || th->dest != th2->dest) { 2543 if ((th->source ^ th2->source) | (th->dest ^ th2->dest)) {
2508 NAPI_GRO_CB(p)->same_flow = 0; 2544 NAPI_GRO_CB(p)->same_flow = 0;
2509 continue; 2545 continue;
2510 } 2546 }
@@ -2519,14 +2555,15 @@ found:
2519 flush |= flags & TCP_FLAG_CWR; 2555 flush |= flags & TCP_FLAG_CWR;
2520 flush |= (flags ^ tcp_flag_word(th2)) & 2556 flush |= (flags ^ tcp_flag_word(th2)) &
2521 ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH); 2557 ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH);
2522 flush |= th->ack_seq != th2->ack_seq || th->window != th2->window; 2558 flush |= (th->ack_seq ^ th2->ack_seq) | (th->window ^ th2->window);
2523 flush |= memcmp(th + 1, th2 + 1, thlen - sizeof(*th)); 2559 for (i = sizeof(*th); !flush && i < thlen; i += 4)
2560 flush |= *(u32 *)((u8 *)th + i) ^
2561 *(u32 *)((u8 *)th2 + i);
2524 2562
2525 total = p->len;
2526 mss = skb_shinfo(p)->gso_size; 2563 mss = skb_shinfo(p)->gso_size;
2527 2564
2528 flush |= skb->len > mss || skb->len <= 0; 2565 flush |= (skb_gro_len(skb) > mss) | !skb_gro_len(skb);
2529 flush |= ntohl(th2->seq) + total != ntohl(th->seq); 2566 flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq);
2530 2567
2531 if (flush || skb_gro_receive(head, skb)) { 2568 if (flush || skb_gro_receive(head, skb)) {
2532 mss = 1; 2569 mss = 1;
@@ -2538,7 +2575,7 @@ found:
2538 tcp_flag_word(th2) |= flags & (TCP_FLAG_FIN | TCP_FLAG_PSH); 2575 tcp_flag_word(th2) |= flags & (TCP_FLAG_FIN | TCP_FLAG_PSH);
2539 2576
2540out_check_final: 2577out_check_final:
2541 flush = skb->len < mss; 2578 flush = skb_gro_len(skb) < mss;
2542 flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST | 2579 flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST |
2543 TCP_FLAG_SYN | TCP_FLAG_FIN); 2580 TCP_FLAG_SYN | TCP_FLAG_FIN);
2544 2581