RE: [PATCH V2,net-next, 2/3] net: mana: Enable RX path to handle various MTU sizes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Jacob Keller <jacob.e.keller@xxxxxxxxx>
> Sent: Tuesday, April 11, 2023 7:11 PM
> To: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx>; linux-hyperv@xxxxxxxxxxxxxxx;
> netdev@xxxxxxxxxxxxxxx
> Cc: Dexuan Cui <decui@xxxxxxxxxxxxx>; KY Srinivasan <kys@xxxxxxxxxxxxx>;
> Paul Rosswurm <paulros@xxxxxxxxxxxxx>; olaf@xxxxxxxxx;
> vkuznets@xxxxxxxxxx; davem@xxxxxxxxxxxxx; wei.liu@xxxxxxxxxx;
> edumazet@xxxxxxxxxx; kuba@xxxxxxxxxx; pabeni@xxxxxxxxxx;
> leon@xxxxxxxxxx; Long Li <longli@xxxxxxxxxxxxx>;
> ssengar@xxxxxxxxxxxxxxxxxxx; linux-rdma@xxxxxxxxxxxxxxx;
> daniel@xxxxxxxxxxxxx; john.fastabend@xxxxxxxxx; bpf@xxxxxxxxxxxxxxx;
> ast@xxxxxxxxxx; Ajay Sharma <sharmaajay@xxxxxxxxxxxxx>;
> hawk@xxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
> Subject: Re: [PATCH V2,net-next, 2/3] net: mana: Enable RX path to handle
> various MTU sizes
> 
> 
> 
> On 4/7/2023 1:59 PM, Haiyang Zhang wrote:
> > Update RX data path to allocate and use RX queue DMA buffers with
> > proper size based on potentially various MTU sizes.
> >
> > Signed-off-by: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx>
> >
> > ---
> > V2:
> > Refectored to multiple patches for readability. Suggested by Yunsheng Lin.
> >
> > ---
> >  drivers/net/ethernet/microsoft/mana/mana_en.c | 188 +++++++++++------
> -
> >  include/net/mana/mana.h                       |  13 +-
> >  2 files changed, 124 insertions(+), 77 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > index 112c642dc89b..e5d5dea763f2 100644
> > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> > @@ -1185,10 +1185,10 @@ static void mana_post_pkt_rxq(struct
> mana_rxq *rxq)
> >  	WARN_ON_ONCE(recv_buf_oob->wqe_inf.wqe_size_in_bu != 1);
> >  }
> >
> > -static struct sk_buff *mana_build_skb(void *buf_va, uint pkt_len,
> > -				      struct xdp_buff *xdp)
> > +static struct sk_buff *mana_build_skb(struct mana_rxq *rxq, void *buf_va,
> > +				      uint pkt_len, struct xdp_buff *xdp)
> >  {
> > -	struct sk_buff *skb = napi_build_skb(buf_va, PAGE_SIZE);
> > +	struct sk_buff *skb = napi_build_skb(buf_va, rxq->alloc_size);
> >
> >  	if (!skb)
> >  		return NULL;
> > @@ -1196,11 +1196,12 @@ static struct sk_buff *mana_build_skb(void
> *buf_va, uint pkt_len,
> >  	if (xdp->data_hard_start) {
> >  		skb_reserve(skb, xdp->data - xdp->data_hard_start);
> >  		skb_put(skb, xdp->data_end - xdp->data);
> > -	} else {
> > -		skb_reserve(skb, XDP_PACKET_HEADROOM);
> > -		skb_put(skb, pkt_len);
> > +		return skb;
> >  	}
> >
> > +	skb_reserve(skb, rxq->headroom);
> > +	skb_put(skb, pkt_len);
> > +
> >  	return skb;
> >  }
> >
> > @@ -1233,7 +1234,7 @@ static void mana_rx_skb(void *buf_va, struct
> mana_rxcomp_oob *cqe,
> >  	if (act != XDP_PASS && act != XDP_TX)
> >  		goto drop_xdp;
> >
> > -	skb = mana_build_skb(buf_va, pkt_len, &xdp);
> > +	skb = mana_build_skb(rxq, buf_va, pkt_len, &xdp);
> >
> >  	if (!skb)
> >  		goto drop;
> > @@ -1282,14 +1283,72 @@ static void mana_rx_skb(void *buf_va, struct
> mana_rxcomp_oob *cqe,
> >  	u64_stats_update_end(&rx_stats->syncp);
> >
> >  drop:
> > -	WARN_ON_ONCE(rxq->xdp_save_page);
> > -	rxq->xdp_save_page = virt_to_page(buf_va);
> > +	WARN_ON_ONCE(rxq->xdp_save_va);
> > +	/* Save for reuse */
> > +	rxq->xdp_save_va = buf_va;
> >
> >  	++ndev->stats.rx_dropped;
> >
> >  	return;
> >  }
> >
> > +static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
> > +			     dma_addr_t *da, bool is_napi)
> > +{
> > +	struct page *page;
> > +	void *va;
> > +
> > +	/* Reuse XDP dropped page if available */
> > +	if (rxq->xdp_save_va) {
> > +		va = rxq->xdp_save_va;
> > +		rxq->xdp_save_va = NULL;
> > +	} else if (rxq->alloc_size > PAGE_SIZE) {
> > +		if (is_napi)
> > +			va = napi_alloc_frag(rxq->alloc_size);
> > +		else
> > +			va = netdev_alloc_frag(rxq->alloc_size);
> > +
> > +		if (!va)
> > +			return NULL;
> > +	} else {
> > +		page = dev_alloc_page();
> > +		if (!page)
> > +			return NULL;
> > +
> > +		va = page_to_virt(page);
> > +	}
> > +
> > +	*da = dma_map_single(dev, va + rxq->headroom, rxq->datasize,
> > +			     DMA_FROM_DEVICE);
> > +
> > +	if (dma_mapping_error(dev, *da)) {
> > +		put_page(virt_to_head_page(va));
> > +		return NULL;
> > +	}
> > +
> > +	return va;
> > +}
> > +
> > +/* Allocate frag for rx buffer, and save the old buf */
> > +static void mana_refill_rxoob(struct device *dev, struct mana_rxq *rxq,
> > +			      struct mana_recv_buf_oob *rxoob, void
> **old_buf)
> > +{
> > +	dma_addr_t da;
> > +	void *va;
> > +
> > +	va = mana_get_rxfrag(rxq, dev, &da, true);
> > +
> > +	if (!va)
> > +		return;
> > +
> > +	dma_unmap_single(dev, rxoob->sgl[0].address, rxq->datasize,
> > +			 DMA_FROM_DEVICE);
> > +	*old_buf = rxoob->buf_va;
> > +
> > +	rxoob->buf_va = va;
> > +	rxoob->sgl[0].address = da;
> > +}
> > +
> 
> So you're pulling out these functions from the code below, which is
> good, but it makes it hard to tell what code actually changed.
> 
> >  static void mana_process_rx_cqe(struct mana_rxq *rxq, struct mana_cq *cq,
> >  				struct gdma_comp *cqe)
> >  {
> > @@ -1299,10 +1358,8 @@ static void mana_process_rx_cqe(struct
> mana_rxq *rxq, struct mana_cq *cq,
> >  	struct mana_recv_buf_oob *rxbuf_oob;
> >  	struct mana_port_context *apc;
> >  	struct device *dev = gc->dev;
> > -	void *new_buf, *old_buf;
> > -	struct page *new_page;
> > +	void *old_buf = NULL;
> >  	u32 curr, pktlen;
> > -	dma_addr_t da;
> >
> >  	apc = netdev_priv(ndev);
> >
> > @@ -1345,40 +1402,11 @@ static void mana_process_rx_cqe(struct
> mana_rxq *rxq, struct mana_cq *cq,
> >  	rxbuf_oob = &rxq->rx_oobs[curr];
> >  	WARN_ON_ONCE(rxbuf_oob->wqe_inf.wqe_size_in_bu != 1);
> >
> > -	/* Reuse XDP dropped page if available */
> > -	if (rxq->xdp_save_page) {
> > -		new_page = rxq->xdp_save_page;
> > -		rxq->xdp_save_page = NULL;
> > -	} else {
> > -		new_page = alloc_page(GFP_ATOMIC);
> > -	}
> > -
> > -	if (new_page) {
> > -		da = dma_map_page(dev, new_page,
> XDP_PACKET_HEADROOM, rxq->datasize,
> > -				  DMA_FROM_DEVICE);
> > -
> > -		if (dma_mapping_error(dev, da)) {
> > -			__free_page(new_page);
> > -			new_page = NULL;
> > -		}
> > -	}
> > -
> > -	new_buf = new_page ? page_to_virt(new_page) : NULL;
> > -
> > -	if (new_buf) {
> > -		dma_unmap_page(dev, rxbuf_oob->buf_dma_addr, rxq-
> >datasize,
> > -			       DMA_FROM_DEVICE);
> > -
> > -		old_buf = rxbuf_oob->buf_va;
> > -
> > -		/* refresh the rxbuf_oob with the new page */
> > -		rxbuf_oob->buf_va = new_buf;
> > -		rxbuf_oob->buf_dma_addr = da;
> > -		rxbuf_oob->sgl[0].address = rxbuf_oob->buf_dma_addr;
> > -	} else {
> > -		old_buf = NULL; /* drop the packet if no memory */
> > -	}
> 
> Could you do this split into helper functions first in a separate change
> before adding support for handling various MTU size?
> 
> Doing it that way would make it much easier to review what actually
> changes in that block of code.

Will do.

Thanks,
- Haiyang





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux