diff mbox series

[1/8] rt2800: partially restore old mmio txstatus behaviour

Message ID 1553680711-15730-2-git-send-email-sgruszka@redhat.com (mailing list archive)
State Accepted
Commit 889bb866baafd191275812574cfe57f6c83910eb
Delegated to: Kalle Valo
Headers show
Series rt2x00: performance fixes for mmio | expand

Commit Message

Stanislaw Gruszka March 27, 2019, 9:58 a.m. UTC
Do not disable txstatus interrupt and add quota of processed tx statuses in
one tasklet. Quota is needed to allow to fed device with new frames during
processing of tx statuses.

Patch fixes about 15% performance degradation on some scenarios caused by
0b0d556e0ebb ("rt2800mmio: use txdone/txstatus routines from lib").

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c  |  4 ++--
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h  |  2 +-
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 30 +++++++------------------
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c  |  2 +-
 4 files changed, 12 insertions(+), 26 deletions(-)

Comments

Kalle Valo April 25, 2019, 4:44 p.m. UTC | #1
Stanislaw Gruszka <sgruszka@redhat.com> wrote:

> Do not disable txstatus interrupt and add quota of processed tx statuses in
> one tasklet. Quota is needed to allow to fed device with new frames during
> processing of tx statuses.
> 
> Patch fixes about 15% performance degradation on some scenarios caused by
> 0b0d556e0ebb ("rt2800mmio: use txdone/txstatus routines from lib").
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>

8 patches applied to wireless-drivers-next.git, thanks.

889bb866baaf rt2800: partially restore old mmio txstatus behaviour
f61131505e85 rt2800: new flush implementation for SoC devices
6efa79876486 rt2800: move txstatus pending routine
2c7ba758cc4b rt2800mmio: fetch tx status changes
e5ceab9df437 rt2800mmio: use timer and work for handling tx statuses timeouts
eb662b1dc62e rt2x00: remove last_nostatus_check
d954f9e3fb42 rt2x00: remove not used entry field
9ea3812f015b rt2x00mmio: remove legacy comment
diff mbox series

Patch

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index a03b5284a050..635aa6729529 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1100,7 +1100,7 @@  void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
 }
 EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota)
 {
 	struct data_queue *queue;
 	struct queue_entry *entry;
@@ -1108,7 +1108,7 @@  void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
 	u8 qid;
 	bool match;
 
-	while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
+	while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
 		/*
 		 * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
 		 * guaranteed to be one of the TX QIDs .
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
index 0dff2c7b3010..506c319070dd 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -195,7 +195,7 @@  void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *tx
 
 void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
 			 bool match);
-void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
+void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota);
 void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev);
 bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev);
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
index ddb88cfeace2..f7635a47dbcd 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
@@ -255,20 +255,6 @@  void rt2800mmio_autowake_tasklet(unsigned long data)
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
 
-static void rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev)
-{
-	bool timeout = false;
-
-	while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
-	       (timeout = rt2800_txstatus_timeout(rt2x00dev))) {
-
-		rt2800_txdone(rt2x00dev);
-
-		if (timeout)
-			rt2800_txdone_nostatus(rt2x00dev);
-	}
-}
-
 static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)
 {
 	u32 status;
@@ -305,14 +291,11 @@  void rt2800mmio_txstatus_tasklet(unsigned long data)
 {
 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
 
-	do {
-		rt2800mmio_txdone(rt2x00dev);
+	rt2800_txdone(rt2x00dev, 16);
 
-	} while (rt2800mmio_fetch_txstatus(rt2x00dev));
+	if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
+		tasklet_schedule(&rt2x00dev->txstatus_tasklet);
 
-	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
-		rt2800mmio_enable_interrupt(rt2x00dev,
-					    INT_SOURCE_CSR_TX_FIFO_STATUS);
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet);
 
@@ -339,8 +322,10 @@  irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)
 	mask = ~reg;
 
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
+		rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1);
 		rt2800mmio_fetch_txstatus(rt2x00dev);
-		tasklet_schedule(&rt2x00dev->txstatus_tasklet);
+		if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
+			tasklet_schedule(&rt2x00dev->txstatus_tasklet);
 	}
 
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
@@ -500,7 +485,8 @@  void rt2800mmio_flush_queue(struct data_queue *queue, bool drop)
 		 */
 		if (tx_queue) {
 			tasklet_disable(&rt2x00dev->txstatus_tasklet);
-			rt2800mmio_txdone(rt2x00dev);
+			rt2800_txdone(rt2x00dev, UINT_MAX);
+			rt2800_txdone_nostatus(rt2x00dev);
 			tasklet_enable(&rt2x00dev->txstatus_tasklet);
 		}
 
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
index 19eabf16147b..0bdcab374203 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -480,7 +480,7 @@  static void rt2800usb_work_txdone(struct work_struct *work)
 	while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
 	       rt2800_txstatus_timeout(rt2x00dev)) {
 
-		rt2800_txdone(rt2x00dev);
+		rt2800_txdone(rt2x00dev, UINT_MAX);
 
 		rt2800_txdone_nostatus(rt2x00dev);