netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kurt Kanzenbach <kurt@linutronix.de>
To: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>,
	Przemek Kitszel <przemyslaw.kitszel@intel.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Jesper Dangaard Brouer <hawk@kernel.org>,
	John Fastabend <john.fastabend@gmail.com>,
	Richard Cochran <richardcochran@gmail.com>,
	Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>,
	Benjamin Steinke <benjamin.steinke@woks-audio.com>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org,
	bpf@vger.kernel.org,
	Sriram Yagnaraman <sriram.yagnaraman@est.tech>
Subject: Re: [PATCH iwl-next v8 6/6] igb: Add AF_XDP zero-copy Tx support
Date: Tue, 15 Oct 2024 19:16:25 +0200	[thread overview]
Message-ID: <875xptnv6e.fsf@kurt.kurt.home> (raw)
In-Reply-To: <Zw5uBZa7+Iy5qD1t@boxer>

[-- Attachment #1: Type: text/plain, Size: 8670 bytes --]

On Tue Oct 15 2024, Maciej Fijalkowski wrote:
> On Fri, Oct 11, 2024 at 11:01:04AM +0200, Kurt Kanzenbach wrote:
>> From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
>> 
>> Add support for AF_XDP zero-copy transmit path.
>> 
>> A new TX buffer type IGB_TYPE_XSK is introduced to indicate that the Tx
>> frame was allocated from the xsk buff pool, so igb_clean_tx_ring() and
>> igb_clean_tx_irq() can clean the buffers correctly based on type.
>> 
>> igb_xmit_zc() performs the actual packet transmit when AF_XDP zero-copy is
>> enabled. We share the TX ring between slow path, XDP and AF_XDP
>> zero-copy, so we use the netdev queue lock to ensure mutual exclusion.
>> 
>> Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
>> [Kurt: Set olinfo_status in igb_xmit_zc() so that frames are transmitted,
>>        Use READ_ONCE() for xsk_pool and check Tx disabled and carrier in
>>        igb_xmit_zc(), Add FIXME for RS bit]
>> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
>> Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
>> ---
>>  drivers/net/ethernet/intel/igb/igb.h      |  2 +
>>  drivers/net/ethernet/intel/igb/igb_main.c | 61 ++++++++++++++++++++++++-----
>>  drivers/net/ethernet/intel/igb/igb_xsk.c  | 64 +++++++++++++++++++++++++++++++
>>  3 files changed, 117 insertions(+), 10 deletions(-)
>> 
>> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
>> index e4a85867aa18..f6ac74327bb3 100644
>> --- a/drivers/net/ethernet/intel/igb/igb.h
>> +++ b/drivers/net/ethernet/intel/igb/igb.h
>> @@ -258,6 +258,7 @@ enum igb_tx_flags {
>>  enum igb_tx_buf_type {
>>  	IGB_TYPE_SKB = 0,
>>  	IGB_TYPE_XDP,
>> +	IGB_TYPE_XSK
>>  };
>>  
>>  /* wrapper around a pointer to a socket buffer,
>> @@ -859,6 +860,7 @@ bool igb_alloc_rx_buffers_zc(struct igb_ring *rx_ring,
>>  void igb_clean_rx_ring_zc(struct igb_ring *rx_ring);
>>  int igb_clean_rx_irq_zc(struct igb_q_vector *q_vector,
>>  			struct xsk_buff_pool *xsk_pool, const int budget);
>> +bool igb_xmit_zc(struct igb_ring *tx_ring);
>>  int igb_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags);
>>  
>>  #endif /* _IGB_H_ */
>> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
>> index 711b60cab594..5f396c02e3b9 100644
>> --- a/drivers/net/ethernet/intel/igb/igb_main.c
>> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
>> @@ -2979,6 +2979,9 @@ static int igb_xdp_xmit(struct net_device *dev, int n,
>>  	if (unlikely(!tx_ring))
>>  		return -ENXIO;
>>  
>> +	if (unlikely(test_bit(IGB_RING_FLAG_TX_DISABLED, &tx_ring->flags)))
>> +		return -ENXIO;
>> +
>>  	nq = txring_txq(tx_ring);
>>  	__netif_tx_lock(nq, cpu);
>>  
>> @@ -3326,7 +3329,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>>  	netdev->priv_flags |= IFF_SUPP_NOFCS;
>>  
>>  	netdev->priv_flags |= IFF_UNICAST_FLT;
>> -	netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT;
>> +	netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
>> +			       NETDEV_XDP_ACT_XSK_ZEROCOPY;
>>  
>>  	/* MTU range: 68 - 9216 */
>>  	netdev->min_mtu = ETH_MIN_MTU;
>> @@ -4900,15 +4904,20 @@ void igb_clean_tx_ring(struct igb_ring *tx_ring)
>>  {
>>  	u16 i = tx_ring->next_to_clean;
>>  	struct igb_tx_buffer *tx_buffer = &tx_ring->tx_buffer_info[i];
>> +	u32 xsk_frames = 0;
>>  
>>  	while (i != tx_ring->next_to_use) {
>>  		union e1000_adv_tx_desc *eop_desc, *tx_desc;
>>  
>>  		/* Free all the Tx ring sk_buffs or xdp frames */
>> -		if (tx_buffer->type == IGB_TYPE_SKB)
>> +		if (tx_buffer->type == IGB_TYPE_SKB) {
>>  			dev_kfree_skb_any(tx_buffer->skb);
>> -		else
>> +		} else if (tx_buffer->type == IGB_TYPE_XDP) {
>>  			xdp_return_frame(tx_buffer->xdpf);
>> +		} else if (tx_buffer->type == IGB_TYPE_XSK) {
>> +			xsk_frames++;
>> +			goto skip_for_xsk;
>> +		}
>>  
>>  		/* unmap skb header data */
>>  		dma_unmap_single(tx_ring->dev,
>> @@ -4939,6 +4948,7 @@ void igb_clean_tx_ring(struct igb_ring *tx_ring)
>>  					       DMA_TO_DEVICE);
>>  		}
>>  
>> +skip_for_xsk:
>>  		tx_buffer->next_to_watch = NULL;
>>  
>>  		/* move us one more past the eop_desc for start of next pkt */
>> @@ -4953,6 +4963,9 @@ void igb_clean_tx_ring(struct igb_ring *tx_ring)
>>  	/* reset BQL for queue */
>>  	netdev_tx_reset_queue(txring_txq(tx_ring));
>>  
>> +	if (tx_ring->xsk_pool && xsk_frames)
>> +		xsk_tx_completed(tx_ring->xsk_pool, xsk_frames);
>> +
>>  	/* reset next_to_use and next_to_clean */
>>  	tx_ring->next_to_use = 0;
>>  	tx_ring->next_to_clean = 0;
>> @@ -6486,6 +6499,9 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
>>  		return NETDEV_TX_BUSY;
>>  	}
>>  
>> +	if (unlikely(test_bit(IGB_RING_FLAG_TX_DISABLED, &tx_ring->flags)))
>> +		return NETDEV_TX_BUSY;
>> +
>>  	/* record the location of the first descriptor for this packet */
>>  	first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
>>  	first->type = IGB_TYPE_SKB;
>> @@ -8260,13 +8276,18 @@ static int igb_poll(struct napi_struct *napi, int budget)
>>   **/
>>  static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
>>  {
>> -	struct igb_adapter *adapter = q_vector->adapter;
>> -	struct igb_ring *tx_ring = q_vector->tx.ring;
>> -	struct igb_tx_buffer *tx_buffer;
>> -	union e1000_adv_tx_desc *tx_desc;
>>  	unsigned int total_bytes = 0, total_packets = 0;
>> +	struct igb_adapter *adapter = q_vector->adapter;
>>  	unsigned int budget = q_vector->tx.work_limit;
>> +	struct igb_ring *tx_ring = q_vector->tx.ring;
>>  	unsigned int i = tx_ring->next_to_clean;
>> +	union e1000_adv_tx_desc *tx_desc;
>> +	struct igb_tx_buffer *tx_buffer;
>> +	struct xsk_buff_pool *xsk_pool;
>> +	int cpu = smp_processor_id();
>> +	bool xsk_xmit_done = true;
>> +	struct netdev_queue *nq;
>> +	u32 xsk_frames = 0;
>>  
>>  	if (test_bit(__IGB_DOWN, &adapter->state))
>>  		return true;
>> @@ -8297,10 +8318,14 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
>>  		total_packets += tx_buffer->gso_segs;
>>  
>>  		/* free the skb */
>> -		if (tx_buffer->type == IGB_TYPE_SKB)
>> +		if (tx_buffer->type == IGB_TYPE_SKB) {
>>  			napi_consume_skb(tx_buffer->skb, napi_budget);
>> -		else
>> +		} else if (tx_buffer->type == IGB_TYPE_XDP) {
>>  			xdp_return_frame(tx_buffer->xdpf);
>> +		} else if (tx_buffer->type == IGB_TYPE_XSK) {
>> +			xsk_frames++;
>> +			goto skip_for_xsk;
>> +		}
>>  
>>  		/* unmap skb header data */
>>  		dma_unmap_single(tx_ring->dev,
>> @@ -8332,6 +8357,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
>>  			}
>>  		}
>>  
>> +skip_for_xsk:
>>  		/* move us one more past the eop_desc for start of next pkt */
>>  		tx_buffer++;
>>  		tx_desc++;
>> @@ -8360,6 +8386,21 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
>>  	q_vector->tx.total_bytes += total_bytes;
>>  	q_vector->tx.total_packets += total_packets;
>>  
>> +	xsk_pool = READ_ONCE(tx_ring->xsk_pool);
>> +	if (xsk_pool) {
>> +		if (xsk_frames)
>> +			xsk_tx_completed(xsk_pool, xsk_frames);
>> +		if (xsk_uses_need_wakeup(xsk_pool))
>> +			xsk_set_tx_need_wakeup(xsk_pool);
>> +
>> +		nq = txring_txq(tx_ring);
>> +		__netif_tx_lock(nq, cpu);
>> +		/* Avoid transmit queue timeout since we share it with the slow path */
>> +		txq_trans_cond_update(nq);
>> +		xsk_xmit_done = igb_xmit_zc(tx_ring);
>> +		__netif_tx_unlock(nq);
>> +	}
>> +
>>  	if (test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
>>  		struct e1000_hw *hw = &adapter->hw;
>>  
>> @@ -8422,7 +8463,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget)
>>  		}
>>  	}
>>  
>> -	return !!budget;
>> +	return !!budget && xsk_xmit_done;
>>  }
>>  
>>  /**
>> diff --git a/drivers/net/ethernet/intel/igb/igb_xsk.c b/drivers/net/ethernet/intel/igb/igb_xsk.c
>> index 22d234db0fab..d962c5e22b71 100644
>> --- a/drivers/net/ethernet/intel/igb/igb_xsk.c
>> +++ b/drivers/net/ethernet/intel/igb/igb_xsk.c
>> @@ -465,6 +465,70 @@ int igb_clean_rx_irq_zc(struct igb_q_vector *q_vector,
>>  	return failure ? budget : (int)total_packets;
>>  }
>>  
>> +bool igb_xmit_zc(struct igb_ring *tx_ring)
>> +{
>> +	unsigned int budget = igb_desc_unused(tx_ring);
>> +	struct xsk_buff_pool *pool = tx_ring->xsk_pool;
>
> Ughh that's another read of pool ptr, you should have passed it by arg to
> igb_xmit_zc()...

Ups, missed that somehow. Thanks!

Thanks,
Kurt

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]

      reply	other threads:[~2024-10-15 17:16 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-11  9:00 [PATCH iwl-next v8 0/6] igb: Add support for AF_XDP zero-copy Kurt Kanzenbach
2024-10-11  9:00 ` [PATCH iwl-next v8 1/6] igb: Remove static qualifiers Kurt Kanzenbach
2024-10-11  9:01 ` [PATCH iwl-next v8 2/6] igb: Introduce igb_xdp_is_enabled() Kurt Kanzenbach
2024-10-11  9:01 ` [PATCH iwl-next v8 3/6] igb: Introduce XSK data structures and helpers Kurt Kanzenbach
2024-10-11  9:01 ` [PATCH iwl-next v8 4/6] igb: Add XDP finalize and stats update functions Kurt Kanzenbach
2024-10-15 12:05   ` Maciej Fijalkowski
2024-10-11  9:01 ` [PATCH iwl-next v8 5/6] igb: Add AF_XDP zero-copy Rx support Kurt Kanzenbach
2024-10-15 12:15   ` Maciej Fijalkowski
2024-10-11  9:01 ` [PATCH iwl-next v8 6/6] igb: Add AF_XDP zero-copy Tx support Kurt Kanzenbach
2024-10-15 13:28   ` Maciej Fijalkowski
2024-10-15 17:16     ` Kurt Kanzenbach [this message]

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=875xptnv6e.fsf@kurt.kurt.home \
    --to=kurt@linutronix.de \
    --cc=anthony.l.nguyen@intel.com \
    --cc=ast@kernel.org \
    --cc=benjamin.steinke@woks-audio.com \
    --cc=bigeasy@linutronix.de \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=hawk@kernel.org \
    --cc=intel-wired-lan@lists.osuosl.org \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=maciej.fijalkowski@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=przemyslaw.kitszel@intel.com \
    --cc=richardcochran@gmail.com \
    --cc=sriram.yagnaraman@ericsson.com \
    --cc=sriram.yagnaraman@est.tech \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).