aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-12-08 09:25:06 -0500
committerIngo Molnar <mingo@kernel.org>2012-12-08 09:25:06 -0500
commitf0b9abfb044649bc452fb2fb975ff2fd599cc6a3 (patch)
tree7800081c5cb16a4dfee1e57a70f3be90f7b50d9a /net/ipv4/tcp.c
parentadc1ef1e37358d3c17d1a74a58b2e104fc0bda15 (diff)
parent1b3c393cd43f22ead8a6a2f839efc6df8ebd7465 (diff)
Merge branch 'linus' into perf/core
Conflicts: tools/perf/Makefile tools/perf/builtin-test.c tools/perf/perf.h tools/perf/tests/parse-events.c tools/perf/util/evsel.h Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f32c02e2a543..e457c7ab2e28 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -549,14 +549,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
549 !tp->urg_data || 549 !tp->urg_data ||
550 before(tp->urg_seq, tp->copied_seq) || 550 before(tp->urg_seq, tp->copied_seq) ||
551 !before(tp->urg_seq, tp->rcv_nxt)) { 551 !before(tp->urg_seq, tp->rcv_nxt)) {
552 struct sk_buff *skb;
553 552
554 answ = tp->rcv_nxt - tp->copied_seq; 553 answ = tp->rcv_nxt - tp->copied_seq;
555 554
556 /* Subtract 1, if FIN is in queue. */ 555 /* Subtract 1, if FIN was received */
557 skb = skb_peek_tail(&sk->sk_receive_queue); 556 if (answ && sock_flag(sk, SOCK_DONE))
558 if (answ && skb) 557 answ--;
559 answ -= tcp_hdr(skb)->fin;
560 } else 558 } else
561 answ = tp->urg_seq - tp->copied_seq; 559 answ = tp->urg_seq - tp->copied_seq;
562 release_sock(sk); 560 release_sock(sk);
@@ -832,8 +830,8 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
832 return mss_now; 830 return mss_now;
833} 831}
834 832
835static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, 833static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
836 size_t psize, int flags) 834 size_t size, int flags)
837{ 835{
838 struct tcp_sock *tp = tcp_sk(sk); 836 struct tcp_sock *tp = tcp_sk(sk);
839 int mss_now, size_goal; 837 int mss_now, size_goal;
@@ -860,12 +858,9 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
860 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) 858 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
861 goto out_err; 859 goto out_err;
862 860
863 while (psize > 0) { 861 while (size > 0) {
864 struct sk_buff *skb = tcp_write_queue_tail(sk); 862 struct sk_buff *skb = tcp_write_queue_tail(sk);
865 struct page *page = pages[poffset / PAGE_SIZE];
866 int copy, i; 863 int copy, i;
867 int offset = poffset % PAGE_SIZE;
868 int size = min_t(size_t, psize, PAGE_SIZE - offset);
869 bool can_coalesce; 864 bool can_coalesce;
870 865
871 if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) { 866 if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) {
@@ -914,8 +909,8 @@ new_segment:
914 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; 909 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH;
915 910
916 copied += copy; 911 copied += copy;
917 poffset += copy; 912 offset += copy;
918 if (!(psize -= copy)) 913 if (!(size -= copy))
919 goto out; 914 goto out;
920 915
921 if (skb->len < size_goal || (flags & MSG_OOB)) 916 if (skb->len < size_goal || (flags & MSG_OOB))
@@ -962,7 +957,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset,
962 flags); 957 flags);
963 958
964 lock_sock(sk); 959 lock_sock(sk);
965 res = do_tcp_sendpages(sk, &page, offset, size, flags); 960 res = do_tcp_sendpages(sk, page, offset, size, flags);
966 release_sock(sk); 961 release_sock(sk);
967 return res; 962 return res;
968} 963}
@@ -1214,7 +1209,7 @@ new_segment:
1214wait_for_sndbuf: 1209wait_for_sndbuf:
1215 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 1210 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1216wait_for_memory: 1211wait_for_memory:
1217 if (copied && likely(!tp->repair)) 1212 if (copied)
1218 tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); 1213 tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
1219 1214
1220 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) 1215 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
@@ -1225,7 +1220,7 @@ wait_for_memory:
1225 } 1220 }
1226 1221
1227out: 1222out:
1228 if (copied && likely(!tp->repair)) 1223 if (copied)
1229 tcp_push(sk, flags, mss_now, tp->nonagle); 1224 tcp_push(sk, flags, mss_now, tp->nonagle);
1230 release_sock(sk); 1225 release_sock(sk);
1231 return copied + copied_syn; 1226 return copied + copied_syn;
@@ -2766,6 +2761,8 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info)
2766 info->tcpi_options |= TCPI_OPT_ECN; 2761 info->tcpi_options |= TCPI_OPT_ECN;
2767 if (tp->ecn_flags & TCP_ECN_SEEN) 2762 if (tp->ecn_flags & TCP_ECN_SEEN)
2768 info->tcpi_options |= TCPI_OPT_ECN_SEEN; 2763 info->tcpi_options |= TCPI_OPT_ECN_SEEN;
2764 if (tp->syn_data_acked)
2765 info->tcpi_options |= TCPI_OPT_SYN_DATA;
2769 2766
2770 info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); 2767 info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto);
2771 info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); 2768 info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato);