net: add a helper to avoid issues with HW TX timestamping and SO_TXTIME
authorVladimir Oltean <olteanv@gmail.com>
Wed, 10 Mar 2021 14:50:44 +0000 (16:50 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 10 Mar 2021 20:45:16 +0000 (12:45 -0800)
As explained in commit 29d98f54a4fe ("net: enetc: allow hardware
timestamping on TX queues with tc-etf enabled"), hardware TX
timestamping requires an skb with skb->tstamp = 0. When a packet is sent
with SO_TXTIME, the skb->skb_mstamp_ns corrupts the value of skb->tstamp,
so the drivers need to explicitly reset skb->tstamp to zero after
consuming the TX time.

Create a helper named skb_txtime_consumed() which does just that. All
drivers which offload TC_SETUP_QDISC_ETF should implement it, and it
would make it easier to assess during review whether they do the right
thing in order to be compatible with hardware timestamping or not.

Suggested-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/enetc/enetc.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igc/igc_main.c
include/net/pkt_sched.h

index 09471329f3a36ebaee687b105556f33ba22c1b5c..89d2cb348271f90df7cb22b89a67081c28fa82a2 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/vmalloc.h>
+#include <net/pkt_sched.h>
 
 /* ENETC overhead: optional extension BD + 1 BD gap */
 #define ENETC_TXBDS_NEEDED(val)        ((val) + 2)
@@ -344,12 +345,7 @@ static void enetc_tstamp_tx(struct sk_buff *skb, u64 tstamp)
        if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) {
                memset(&shhwtstamps, 0, sizeof(shhwtstamps));
                shhwtstamps.hwtstamp = ns_to_ktime(tstamp);
-               /* Ensure skb_mstamp_ns, which might have been populated with
-                * the txtime, is not mistaken for a software timestamp,
-                * because this will prevent the dispatch of our hardware
-                * timestamp to the socket.
-                */
-               skb->tstamp = ktime_set(0, 0);
+               skb_txtime_consumed(skb);
                skb_tstamp_tx(skb, &shhwtstamps);
        }
 }
index 878b31d534ec436a88269b9742b4899c653cea1b..369533feb4f2f371c4be36773c7d3356e03072d5 100644 (file)
@@ -5856,7 +5856,7 @@ static void igb_tx_ctxtdesc(struct igb_ring *tx_ring,
         */
        if (tx_ring->launchtime_enable) {
                ts = ktime_to_timespec64(first->skb->tstamp);
-               first->skb->tstamp = ktime_set(0, 0);
+               skb_txtime_consumed(first->skb);
                context_desc->seqnum_seed = cpu_to_le32(ts.tv_nsec / 32);
        } else {
                context_desc->seqnum_seed = 0;
index 7ac9597ddb84507c32bbd9ba5aed2561fb77a734..059ffcfb0bda252a4b4d1bc0f9f22f6e8c2023f8 100644 (file)
@@ -941,7 +941,7 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
                struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
                ktime_t txtime = first->skb->tstamp;
 
-               first->skb->tstamp = ktime_set(0, 0);
+               skb_txtime_consumed(first->skb);
                context_desc->launch_time = igc_tx_launchtime(adapter,
                                                              txtime);
        } else {
index 15b1b30f454e4837cd1fc07bb3ff6b4f178b1d39..f5c1bee0cd6ac94440f4b62fe066a065b8c2d70f 100644 (file)
@@ -188,4 +188,13 @@ struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload
                                                  *offload);
 void taprio_offload_free(struct tc_taprio_qopt_offload *offload);
 
+/* Ensure skb_mstamp_ns, which might have been populated with the txtime, is
+ * not mistaken for a software timestamp, because this will otherwise prevent
+ * the dispatch of hardware timestamps to the socket.
+ */
+static inline void skb_txtime_consumed(struct sk_buff *skb)
+{
+       skb->tstamp = ktime_set(0, 0);
+}
+
 #endif