summaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2026-03-04 01:27:47 +0000
committerJakub Kicinski <kuba@kernel.org>2026-03-04 17:53:34 -0800
commitc66e0f453d1afa82534383c58d503238a43fa76c (patch)
tree21e31a861c8e9528b41223830d0f6c286f609a3c /net/ipv4
parent39ae83b0f557969c461d93c608545443a2f5c307 (diff)
downloadlinux-next-c66e0f453d1afa82534383c58d503238a43fa76c.tar.gz
linux-next-c66e0f453d1afa82534383c58d503238a43fa76c.zip
net: use ktime_t in struct scm_timestamping_internal
Instead of using struct timespec64 in scm_timestamping_internal, use ktime_t, saving 24 bytes in kernel stack. This makes tcp_update_recv_tstamps() small enough to be inlined. The ktime_t -> timespec64 conversions happen after socket lock has been released in tcp_recvmsg(), and only if the application requested them. $ scripts/bloat-o-meter -t vmlinux.0 vmlinux add/remove: 0/2 grow/shrink: 5/4 up/down: 146/-277 (-131) Function old new delta tcp_zerocopy_receive 2383 2425 +42 mptcp_recvmsg 1565 1607 +42 tcp_recvmsg_locked 3797 3823 +26 put_cmsg_scm_timestamping64 131 149 +18 put_cmsg_scm_timestamping 131 149 +18 __pfx_tcp_update_recv_tstamps 16 - -16 do_tcp_getsockopt 4024 4006 -18 tcp_recv_timestamp 474 430 -44 tcp_zc_handle_leftover 417 371 -46 __sock_recv_timestamp 1087 1031 -56 tcp_update_recv_tstamps 97 - -97 Total: Before=25223788, After=25223657, chg -0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Link: https://patch.msgid.link/20260304012747.881644-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/tcp.c61
1 files changed, 22 insertions, 39 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5997e0fb7a45..1c8be22a361e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1871,20 +1871,6 @@ int tcp_set_rcvlowat(struct sock *sk, int val)
}
EXPORT_IPV6_MOD(tcp_set_rcvlowat);
-void tcp_update_recv_tstamps(struct sk_buff *skb,
- struct scm_timestamping_internal *tss)
-{
- if (skb->tstamp)
- tss->ts[0] = ktime_to_timespec64(skb->tstamp);
- else
- tss->ts[0] = (struct timespec64) {0};
-
- if (skb_hwtstamps(skb)->hwtstamp)
- tss->ts[2] = ktime_to_timespec64(skb_hwtstamps(skb)->hwtstamp);
- else
- tss->ts[2] = (struct timespec64) {0};
-}
-
#ifdef CONFIG_MMU
static const struct vm_operations_struct tcp_vm_ops = {
};
@@ -2376,22 +2362,23 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
{
int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
u32 tsflags = READ_ONCE(sk->sk_tsflags);
- bool has_timestamping = false;
- if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
+ if (tss->ts[0]) {
if (sock_flag(sk, SOCK_RCVTSTAMP)) {
+ struct timespec64 tv = ktime_to_timespec64(tss->ts[0]);
+
if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
if (new_tstamp) {
struct __kernel_timespec kts = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_nsec = tss->ts[0].tv_nsec,
+ .tv_sec = tv.tv_sec,
+ .tv_nsec = tv.tv_nsec,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
sizeof(kts), &kts);
} else {
struct __kernel_old_timespec ts_old = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_nsec = tss->ts[0].tv_nsec,
+ .tv_sec = tv.tv_sec,
+ .tv_nsec = tv.tv_nsec,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
sizeof(ts_old), &ts_old);
@@ -2399,41 +2386,37 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
} else {
if (new_tstamp) {
struct __kernel_sock_timeval stv = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_usec = tss->ts[0].tv_nsec / 1000,
+ .tv_sec = tv.tv_sec,
+ .tv_usec = tv.tv_nsec / 1000,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
sizeof(stv), &stv);
} else {
- struct __kernel_old_timeval tv = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_usec = tss->ts[0].tv_nsec / 1000,
+ struct __kernel_old_timeval otv = {
+ .tv_sec = tv.tv_sec,
+ .tv_usec = tv.tv_nsec / 1000,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
- sizeof(tv), &tv);
+ sizeof(otv), &otv);
}
}
}
- if (tsflags & SOF_TIMESTAMPING_SOFTWARE &&
+ if (!(tsflags & SOF_TIMESTAMPING_SOFTWARE &&
(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
- !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
- has_timestamping = true;
- else
- tss->ts[0] = (struct timespec64) {0};
+ !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))))
+ tss->ts[0] = 0;
}
- if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
- if (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
+ if (tss->ts[2]) {
+ if (!(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
(tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
- !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
- has_timestamping = true;
- else
- tss->ts[2] = (struct timespec64) {0};
+ !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))))
+ tss->ts[2] = 0;
}
- if (has_timestamping) {
- tss->ts[1] = (struct timespec64) {0};
+ if (tss->ts[0] | tss->ts[2]) {
+ tss->ts[1] = 0;
if (sock_flag(sk, SOCK_TSTAMP_NEW))
put_cmsg_scm_timestamping64(msg, tss);
else