Hi

Can it just move

 skb->tstamp = ktime_set(0, 0);  

into 

skb_tstamp_tx(skb, &shhwtstamps);

if it always need to clear for HW tstamp setting.


> -----Original Message-----
> From: Vladimir Oltean <olte...@gmail.com>
> Sent: 2021年3月10日 22:51
> To: Jakub Kicinski <k...@kernel.org>; netdev@vger.kernel.org; Po Liu
> <po....@nxp.com>; Claudiu Manoil <claudiu.man...@nxp.com>
> Cc: Vinicius Costa Gomes <vinicius.go...@intel.com>; Richard Cochran
> <richardcoch...@gmail.com>
> Subject: [PATCH net-next] net: add a helper to avoid issues with HW TX
> timestamping and SO_TXTIME
> 
> Caution: EXT Email
> 
> 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.go...@intel.com>
> Signed-off-by: Vladimir Oltean <vladimir.olt...@nxp.com>
> ---
>  drivers/net/ethernet/freescale/enetc/enetc.c | 8 ++------
>  drivers/net/ethernet/intel/igb/igb_main.c    | 2 +-
>  drivers/net/ethernet/intel/igc/igc_main.c    | 2 +-
>  include/net/pkt_sched.h                      | 9 +++++++++
>  4 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c
> b/drivers/net/ethernet/freescale/enetc/enetc.c
> index e85dfccb9ed1..5a54976e6a28 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc.c
> @@ -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)
> @@ -293,12 +294,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);
>         }
>  }
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c
> b/drivers/net/ethernet/intel/igb/igb_main.c
> index 878b31d534ec..369533feb4f2 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -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; diff --git
> a/drivers/net/ethernet/intel/igc/igc_main.c
> b/drivers/net/ethernet/intel/igc/igc_main.c
> index 7ac9597ddb84..059ffcfb0bda 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -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 {
> diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index
> 15b1b30f454e..f5c1bee0cd6a 100644
> --- a/include/net/pkt_sched.h
> +++ b/include/net/pkt_sched.h
> @@ -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
> --
> 2.25.1



Br,
Po Liu


Reply via email to