From: Willy Tarreau <w@1wt.eu>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, Willy Tarreau <w@1wt.eu>,
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
Gregory CLEMENT <gregory.clement@free-electrons.com>
Subject: [PATCH 11/13] net: mvneta: implement rx_copybreak
Date: Thu, 16 Jan 2014 08:20:17 +0100 [thread overview]
Message-ID: <1389856819-6503-12-git-send-email-w@1wt.eu> (raw)
In-Reply-To: <1389856819-6503-1-git-send-email-w@1wt.eu>
calling dma_map_single()/dma_unmap_single() is quite expensive compared
to copying a small packet. So let's copy short frames and keep the buffers
mapped. We set the limit to 256 bytes which seems to give good results both
on the XP-GP board and on the AX3/4.
The Rx small packet rate increased by 16.4% doing this, from 486kpps to
573kpps. It is worth noting that even the call to the function
dma_sync_single_range_for_cpu() is expensive (300 ns) although less
than dma_unmap_single(). Without it, the packet rate raises to 711kpps
(+24% more). Thus on systems where coherency from device to CPU is
guaranteed by a snoop control unit, this patch should provide even more
gains, and probably rx_copybreak could be increased.
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Gregory CLEMENT <gregory.clement@free-electrons.com>
Tested-by: Arnaud Ebalard <arno@natisbad.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
---
drivers/net/ethernet/marvell/mvneta.c | 44 ++++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 726a8d2..f5fc7a2 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -444,6 +444,8 @@ static int txq_number = 8;
static int rxq_def;
+static int rx_copybreak __read_mostly = 256;
+
#define MVNETA_DRIVER_NAME "mvneta"
#define MVNETA_DRIVER_VERSION "1.0"
@@ -1463,22 +1465,51 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
rx_done++;
rx_filled++;
rx_status = rx_desc->status;
+ rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
data = (unsigned char *)rx_desc->buf_cookie;
if (!mvneta_rxq_desc_is_first_last(rx_status) ||
- (rx_status & MVNETA_RXD_ERR_SUMMARY) ||
- !(skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size))) {
+ (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
+ err_drop_frame:
dev->stats.rx_errors++;
mvneta_rx_error(pp, rx_desc);
/* leave the descriptor untouched */
continue;
}
- dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
+ if (rx_bytes <= rx_copybreak) {
+ /* better copy a small frame and not unmap the DMA region */
+ skb = netdev_alloc_skb_ip_align(dev, rx_bytes);
+ if (unlikely(!skb))
+ goto err_drop_frame;
+
+ dma_sync_single_range_for_cpu(dev->dev.parent,
+ rx_desc->buf_phys_addr,
+ MVNETA_MH_SIZE + NET_SKB_PAD,
+ rx_bytes,
+ DMA_FROM_DEVICE);
+ memcpy(skb_put(skb, rx_bytes),
+ data + MVNETA_MH_SIZE + NET_SKB_PAD,
+ rx_bytes);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ mvneta_rx_csum(pp, rx_status, skb);
+ napi_gro_receive(&pp->napi, skb);
+
+ rcvd_pkts++;
+ rcvd_bytes += rx_bytes;
+
+ /* leave the descriptor and buffer untouched */
+ continue;
+ }
+
+ skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size);
+ if (!skb)
+ goto err_drop_frame;
+
+ dma_unmap_single(dev->dev.parent, rx_desc->buf_phys_addr,
MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
- rx_bytes = rx_desc->data_size -
- (ETH_FCS_LEN + MVNETA_MH_SIZE);
rcvd_pkts++;
rcvd_bytes += rx_bytes;
@@ -1495,7 +1526,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
/* Refill processing */
err = mvneta_rx_refill(pp, rx_desc);
if (err) {
- netdev_err(pp->dev, "Linux processing - Can't refill\n");
+ netdev_err(dev, "Linux processing - Can't refill\n");
rxq->missed++;
rx_filled--;
}
@@ -2945,3 +2976,4 @@ module_param(rxq_number, int, S_IRUGO);
module_param(txq_number, int, S_IRUGO);
module_param(rxq_def, int, S_IRUGO);
+module_param(rx_copybreak, int, S_IRUGO | S_IWUSR);
--
1.7.12.2.21.g234cd45.dirty
next prev parent reply other threads:[~2014-01-16 7:21 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-16 7:20 [PATCH 00/13] Assorted mvneta fixes and improvements Willy Tarreau
2014-01-16 7:20 ` [PATCH 01/13] net: mvneta: increase the 64-bit rx/tx stats out of the hot path Willy Tarreau
2014-01-16 7:20 ` [PATCH 02/13] net: mvneta: use per_cpu stats to fix an SMP lock up Willy Tarreau
2014-01-16 7:20 ` [PATCH 03/13] net: mvneta: do not schedule in mvneta_tx_timeout Willy Tarreau
2014-01-16 7:20 ` [PATCH 04/13] net: mvneta: add missing bit descriptions for interrupt masks and causes Willy Tarreau
2014-01-16 7:20 ` [PATCH 05/13] net: mvneta: replace Tx timer with a real interrupt Willy Tarreau
2014-01-16 7:20 ` [PATCH 06/13] net: mvneta: remove tests for impossible cases in the tx_done path Willy Tarreau
2014-01-16 7:20 ` [PATCH 07/13] net: mvneta: factor rx refilling code Willy Tarreau
2014-01-16 7:20 ` [PATCH 08/13] net: mvneta: simplify access to the rx descriptor status Willy Tarreau
2014-01-16 7:20 ` [PATCH 09/13] net: mvneta: prefetch next rx descriptor instead of current one Willy Tarreau
2014-01-16 7:20 ` [PATCH 10/13] net: mvneta: convert to build_skb() Willy Tarreau
2014-01-16 7:20 ` Willy Tarreau [this message]
2014-01-16 9:14 ` [PATCH 11/13] net: mvneta: implement rx_copybreak David Laight
2014-01-16 9:36 ` Willy Tarreau
2014-01-16 19:49 ` David Miller
2014-01-16 20:07 ` Willy Tarreau
2014-01-16 20:11 ` David Miller
2014-01-17 9:28 ` David Laight
2014-01-17 9:48 ` Willy Tarreau
2014-01-17 9:32 ` David Laight
2014-01-16 7:20 ` [PATCH 12/13] net: mvneta: mvneta_tx_done_gbe() cleanups Willy Tarreau
2014-01-16 7:20 ` [PATCH 13/13] net: mvneta: make mvneta_txq_done() return void Willy Tarreau
2014-01-16 7:22 ` [PATCH net-next 00/13] Assorted mvneta fixes and improvements Willy Tarreau
2014-01-16 23:21 ` [PATCH " David Miller
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=1389856819-6503-12-git-send-email-w@1wt.eu \
--to=w@1wt.eu \
--cc=davem@davemloft.net \
--cc=gregory.clement@free-electrons.com \
--cc=netdev@vger.kernel.org \
--cc=thomas.petazzoni@free-electrons.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 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).