Skip to content

Commit ad02c4f

Browse files
soheilhydavem330
authored andcommitted
tcp: provide timestamps for partial writes
For TCP sockets, TX timestamps are only captured when the user data is successfully and fully written to the socket. In many cases, however, TCP writes can be partial for which no timestamp is collected. Collect timestamps whenever any user data is (fully or partially) copied into the socket. Pass tcp_write_queue_tail to tcp_tx_timestamp instead of the local skb pointer since it can be set to NULL on the error path. Note that tcp_write_queue_tail can be NULL, even if bytes have been copied to the socket. This is because acknowledgements are being processed in tcp_sendmsg(), and by the time tcp_tx_timestamp is called tcp_write_queue_tail can be NULL. For such cases, this patch does not collect any timestamps (i.e., it is best-effort). This patch is written with suggestions from Willem de Bruijn and Eric Dumazet. Change-log V1 -> V2: - Use sockc.tsflags instead of sk->sk_tsflags. - Use the same code path for normal writes and errors. Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com> Acked-by: Yuchung Cheng <ycheng@google.com> Cc: Willem de Bruijn <willemb@google.com> Cc: Eric Dumazet <edumazet@google.com> Cc: Neal Cardwell <ncardwell@google.com> Cc: Martin KaFai Lau <kafai@fb.com> Acked-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 37e65dc commit ad02c4f

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

net/ipv4/tcp.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ EXPORT_SYMBOL(tcp_init_sock);
429429

430430
static void tcp_tx_timestamp(struct sock *sk, u16 tsflags, struct sk_buff *skb)
431431
{
432-
if (tsflags) {
432+
if (tsflags && skb) {
433433
struct skb_shared_info *shinfo = skb_shinfo(skb);
434434
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
435435

@@ -958,10 +958,8 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
958958
copied += copy;
959959
offset += copy;
960960
size -= copy;
961-
if (!size) {
962-
tcp_tx_timestamp(sk, sk->sk_tsflags, skb);
961+
if (!size)
963962
goto out;
964-
}
965963

966964
if (skb->len < size_goal || (flags & MSG_OOB))
967965
continue;
@@ -987,8 +985,11 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
987985
}
988986

989987
out:
990-
if (copied && !(flags & MSG_SENDPAGE_NOTLAST))
991-
tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
988+
if (copied) {
989+
tcp_tx_timestamp(sk, sk->sk_tsflags, tcp_write_queue_tail(sk));
990+
if (!(flags & MSG_SENDPAGE_NOTLAST))
991+
tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
992+
}
992993
return copied;
993994

994995
do_error:
@@ -1281,7 +1282,6 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
12811282

12821283
copied += copy;
12831284
if (!msg_data_left(msg)) {
1284-
tcp_tx_timestamp(sk, sockc.tsflags, skb);
12851285
if (unlikely(flags & MSG_EOR))
12861286
TCP_SKB_CB(skb)->eor = 1;
12871287
goto out;
@@ -1312,8 +1312,10 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
13121312
}
13131313

13141314
out:
1315-
if (copied)
1315+
if (copied) {
1316+
tcp_tx_timestamp(sk, sockc.tsflags, tcp_write_queue_tail(sk));
13161317
tcp_push(sk, flags, mss_now, tp->nonagle, size_goal);
1318+
}
13171319
out_nopush:
13181320
release_sock(sk);
13191321
return copied + copied_syn;

0 commit comments

Comments
 (0)