public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal
@ 2026-03-04  1:27 Eric Dumazet
  2026-03-04  3:26 ` Willem de Bruijn
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Eric Dumazet @ 2026-03-04  1:27 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Willem de Bruijn, netdev,
	eric.dumazet, Eric Dumazet

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>
---
 include/linux/socket.h |  2 +-
 include/net/tcp.h      | 11 ++++++--
 net/core/scm.c         | 12 ++++++---
 net/ipv4/tcp.c         | 61 +++++++++++++++---------------------------
 net/socket.c           | 23 ++++++++--------
 5 files changed, 51 insertions(+), 58 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index ec715ad4bf25f5f759d2cab3c6b796fed84df932..ec4a0a0257939a5363c55bed3ccb20182965b2e3 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -415,7 +415,7 @@ struct __kernel_timespec;
 struct old_timespec32;
 
 struct scm_timestamping_internal {
-	struct timespec64 ts[3];
+	ktime_t ts[3];
 };
 
 extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9cf8785ef0b42460a2389b4aa75570b3aa31cbb4..fea6081cf6c798fe5f3f3b3ab3335619d7324f6e 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -503,8 +503,15 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		int flags);
 int tcp_set_rcvlowat(struct sock *sk, int val);
 int tcp_set_window_clamp(struct sock *sk, int val);
-void tcp_update_recv_tstamps(struct sk_buff *skb,
-			     struct scm_timestamping_internal *tss);
+
+static inline void
+tcp_update_recv_tstamps(struct sk_buff *skb,
+			struct scm_timestamping_internal *tss)
+{
+	tss->ts[0] = skb->tstamp;
+	tss->ts[2] = skb_hwtstamps(skb)->hwtstamp;
+}
+
 void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
 			struct scm_timestamping_internal *tss);
 void tcp_data_ready(struct sock *sk);
diff --git a/net/core/scm.c b/net/core/scm.c
index a29aa8fb8065665f8a8f2255ec3e55df973a6b0a..eec13f50ecaf6fa7caf9316bf17ab401d98d0efc 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -318,8 +318,10 @@ void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_int
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
-		tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
-		tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
+		struct timespec64 tv = ktime_to_timespec64(tss_internal->ts[i]);
+
+		tss.ts[i].tv_sec = tv.tv_sec;
+		tss.ts[i].tv_nsec = tv.tv_nsec;
 	}
 
 	put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_NEW, sizeof(tss), &tss);
@@ -332,8 +334,10 @@ void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_inter
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
-		tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
-		tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
+		struct timespec64 tv = ktime_to_timespec64(tss_internal->ts[i]);
+
+		tss.ts[i].tv_sec = tv.tv_sec;
+		tss.ts[i].tv_nsec = tv.tv_nsec;
 	}
 
 	put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 1790d2fa75ade77cda8d0a593e689ea4432734dd..3d77d90c14fe13777d17563e17596066c44c66bd 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
diff --git a/net/socket.c b/net/socket.c
index 05952188127f5bce41494e99e86418249e9022f2..68829d09bcf1468dee49864c5e4ea52362c3c6c7 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -912,11 +912,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 {
 	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
 	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
-	struct scm_timestamping_internal tss;
-	int empty = 1, false_tstamp = 0;
 	struct skb_shared_hwtstamps *shhwtstamps =
 		skb_hwtstamps(skb);
-	int if_index;
+	struct scm_timestamping_internal tss;
+	int if_index, false_tstamp = 0;
 	ktime_t hwtstamp;
 	u32 tsflags;
 
@@ -961,12 +960,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 
 	memset(&tss, 0, sizeof(tss));
 	tsflags = READ_ONCE(sk->sk_tsflags);
-	if ((tsflags & SOF_TIMESTAMPING_SOFTWARE &&
-	     (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
-	      skb_is_err_queue(skb) ||
-	      !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
-	    ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
-		empty = 0;
+	if (tsflags & SOF_TIMESTAMPING_SOFTWARE &&
+	    (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
+	    skb_is_err_queue(skb) ||
+	    !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
+		tss.ts[0] = skb->tstamp;
+
 	if (shhwtstamps &&
 	    (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
 	     (tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
@@ -983,15 +982,15 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 			hwtstamp = ptp_convert_timestamp(&hwtstamp,
 							 READ_ONCE(sk->sk_bind_phc));
 
-		if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
-			empty = 0;
+		if (hwtstamp) {
+			tss.ts[2] = hwtstamp;
 
 			if ((tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
 			    !skb_is_err_queue(skb))
 				put_ts_pktinfo(msg, skb, if_index);
 		}
 	}
-	if (!empty) {
+	if (tss.ts[0] | tss.ts[2]) {
 		if (sock_flag(sk, SOCK_TSTAMP_NEW))
 			put_cmsg_scm_timestamping64(msg, &tss);
 		else
-- 
2.53.0.473.g4a7958ca14-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal
  2026-03-04  1:27 [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal Eric Dumazet
@ 2026-03-04  3:26 ` Willem de Bruijn
  2026-03-04  7:11 ` Jason Xing
  2026-03-05  2:40 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: Willem de Bruijn @ 2026-03-04  3:26 UTC (permalink / raw)
  To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Willem de Bruijn, netdev,
	eric.dumazet, Eric Dumazet

Eric Dumazet wrote:
> 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>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal
  2026-03-04  1:27 [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal Eric Dumazet
  2026-03-04  3:26 ` Willem de Bruijn
