* [PATCH] net: fec: remove memory copy for rx path
@ 2014-09-24 6:05 Fugang Duan
2014-09-26 21:07 ` David Miller
0 siblings, 1 reply; 6+ messages in thread
From: Fugang Duan @ 2014-09-24 6:05 UTC (permalink / raw)
To: b20596, davem; +Cc: netdev, shawn.guo, bhutchings, b38611
Re-allocate skb instead of memory copy skb data in rx path to improve
enet rx performance.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec_main.c | 90 +++++++++++++++--------------
1 files changed, 47 insertions(+), 43 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 2b16ead..1fc8e52 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1322,6 +1322,28 @@ fec_enet_tx(struct net_device *ndev)
return;
}
+static int
+fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff *skb)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int off;
+
+ off = ((unsigned long)skb->data) & fep->rx_align;
+ if (off)
+ skb_reserve(skb, fep->rx_align + 1 - off);
+
+ bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
+ FEC_ENET_RX_FRSIZE - fep->rx_align,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
+ if (net_ratelimit())
+ netdev_err(ndev, "Rx DMA memory map failed\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
/* During a receive, the cur_rx points to the current incoming buffer.
* When we update through the ring, if the next incoming buffer has
* not been given to the system, we just set the empty indicator,
@@ -1336,7 +1358,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned short status;
- struct sk_buff *skb;
+ struct sk_buff *skb_new = NULL;
+ struct sk_buff *skb_cur;
ushort pkt_len;
__u8 *data;
int pkt_received = 0;
@@ -1402,9 +1425,10 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
index = fec_enet_get_bd_index(rxq->rx_bd_base, bdp, fep);
data = rxq->rx_skbuff[index]->data;
- dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
- FEC_ENET_RX_FRSIZE - fep->rx_align,
- DMA_FROM_DEVICE);
+ skb_cur = rxq->rx_skbuff[index];
+ dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
+ FEC_ENET_RX_FRSIZE - fep->rx_align,
+ DMA_FROM_DEVICE);
if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
swap_buffer(data, pkt_len);
@@ -1427,57 +1451,50 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
vlan_packet_rcvd = true;
}
- /* This does 16 byte alignment, exactly what we need.
- * The packet length includes FCS, but we don't want to
- * include that when passing upstream as it messes up
- * bridging applications.
- */
- skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN);
+ skb_new = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
- if (unlikely(!skb)) {
+ if (unlikely(!skb_new)) {
ndev->stats.rx_dropped++;
} else {
- int payload_offset = (2 * ETH_ALEN);
- skb_reserve(skb, NET_IP_ALIGN);
- skb_put(skb, pkt_len - 4); /* Make room */
+ skb_put(skb_cur, pkt_len - 4); /* Make room */
/* Extract the frame data without the VLAN header. */
- skb_copy_to_linear_data(skb, data, (2 * ETH_ALEN));
- if (vlan_packet_rcvd)
- payload_offset = (2 * ETH_ALEN) + VLAN_HLEN;
- skb_copy_to_linear_data_offset(skb, (2 * ETH_ALEN),
- data + payload_offset,
- pkt_len - 4 - (2 * ETH_ALEN));
+ if (vlan_packet_rcvd) {
+ skb_copy_to_linear_data_offset(skb_cur, VLAN_HLEN,
+ data, (2 * ETH_ALEN));
+ skb_pull(skb_cur, VLAN_HLEN);
+ }
- skb->protocol = eth_type_trans(skb, ndev);
+ skb_cur->protocol = eth_type_trans(skb_cur, ndev);
/* Get receive timestamp from the skb */
if (fep->hwts_rx_en && fep->bufdesc_ex)
fec_enet_hwtstamp(fep, ebdp->ts,
- skb_hwtstamps(skb));
+ skb_hwtstamps(skb_cur));
if (fep->bufdesc_ex &&
(fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
if (!(ebdp->cbd_esc & FLAG_RX_CSUM_ERROR)) {
/* don't check it */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb_cur->ip_summed = CHECKSUM_UNNECESSARY;
} else {
- skb_checksum_none_assert(skb);
+ skb_checksum_none_assert(skb_cur);
}
}
/* Handle received VLAN packets */
if (vlan_packet_rcvd)
- __vlan_hwaccel_put_tag(skb,
+ __vlan_hwaccel_put_tag(skb_cur,
htons(ETH_P_8021Q),
vlan_tag);
- napi_gro_receive(&fep->napi, skb);
+ napi_gro_receive(&fep->napi, skb_cur);
}
- dma_sync_single_for_device(&fep->pdev->dev, bdp->cbd_bufaddr,
- FEC_ENET_RX_FRSIZE - fep->rx_align,
- DMA_FROM_DEVICE);
+ /* set the new skb */
+ rxq->rx_skbuff[index] = skb_new;
+ fec_enet_new_rxbdp(ndev, bdp, skb_new);
+
rx_processing_done:
/* Clear the status flags for this buffer */
status &= ~BD_ENET_RX_STATS;
@@ -2553,33 +2570,20 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
struct sk_buff *skb;
struct bufdesc *bdp;
struct fec_enet_priv_rx_q *rxq;
- unsigned int off;
rxq = fep->rx_queue[queue];
bdp = rxq->rx_bd_base;
for (i = 0; i < rxq->rx_ring_size; i++) {
- dma_addr_t addr;
-
skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
if (!skb)
goto err_alloc;
- off = ((unsigned long)skb->data) & fep->rx_align;
- if (off)
- skb_reserve(skb, fep->rx_align + 1 - off);
-
- addr = dma_map_single(&fep->pdev->dev, skb->data,
- FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE);
-
- if (dma_mapping_error(&fep->pdev->dev, addr)) {
+ if (fec_enet_new_rxbdp(ndev, bdp, skb)) {
dev_kfree_skb(skb);
- if (net_ratelimit())
- netdev_err(ndev, "Rx DMA memory map failed\n");
goto err_alloc;
}
rxq->rx_skbuff[i] = skb;
- bdp->cbd_bufaddr = addr;
bdp->cbd_sc = BD_ENET_RX_EMPTY;
if (fep->bufdesc_ex) {
--
1.7.8
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] net: fec: remove memory copy for rx path
2014-09-24 6:05 [PATCH] net: fec: remove memory copy for rx path Fugang Duan
@ 2014-09-26 21:07 ` David Miller
2014-09-27 9:15 ` fugang.duan
0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2014-09-26 21:07 UTC (permalink / raw)
To: b38611; +Cc: b20596, netdev, shawn.guo, bhutchings
From: Fugang Duan <b38611@freescale.com>
Date: Wed, 24 Sep 2014 14:05:30 +0800
> Re-allocate skb instead of memory copy skb data in rx path to improve
> enet rx performance.
>
> Signed-off-by: Fugang Duan <B38611@freescale.com>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
For small packet sizes, copying is almost certainly faster and it avoids
mismatched skb->truesize vs. skb->len which hurts TCP performance.
We call this rx_copybreak, and there are many drivers you can look at
to see how this works.
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH] net: fec: remove memory copy for rx path
2014-09-26 21:07 ` David Miller
@ 2014-09-27 9:15 ` fugang.duan
2014-09-27 11:39 ` Francois Romieu
0 siblings, 1 reply; 6+ messages in thread
From: fugang.duan @ 2014-09-27 9:15 UTC (permalink / raw)
To: David Miller; +Cc: Frank.Li, netdev, shawn.guo, bhutchings
From: David Miller <davem@davemloft.net> Sent: Saturday, September 27, 2014 5:07 AM
>To: Duan Fugang-B38611
>Cc: Li Frank-B20596; netdev@vger.kernel.org; shawn.guo@linaro.org;
>bhutchings@solarflare.com
>Subject: Re: [PATCH] net: fec: remove memory copy for rx path
>
>From: Fugang Duan <b38611@freescale.com>
>Date: Wed, 24 Sep 2014 14:05:30 +0800
>
>> Re-allocate skb instead of memory copy skb data in rx path to improve
>> enet rx performance.
>>
>> Signed-off-by: Fugang Duan <B38611@freescale.com>
>> Signed-off-by: Frank Li <Frank.Li@freescale.com>
>
>For small packet sizes, copying is almost certainly faster and it avoids
>mismatched skb->truesize vs. skb->len which hurts TCP performance.
>
>We call this rx_copybreak, and there are many drivers you can look at to
>see how this works.
>
>Thanks.
Great suggestion. I will change it for next version.
Thanks,
Andy
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] net: fec: remove memory copy for rx path
2014-09-27 9:15 ` fugang.duan
@ 2014-09-27 11:39 ` Francois Romieu
2014-09-27 22:56 ` David Miller
0 siblings, 1 reply; 6+ messages in thread
From: Francois Romieu @ 2014-09-27 11:39 UTC (permalink / raw)
To: fugang.duan; +Cc: David Miller, Frank.Li, netdev, shawn.guo, bhutchings
fugang.duan@freescale.com <fugang.duan@freescale.com> :
> From: David Miller <davem@davemloft.net> Sent: Saturday, September 27, 2014 5:07 AM
[...]
> >We call this rx_copybreak, and there are many drivers you can look at to
> >see how this works.
> >
> >Thanks.
>
> Great suggestion. I will change it for next version.
Be aware that copybreak module option should be considered legacy.
There is an ethtool api for it.
--
Ueimor
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] net: fec: remove memory copy for rx path
2014-09-27 11:39 ` Francois Romieu
@ 2014-09-27 22:56 ` David Miller
2014-09-28 3:30 ` fugang.duan
0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2014-09-27 22:56 UTC (permalink / raw)
To: romieu; +Cc: fugang.duan, Frank.Li, netdev, shawn.guo, bhutchings
From: Francois Romieu <romieu@fr.zoreil.com>
Date: Sat, 27 Sep 2014 13:39:37 +0200
> fugang.duan@freescale.com <fugang.duan@freescale.com> :
>> From: David Miller <davem@davemloft.net> Sent: Saturday, September 27, 2014 5:07 AM
> [...]
>> >We call this rx_copybreak, and there are many drivers you can look at to
>> >see how this works.
>> >
>> >Thanks.
>>
>> Great suggestion. I will change it for next version.
>
> Be aware that copybreak module option should be considered legacy.
>
> There is an ethtool api for it.
Right.
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH] net: fec: remove memory copy for rx path
2014-09-27 22:56 ` David Miller
@ 2014-09-28 3:30 ` fugang.duan
0 siblings, 0 replies; 6+ messages in thread
From: fugang.duan @ 2014-09-28 3:30 UTC (permalink / raw)
To: David Miller, romieu; +Cc: Frank.Li, netdev, shawn.guo, bhutchings
From: David Miller <davem@davemloft.net> Sent: Sunday, September 28, 2014 6:56 AM
>To: romieu@fr.zoreil.com
>Cc: Duan Fugang-B38611; Li Frank-B20596; netdev@vger.kernel.org;
>shawn.guo@linaro.org; bhutchings@solarflare.com
>Subject: Re: [PATCH] net: fec: remove memory copy for rx path
>
>From: Francois Romieu <romieu@fr.zoreil.com>
>Date: Sat, 27 Sep 2014 13:39:37 +0200
>
>> fugang.duan@freescale.com <fugang.duan@freescale.com> :
>>> From: David Miller <davem@davemloft.net> Sent: Saturday, September
>>> 27, 2014 5:07 AM
>> [...]
>>> >We call this rx_copybreak, and there are many drivers you can look
>>> >at to see how this works.
>>> >
>>> >Thanks.
>>>
>>> Great suggestion. I will change it for next version.
>>
>> Be aware that copybreak module option should be considered legacy.
>>
>> There is an ethtool api for it.
>
>Right.
Got it, thanks David and romieu.
Regards,
Andy
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-09-28 3:32 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-24 6:05 [PATCH] net: fec: remove memory copy for rx path Fugang Duan
2014-09-26 21:07 ` David Miller
2014-09-27 9:15 ` fugang.duan
2014-09-27 11:39 ` Francois Romieu
2014-09-27 22:56 ` David Miller
2014-09-28 3:30 ` fugang.duan
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.