Hi Yangbo,
Pls add the [net-next] prefix to the subject of these patches next time, to avoid the patchwork warnings and let reviewers know where to apply them.

On 26.03.2021 10:35, Yangbo Lu wrote:
[...]> +netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+       struct enetc_ndev_priv *priv = netdev_priv(ndev);
+       u8 udp, msgtype, twostep;
+       u16 offset1, offset2;
+
+       /* Mark tx timestamp type on skb->cb[0] if requires */
+       if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+           (priv->active_offloads & ENETC_F_TX_TSTAMP_MASK)) {
+               skb->cb[0] = priv->active_offloads & ENETC_F_TX_TSTAMP_MASK;
+       } else {
+               skb->cb[0] = 0;
+       }
+
+       if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
+               /* For one-step PTP sync packet, queue it */
+               if (!enetc_ptp_parse(skb, &udp, &msgtype, &twostep,
+                                    &offset1, &offset2)) {
+                       if (msgtype == PTP_MSGTYPE_SYNC && twostep == 0) {
+                               skb_queue_tail(&priv->tx_skbs, skb);
+                               queue_work(priv->enetc_ptp_wq,
+                                          &priv->tx_onestep_tstamp);
+                               return NETDEV_TX_OK;
+                       }
+               }
+
+               /* Fall back to two-step timestamp for other packets */
+               skb->cb[0] = ENETC_F_TX_TSTAMP;
+       }
+
+       return enetc_start_xmit(skb, ndev);
+}
+
[...]
+static void enetc_tx_onestep_tstamp(struct work_struct *work)
+{
+       struct enetc_ndev_priv *priv;
+       struct sk_buff *skb;
+
+       priv = container_of(work, struct enetc_ndev_priv, tx_onestep_tstamp);
+
+       while (true) {
+               skb = skb_dequeue(&priv->tx_skbs);
+               if (!skb)
+                       return;
+
+               /* Lock before TX one-step timestamping packet, and release
+                * when the packet has been sent on hardware, or transmit
+                * failure.
+                */
+               mutex_lock(&priv->onestep_tstamp_lock);
+               enetc_start_xmit(skb, priv->ndev);
+       }
+}
+
What happens if the work queue tries to send the ptp packet concurrently with a regular packet being sent by the stack, via .ndo_start_xmit? If both skbs are targetting the same tx_ring then we have a concurrency problem, as enetc_map_tx_buffs(tx_ring, skb) is not thread safe!

Regards,
Claudiu

Reply via email to