All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: Yangbo Lu <yangbo.lu@nxp.com>
Cc: netdev@vger.kernel.org, "David S . Miller" <davem@davemloft.net>,
	Richard Cochran <richardcochran@gmail.com>,
	Claudiu Manoil <claudiu.manoil@nxp.com>,
	Vladimir Oltean <vladimir.oltean@nxp.com>,
	Russell King <linux@armlinux.org.uk>
Subject: Re: [net-next, v2, 2/2] enetc: support PTP Sync packet one-step timestamping
Date: Thu, 8 Apr 2021 09:02:50 -0700	[thread overview]
Message-ID: <20210408090250.21dee5c6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> (raw)
In-Reply-To: <20210408111350.3817-3-yangbo.lu@nxp.com>

On Thu,  8 Apr 2021 19:13:50 +0800 Yangbo Lu wrote:
> This patch is to add support for PTP Sync packet one-step timestamping.
> Since ENETC single-step register has to be configured dynamically per
> packet for correctionField offeset and UDP checksum update, current
> one-step timestamping packet has to be sent only when the last one
> completes transmitting on hardware. So, on the TX below things are done
> by the patch:
> 
> - For one-step timestamping packet, queue to skb queue.
> - Start a work to transmit skbs in queue.
> - For other skbs, transmit immediately.
> - mutex lock used to ensure the last one-step timestamping packet has
>   already been transmitted on hardware before transmitting current one.
> 
> And the configuration for one-step timestamping on ENETC before
> transmitting is,
> 
> - Set one-step timestamping flag in extension BD.
> - Write 30 bits current timestamp in tstamp field of extension BD.
> - Update PTP Sync packet originTimestamp field with current timestamp.
> - Configure single-step register for correctionField offeset and UDP
>   checksum update.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

> @@ -432,9 +544,12 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget)
>  			xdp_return_frame(xdp_frame);
>  			tx_swbd->xdp_frame = NULL;
>  		} else if (skb) {
> -			if (unlikely(do_tstamp)) {
> +			if (unlikely(tx_swbd->skb->cb[0] &
> +				     ENETC_F_TX_ONESTEP_SYNC_TSTAMP)) {
> +				mutex_unlock(&priv->onestep_tstamp_lock);
> +			} else if (unlikely(do_twostep_tstamp)) {
>  				enetc_tstamp_tx(skb, tstamp);
> -				do_tstamp = false;
> +				do_twostep_tstamp = false;
>  			}
>  			napi_consume_skb(skb, napi_budget);
>  			tx_swbd->skb = NULL;
> @@ -1863,6 +1978,47 @@ static int enetc_phylink_connect(struct net_device *ndev)
>  	return 0;
>  }
>  
> +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);

Using a lock to wake up a producer is not a great idea. It usually
breaks advanced features like priority inheritance. Probably doesn't
matter for a struct mutex, but I think it may still make lockdep
complain.

Why not make it work with a flag?

start_xmit:

	if (skb->cb[0] & ONESTEP) {
		if (priv->flags & ONESTEP_BUSY) {
			skb_queue_tail(&priv->tx_skbs, skb);
			return ...;
		}
		priv->flags |= ONESTEP_BUSY;
	}

clean_tx:

	/* don't clear ONESTEP_BUSY, we need the tx lock */
	if (skb->cb[0] & ONESTEP)
		queue_work(...);

work:

	netif_tx_lock()
	skb = skb_dequeue();
	if (skb)
		start_xmit(skb)
	else
		priv->flags &= ~ONESTEP_BUSY;
	netif_tx_unlock()

> +		netif_tx_lock(priv->ndev);
> +		enetc_start_xmit(skb, priv->ndev);
> +		netif_tx_unlock(priv->ndev);
> +	}
> +}
> +
> +static int enetc_tx_onestep_tstamp_init(struct enetc_ndev_priv *priv)
> +{
> +	priv->enetc_ptp_wq = alloc_workqueue("enetc_ptp_wq", 0, 0);
> +	if (!priv->enetc_ptp_wq)
> +		return -ENOMEM;
> +
> +	INIT_WORK(&priv->tx_onestep_tstamp, enetc_tx_onestep_tstamp);
> +	skb_queue_head_init(&priv->tx_skbs);
> +
> +	return 0;
> +}
> +
> +static void enetc_tx_onestep_tstamp_deinit(struct enetc_ndev_priv *priv)
> +{
> +	destroy_workqueue(priv->enetc_ptp_wq);
> +}

Why allocate a separate workqueue for one work? You can queue your
work on the system workqueue.

  reply	other threads:[~2021-04-08 16:02 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-08 11:13 [net-next, v2, 0/2] enetc: support PTP Sync packet one-step timestamping Yangbo Lu
2021-04-08 11:13 ` [net-next, v2, 1/2] enetc: mark TX timestamp type per skb Yangbo Lu
2021-04-08 11:13 ` [net-next, v2, 2/2] enetc: support PTP Sync packet one-step timestamping Yangbo Lu
2021-04-08 16:02   ` Jakub Kicinski [this message]
2021-04-08 16:07     ` Jakub Kicinski
2021-04-09  6:37       ` Claudiu Manoil
2021-04-09 16:09         ` Jakub Kicinski
2021-04-09 19:32           ` Claudiu Manoil
2021-04-09 19:44             ` Jakub Kicinski
2021-04-12  9:15               ` Y.b. Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210408090250.21dee5c6@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com \
    --to=kuba@kernel.org \
    --cc=claudiu.manoil@nxp.com \
    --cc=davem@davemloft.net \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=richardcochran@gmail.com \
    --cc=vladimir.oltean@nxp.com \
    --cc=yangbo.lu@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.