[PATCH 1/3] Add TX sending hardware timestamp.

From: Erez Geva
Date: Wed Dec 09 2020 - 10:43:33 EST


Configure and send TX sending hardware timestamp from
user space application to the socket layer,
to provide to the TC ETC Qdisc, and pass it to
the interface network driver.

- New flag for the SO_TXTIME socket option.
- New access auxiliary data header to pass the
TX sending hardware timestamp.
- Add the hardware timestamp to the socket cookie.
- Copy the TX sending hardware timestamp to the socket cookie.

Signed-off-by: Erez Geva <erez.geva.ext@xxxxxxxxxxx>
---
include/net/sock.h | 2 ++
include/uapi/asm-generic/socket.h | 3 +++
include/uapi/linux/net_tstamp.h | 3 ++-
net/core/sock.c | 9 +++++++++
4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index a5c6ae78df77..dd5bfd42b4e2 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -859,6 +859,7 @@ enum sock_flags {
SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */
SOCK_TXTIME,
+ SOCK_HW_TXTIME,
SOCK_XDP, /* XDP is attached */
SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */
};
@@ -1690,6 +1691,7 @@ void sk_send_sigurg(struct sock *sk);

struct sockcm_cookie {
u64 transmit_time;
+ u64 transmit_hw_time;
u32 mark;
u16 tsflags;
};
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 77f7c1638eb1..16265b00c25a 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -119,6 +119,9 @@

#define SO_DETACH_REUSEPORT_BPF 68

+#define SO_HW_TXTIME 69
+#define SCM_HW_TXTIME SO_HW_TXTIME
+
#if !defined(__KERNEL__)

#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h
index 7ed0b3d1c00a..dd51c9a99b1f 100644
--- a/include/uapi/linux/net_tstamp.h
+++ b/include/uapi/linux/net_tstamp.h
@@ -162,8 +162,9 @@ struct scm_ts_pktinfo {
enum txtime_flags {
SOF_TXTIME_DEADLINE_MODE = (1 << 0),
SOF_TXTIME_REPORT_ERRORS = (1 << 1),
+ SOF_TXTIME_USE_HW_TIMESTAMP = (1 << 2),

- SOF_TXTIME_FLAGS_LAST = SOF_TXTIME_REPORT_ERRORS,
+ SOF_TXTIME_FLAGS_LAST = SOF_TXTIME_USE_HW_TIMESTAMP,
SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_FLAGS_LAST - 1) |
SOF_TXTIME_FLAGS_LAST
};
diff --git a/net/core/sock.c b/net/core/sock.c
index 727ea1cc633c..317dce54321b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1227,6 +1227,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
sock_valbool_flag(sk, SOCK_TXTIME, true);
+ sock_valbool_flag(sk, SOCK_HW_TXTIME,
+ sk_txtime.flags & SOF_TXTIME_USE_HW_TIMESTAMP);
sk->sk_clockid = sk_txtime.clockid;
sk->sk_txtime_deadline_mode =
!!(sk_txtime.flags & SOF_TXTIME_DEADLINE_MODE);
@@ -2378,6 +2380,13 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
return -EINVAL;
sockc->transmit_time = get_unaligned((u64 *)CMSG_DATA(cmsg));
break;
+ case SCM_HW_TXTIME:
+ if (!sock_flag(sk, SOCK_HW_TXTIME))
+ return -EINVAL;
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(u64)))
+ return -EINVAL;
+ sockc->transmit_hw_time = get_unaligned((u64 *)CMSG_DATA(cmsg));
+ break;
/* SCM_RIGHTS and SCM_CREDENTIALS are semantically in SOL_UNIX. */
case SCM_RIGHTS:
case SCM_CREDENTIALS:
--
2.20.1