From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
Gregory CLEMENT <gregory.clement@free-electrons.com>,
Arnaud Ebalard <arno@natisbad.org>,
Eric Dumazet <eric.dumazet@gmail.com>, Willy Tarreau <w@1wt.eu>,
"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 3.10 24/27] net: mvneta: replace Tx timer with a real interrupt
Date: Tue, 5 Aug 2014 11:14:16 -0700 [thread overview]
Message-ID: <20140805181344.979737608@linuxfoundation.org> (raw)
In-Reply-To: <20140805181344.268039690@linuxfoundation.org>
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: willy tarreau <w@1wt.eu>
commit 71f6d1b31fb1f278a345a30a2180515adc7d80ae upstream.
Right now the mvneta driver doesn't handle Tx IRQ, and relies on two
mechanisms to flush Tx descriptors : a flush at the end of mvneta_tx()
and a timer. If a burst of packets is emitted faster than the device
can send them, then the queue is stopped until next wake-up of the
timer 10ms later. This causes jerky output traffic with bursts and
pauses, making it difficult to reach line rate with very few streams.
A test on UDP traffic shows that it's not possible to go beyond 134
Mbps / 12 kpps of outgoing traffic with 1500-bytes IP packets. Routed
traffic tends to observe pauses as well if the traffic is bursty,
making it even burstier after the wake-up.
It seems that this feature was inherited from the original driver but
nothing there mentions any reason for not using the interrupt instead,
which the chip supports.
Thus, this patch enables Tx interrupts and removes the timer. It does
the two at once because it's not really possible to make the two
mechanisms coexist, so a split patch doesn't make sense.
First tests performed on a Mirabox (Armada 370) show that less CPU
seems to be used when sending traffic. One reason might be that we now
call the mvneta_tx_done_gbe() with a mask indicating which queues have
been done instead of looping over all of them.
The same UDP test above now happily reaches 987 Mbps / 87.7 kpps.
Single-stream TCP traffic can now more easily reach line rate. HTTP
transfers of 1 MB objects over a single connection went from 730 to
840 Mbps. It is even possible to go significantly higher (>900 Mbps)
by tweaking tcp_tso_win_divisor.
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: Arnaud Ebalard <arno@natisbad.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Tested-by: Arnaud Ebalard <arno@natisbad.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/marvell/mvneta.c | 72 +++++-----------------------------
1 file changed, 12 insertions(+), 60 deletions(-)
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -214,9 +214,6 @@
#define MVNETA_RX_COAL_PKTS 32
#define MVNETA_RX_COAL_USEC 100
-/* Timer */
-#define MVNETA_TX_DONE_TIMER_PERIOD 10
-
/* Napi polling weight */
#define MVNETA_RX_POLL_WEIGHT 64
@@ -272,16 +269,11 @@ struct mvneta_port {
void __iomem *base;
struct mvneta_rx_queue *rxqs;
struct mvneta_tx_queue *txqs;
- struct timer_list tx_done_timer;
struct net_device *dev;
u32 cause_rx_tx;
struct napi_struct napi;
- /* Flags */
- unsigned long flags;
-#define MVNETA_F_TX_DONE_TIMER_BIT 0
-
/* Napi weight */
int weight;
@@ -1112,17 +1104,6 @@ static void mvneta_tx_done_pkts_coal_set
txq->done_pkts_coal = value;
}
-/* Trigger tx done timer in MVNETA_TX_DONE_TIMER_PERIOD msecs */
-static void mvneta_add_tx_done_timer(struct mvneta_port *pp)
-{
- if (test_and_set_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags) == 0) {
- pp->tx_done_timer.expires = jiffies +
- msecs_to_jiffies(MVNETA_TX_DONE_TIMER_PERIOD);
- add_timer(&pp->tx_done_timer);
- }
-}
-
-
/* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
u32 phys_addr, u32 cookie)
@@ -1614,15 +1595,6 @@ out:
dev_kfree_skb_any(skb);
}
- if (txq->count >= MVNETA_TXDONE_COAL_PKTS)
- mvneta_txq_done(pp, txq);
-
- /* If after calling mvneta_txq_done, count equals
- * frags, we need to set the timer
- */
- if (txq->count == frags && frags > 0)
- mvneta_add_tx_done_timer(pp);
-
return NETDEV_TX_OK;
}
@@ -1898,14 +1870,22 @@ static int mvneta_poll(struct napi_struc
/* Read cause register */
cause_rx_tx = mvreg_read(pp, MVNETA_INTR_NEW_CAUSE) &
- MVNETA_RX_INTR_MASK(rxq_number);
+ (MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number));
+
+ /* Release Tx descriptors */
+ if (cause_rx_tx & MVNETA_TX_INTR_MASK_ALL) {
+ int tx_todo = 0;
+
+ mvneta_tx_done_gbe(pp, (cause_rx_tx & MVNETA_TX_INTR_MASK_ALL), &tx_todo);
+ cause_rx_tx &= ~MVNETA_TX_INTR_MASK_ALL;
+ }
/* For the case where the last mvneta_poll did not process all
* RX packets
*/
cause_rx_tx |= pp->cause_rx_tx;
if (rxq_number > 1) {
- while ((cause_rx_tx != 0) && (budget > 0)) {
+ while ((cause_rx_tx & MVNETA_RX_INTR_MASK_ALL) && (budget > 0)) {
int count;
struct mvneta_rx_queue *rxq;
/* get rx queue number from cause_rx_tx */
@@ -1937,7 +1917,7 @@ static int mvneta_poll(struct napi_struc
napi_complete(napi);
local_irq_save(flags);
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
- MVNETA_RX_INTR_MASK(rxq_number));
+ MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number));
local_irq_restore(flags);
}
@@ -1945,26 +1925,6 @@ static int mvneta_poll(struct napi_struc
return rx_done;
}
-/* tx done timer callback */
-static void mvneta_tx_done_timer_callback(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct mvneta_port *pp = netdev_priv(dev);
- int tx_done = 0, tx_todo = 0;
-
- if (!netif_running(dev))
- return ;
-
- clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
-
- tx_done = mvneta_tx_done_gbe(pp,
- (((1 << txq_number) - 1) &
- MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK),
- &tx_todo);
- if (tx_todo > 0)
- mvneta_add_tx_done_timer(pp);
-}
-
/* Handle rxq fill: allocates rxq skbs; called when initializing a port */
static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
int num)
@@ -2214,7 +2174,7 @@ static void mvneta_start_dev(struct mvne
/* Unmask interrupts */
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
- MVNETA_RX_INTR_MASK(rxq_number));
+ MVNETA_RX_INTR_MASK(rxq_number) | MVNETA_TX_INTR_MASK(txq_number));
phy_start(pp->phy_dev);
netif_tx_start_all_queues(pp->dev);
@@ -2475,8 +2435,6 @@ static int mvneta_stop(struct net_device
free_irq(dev->irq, pp);
mvneta_cleanup_rxqs(pp);
mvneta_cleanup_txqs(pp);
- del_timer(&pp->tx_done_timer);
- clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
return 0;
}
@@ -2777,10 +2735,6 @@ static int mvneta_probe(struct platform_
pp = netdev_priv(dev);
- pp->tx_done_timer.function = mvneta_tx_done_timer_callback;
- init_timer(&pp->tx_done_timer);
- clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
-
pp->weight = MVNETA_RX_POLL_WEIGHT;
pp->phy_node = phy_node;
pp->phy_interface = phy_mode;
@@ -2806,8 +2760,6 @@ static int mvneta_probe(struct platform_
goto err_clk;
}
- pp->tx_done_timer.data = (unsigned long)dev;
-
pp->tx_ring_size = MVNETA_MAX_TXD;
pp->rx_ring_size = MVNETA_MAX_RXD;
next prev parent reply other threads:[~2014-08-05 18:14 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-05 18:13 [PATCH 3.10 00/27] 3.10.52-stable review Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 01/27] crypto: af_alg - properly label AF_ALG socket Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 02/27] ARM: 8115/1: LPAE: reduce damage caused by idmap to virtual memory layout Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 03/27] cfg80211: fix mic_failure tracing Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 04/27] rapidio/tsi721_dma: fix failure to obtain transaction descriptor Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 05/27] scsi: handle flush errors properly Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 06/27] mm, thp: do not allow thp faults to avoid cpuset restrictions Greg Kroah-Hartman
2014-08-05 18:13 ` [PATCH 3.10 07/27] staging: vt6655: Fix disassociated messages every 10 seconds Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 08/27] iio: buffer: Fix demux table creation Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 09/27] printk: rename printk_sched to printk_deferred Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 10/27] timer: Fix lock inversion between hrtimer_bases.lock and scheduler locks Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 11/27] Revert "x86-64, modify_ldt: Make support for 16-bit segments a runtime option" Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 12/27] x86-64, espfix: Dont leak bits 31:16 of %esp returning to 16-bit stack Greg Kroah-Hartman
2014-08-06 15:16 ` Luis Henriques
2014-08-06 15:24 ` Greg Kroah-Hartman
2014-08-06 15:55 ` Luis Henriques
2014-08-07 17:13 ` Greg Kroah-Hartman
2014-08-07 17:29 ` Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 13/27] x86, espfix: Move espfix definitions into a separate header file Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 14/27] x86, espfix: Fix broken header guard Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 15/27] x86, espfix: Make espfix64 a Kconfig option, fix UML Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 16/27] x86, espfix: Make it possible to disable 16-bit support Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 17/27] x86_64/entry/xen: Do not invoke espfix64 on Xen Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 18/27] staging: vt6655: Fix Warning on boot handle_irq_event_percpu Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 19/27] Revert "mac80211: move "bufferable MMPDU" check to fix AP mode scan" Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 20/27] net: mvneta: increase the 64-bit rx/tx stats out of the hot path Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 21/27] net: mvneta: use per_cpu stats to fix an SMP lock up Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 22/27] net: mvneta: do not schedule in mvneta_tx_timeout Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 23/27] net: mvneta: add missing bit descriptions for interrupt masks and causes Greg Kroah-Hartman
2014-08-05 18:14 ` Greg Kroah-Hartman [this message]
2014-08-05 18:14 ` [PATCH 3.10 25/27] net/l2tp: dont fall back on UDP [get|set]sockopt Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 26/27] lib/btree.c: fix leak of whole btree nodes Greg Kroah-Hartman
2014-08-05 18:14 ` [PATCH 3.10 27/27] x86/espfix/xen: Fix allocation of pages for paravirt page tables Greg Kroah-Hartman
2014-08-05 23:08 ` [PATCH 3.10 00/27] 3.10.52-stable review Shuah Khan
2014-08-06 2:34 ` Guenter Roeck
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=20140805181344.979737608@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=arno@natisbad.org \
--cc=davem@davemloft.net \
--cc=eric.dumazet@gmail.com \
--cc=gregory.clement@free-electrons.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=thomas.petazzoni@free-electrons.com \
--cc=w@1wt.eu \
/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).