@ 2026-03-04  7:11 ` Jason Xing
  2026-03-05  2:56   ` Eric Dumazet
  2026-03-05  2:40 ` patchwork-bot+netdevbpf
  2 siblings, 1 reply; 5+ messages in thread
From: Jason Xing @ 2026-03-04  7:11 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Kuniyuki Iwashima, Willem de Bruijn, netdev, eric.dumazet

On Wed, Mar 4, 2026 at 9:30 AM Eric Dumazet <edumazet@google.com> wrote:
>
> 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: Jason Xing <kerneljasonxing@gmail.com>

> ---
>  include/linux/socket.h |  2 +-
>  include/net/tcp.h      | 11 ++++++--
>  net/core/scm.c         | 12 ++++++---
>  net/ipv4/tcp.c         | 61 +++++++++++++++---------------------------
>  net/socket.c           | 23 ++++++++--------
>  5 files changed, 51 insertions(+), 58 deletions(-)
>
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index ec715ad4bf25f5f759d2cab3c6b796fed84df932..ec4a0a0257939a5363c55bed3ccb20182965b2e3 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -415,7 +415,7 @@ struct __kernel_timespec;
>  struct old_timespec32;
>
>  struct scm_timestamping_internal {
> -       struct timespec64 ts[3];
> +       ktime_t ts[3];
>  };
>
>  extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 9cf8785ef0b42460a2389b4aa75570b3aa31cbb4..fea6081cf6c798fe5f3f3b3ab3335619d7324f6e 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -503,8 +503,15 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
>                 int flags);
>  int tcp_set_rcvlowat(struct sock *sk, int val);
>  int tcp_set_window_clamp(struct sock *sk, int val);
> -void tcp_update_recv_tstamps(struct sk_buff *skb,
> -                            struct scm_timestamping_internal *tss);
> +
> +static inline void
> +tcp_update_recv_tstamps(struct sk_buff *skb,
> +                       struct scm_timestamping_internal *tss)
> +{
> +       tss->ts[0] = skb->tstamp;
> +       tss->ts[2] = skb_hwtstamps(skb)->hwtstamp;
> +}
> +
>  void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
>                         struct scm_timestamping_internal *tss);
>  void tcp_data_ready(struct sock *sk);
> diff --git a/net/core/scm.c b/net/core/scm.c
> index a29aa8fb8065665f8a8f2255ec3e55df973a6b0a..eec13f50ecaf6fa7caf9316bf17ab401d98d0efc 100644
> --- a/net/core/scm.c
> +++ b/net/core/scm.c
> @@ -318,8 +318,10 @@ void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_int
>         int i;
>
>         for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
> -               tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
> -               tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
> +               struct timespec64 tv = ktime_to_timespec64(tss_internal->ts[i]);
> +
> +               tss.ts[i].tv_sec = tv.tv_sec;
> +               tss.ts[i].tv_nsec = tv.tv_nsec;
>         }
>
>         put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_NEW, sizeof(tss), &tss);
> @@ -332,8 +334,10 @@ void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_inter
>         int i;
>
>         for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
> -               tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
> -               tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
> +               struct timespec64 tv = ktime_to_timespec64(tss_internal->ts[i]);
> +
> +               tss.ts[i].tv_sec = tv.tv_sec;
> +               tss.ts[i].tv_nsec = tv.tv_nsec;
>         }
>
>         put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 1790d2fa75ade77cda8d0a593e689ea4432734dd..3d77d90c14fe13777d17563e17596066c44c66bd 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]) {

Maybe use tss->ts[0] || tss->ts[2]? It's a bit weird to use a single |
as to readability.

> +               tss->ts[1] = 0;
>                 if (sock_flag(sk, SOCK_TSTAMP_NEW))
>                         put_cmsg_scm_timestamping64(msg, tss);
>                 else
> diff --git a/net/socket.c b/net/socket.c
> index 05952188127f5bce41494e99e86418249e9022f2..68829d09bcf1468dee49864c5e4ea52362c3c6c7 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -912,11 +912,10 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
>  {
>         int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
>         int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
> -       struct scm_timestamping_internal tss;
> -       int empty = 1, false_tstamp = 0;
>         struct skb_shared_hwtstamps *shhwtstamps =
>                 skb_hwtstamps(skb);
> -       int if_index;
> +       struct scm_timestamping_internal tss;
> +       int if_index, false_tstamp = 0;
>         ktime_t hwtstamp;
>         u32 tsflags;
>
> @@ -961,12 +960,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
>
>         memset(&tss, 0, sizeof(tss));
>         tsflags = READ_ONCE(sk->sk_tsflags);
> -       if ((tsflags & SOF_TIMESTAMPING_SOFTWARE &&
> -            (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
> -             skb_is_err_queue(skb) ||
> -             !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
> -           ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
> -               empty = 0;
> +       if (tsflags & SOF_TIMESTAMPING_SOFTWARE &&
> +           (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
> +           skb_is_err_queue(skb) ||
> +           !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
> +               tss.ts[0] = skb->tstamp;
> +
>         if (shhwtstamps &&
>             (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
>              (tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
> @@ -983,15 +982,15 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
>                         hwtstamp = ptp_convert_timestamp(&hwtstamp,
>                                                          READ_ONCE(sk->sk_bind_phc));
>
> -               if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
> -                       empty = 0;
> +               if (hwtstamp) {
> +                       tss.ts[2] = hwtstamp;
>
>                         if ((tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
>                             !skb_is_err_queue(skb))
>                                 put_ts_pktinfo(msg, skb, if_index);
>                 }
>         }
> -       if (!empty) {
> +       if (tss.ts[0] | tss.ts[2]) {

Same here.

Thanks,
Jason

>                 if (sock_flag(sk, SOCK_TSTAMP_NEW))
>                         put_cmsg_scm_timestamping64(msg, &tss);
>                 else
> --
> 2.53.0.473.g4a7958ca14-goog
>
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal
  2026-03-04  1:27 [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal Eric Dumazet
  2026-03-04  3:26 ` Willem de Bruijn
  2026-03-04  7:11 ` Jason Xing
@ 2026-03-05  2:40 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-03-05  2:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: davem, kuba, pabeni, horms, kuniyu, willemb, netdev, eric.dumazet

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Wed,  4 Mar 2026 01:27:47 +0000 you wrote:
> 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.
> 
> [...]

Here is the summary with links:
  - [net-next] net: use ktime_t in struct scm_timestamping_internal
    https://git.kernel.org/netdev/net-next/c/c66e0f453d1a

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal
  2026-03-04  7:11 ` Jason Xing
@ 2026-03-05  2:56   ` Eric Dumazet
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Dumazet @ 2026-03-05  2:56 UTC (permalink / raw)
  To: Jason Xing
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Kuniyuki Iwashima, Willem de Bruijn, netdev, eric.dumazet

On Wed, Mar 4, 2026 at 8:12 AM Jason Xing <kerneljasonxing@gmail.com> wrote:
>
> On Wed, Mar 4, 2026 at 9:30 AM Eric Dumazet <edumazet@google.com> wrote:
> >
> > -       if (has_timestamping) {
> > -               tss->ts[1] = (struct timespec64) {0};
> > +       if (tss->ts[0] | tss->ts[2]) {
>
> Maybe use tss->ts[0] || tss->ts[2]? It's a bit weird to use a single |
> as to readability.

This was done on purpose.
Code is more efficient, with a single conditional.

Thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-03-05  2:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-04  1:27 [PATCH net-next] net: use ktime_t in struct scm_timestamping_internal Eric Dumazet
2026-03-04  3:26 ` Willem de Bruijn
2026-03-04  7:11 ` Jason Xing
2026-03-05  2:56   ` Eric Dumazet
2026-03-05  2:40 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox