diff mbox series

[2/3] Pass TX sending hardware timestamp to a socket's buffer.

Message ID 20201209143707.13503-3-erez.geva.ext@siemens.com
State Superseded
Headers show
Series Add sending TX hardware timestamp for TC ETF Qdisc | expand

Commit Message

Geva, Erez Dec. 9, 2020, 2:37 p.m. UTC
Pass TX sending hardware timestamp from the socket layer to
 a socket's buffer. The TC ETC Qdisc will pass it
 to the interface network driver.

 - Add the hardware timestamp to the IP cork, to support
   the use of IP/UDP with the TX sending hardware timestamp
   when sending through the TC ETF Qdisc
 - Pass the TX sending hardware timestamp to a socket's buffer
   using the hardware timestamp on the socket's buffer shared information.

 Note: The socket buffer's hardware timestamp is used by
       the network interface driver to send the actual sending timestamp
       back to the application.
       The timestamp is used by the TC ETF before the buffer
       arrives in the network interface driver.

Signed-off-by: Erez Geva <erez.geva.ext@siemens.com>
---
 include/net/inet_sock.h | 1 +
 net/ipv4/ip_output.c    | 2 ++
 net/ipv4/raw.c          | 1 +
 net/ipv6/ip6_output.c   | 2 ++
 net/ipv6/raw.c          | 1 +
 net/packet/af_packet.c  | 3 +++
 6 files changed, 10 insertions(+)
diff mbox series

Patch

diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 89163ef8cf4b..e74e8dabf63d 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -160,6 +160,7 @@  struct inet_cork {
 	char			priority;
 	__u16			gso_size;
 	u64			transmit_time;
+	u64			transmit_hw_time;
 	u32			mark;
 };
 
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 879b76ae4435..416598c864e3 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1282,6 +1282,7 @@  static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
 	cork->mark = ipc->sockc.mark;
 	cork->priority = ipc->priority;
 	cork->transmit_time = ipc->sockc.transmit_time;
+	cork->transmit_hw_time = ipc->sockc.transmit_hw_time;
 	cork->tx_flags = 0;
 	sock_tx_timestamp(sk, ipc->sockc.tsflags, &cork->tx_flags);
 
@@ -1545,6 +1546,7 @@  struct sk_buff *__ip_make_skb(struct sock *sk,
 	skb->priority = (cork->tos != -1) ? cork->priority: sk->sk_priority;
 	skb->mark = cork->mark;
 	skb->tstamp = cork->transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(cork->transmit_hw_time);
 	/*
 	 * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec
 	 * on dst refcount
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 7d26e0f8bdae..213a47fb2df8 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -378,6 +378,7 @@  static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
 	skb->priority = sk->sk_priority;
 	skb->mark = sockc->mark;
 	skb->tstamp = sockc->transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(sockc->transmit_hw_time);
 	skb_dst_set(skb, &rt->dst);
 	*rtp = NULL;
 
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 749ad72386b2..8cff05f5aa8a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1375,6 +1375,7 @@  static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
 	cork->base.length = 0;
 
 	cork->base.transmit_time = ipc6->sockc.transmit_time;
+	cork->base.transmit_hw_time = ipc6->sockc.transmit_hw_time;
 
 	return 0;
 }
@@ -1841,6 +1842,7 @@  struct sk_buff *__ip6_make_skb(struct sock *sk,
 	skb->mark = cork->base.mark;
 
 	skb->tstamp = cork->base.transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(cork->base.transmit_hw_time);
 
 	skb_dst_set(skb, dst_clone(&rt->dst));
 	IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 6e4ab80a3b94..417f21867782 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -648,6 +648,7 @@  static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
 	skb->priority = sk->sk_priority;
 	skb->mark = sockc->mark;
 	skb->tstamp = sockc->transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(sockc->transmit_hw_time);
 
 	skb_put(skb, length);
 	skb_reset_network_header(skb);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 7a18ffff8551..c762d5bcecc2 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1986,6 +1986,7 @@  static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg,
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
 	skb->tstamp = sockc.transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(sockc.transmit_hw_time);
 
 	skb_setup_tx_timestamp(skb, sockc.tsflags);
 
@@ -2500,6 +2501,7 @@  static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 	skb->priority = po->sk.sk_priority;
 	skb->mark = po->sk.sk_mark;
 	skb->tstamp = sockc->transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(sockc->transmit_hw_time);
 	skb_setup_tx_timestamp(skb, sockc->tsflags);
 	skb_zcopy_set_nouarg(skb, ph.raw);
 
@@ -2975,6 +2977,7 @@  static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 	skb->priority = sk->sk_priority;
 	skb->mark = sockc.mark;
 	skb->tstamp = sockc.transmit_time;
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(sockc.transmit_hw_time);
 
 	if (has_vnet_hdr) {
 		err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());