Skip to content

Commit 2fe30dc

Browse files
committed
mt76: reduce locking in mt76_dma_tx_cleanup
q->tail can be safely updated without locking, because there is no concurrent access. If called from outside of the tasklet (for flushing), the tasklet is always disabled. q->queued can be safely read without locking, as long as the decrement happens within the locked section. This patch allows cleaning up tx packets outside of the section that holds the queue lock for improved performance Signed-off-by: Felix Fietkau <[email protected]>
1 parent 90fdc17 commit 2fe30dc

File tree

1 file changed

+17
-9
lines changed
  • drivers/net/wireless/mediatek/mt76

1 file changed

+17
-9
lines changed

drivers/net/wireless/mediatek/mt76/dma.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,31 +149,29 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
149149
struct mt76_sw_queue *sq = &dev->q_tx[qid];
150150
struct mt76_queue *q = sq->q;
151151
struct mt76_queue_entry entry;
152+
unsigned int n_swq_queued[4] = {};
153+
unsigned int n_queued = 0;
152154
bool wake = false;
153-
int last;
155+
int i, last;
154156

155157
if (!q)
156158
return;
157159

158-
spin_lock_bh(&q->lock);
159160
if (flush)
160161
last = -1;
161162
else
162163
last = readl(&q->regs->dma_idx);
163164

164-
while (q->queued && q->tail != last) {
165+
while ((q->queued > n_queued) && q->tail != last) {
165166
mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
166167
if (entry.schedule)
167-
dev->q_tx[entry.qid].swq_queued--;
168+
n_swq_queued[entry.qid]++;
168169

169170
q->tail = (q->tail + 1) % q->ndesc;
170-
q->queued--;
171+
n_queued++;
171172

172-
if (entry.skb) {
173-
spin_unlock_bh(&q->lock);
173+
if (entry.skb)
174174
dev->drv->tx_complete_skb(dev, qid, &entry);
175-
spin_lock_bh(&q->lock);
176-
}
177175

178176
if (entry.txwi) {
179177
mt76_put_txwi(dev, entry.txwi);
@@ -184,6 +182,16 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
184182
last = readl(&q->regs->dma_idx);
185183
}
186184

185+
spin_lock_bh(&q->lock);
186+
187+
q->queued -= n_queued;
188+
for (i = 0; i < ARRAY_SIZE(n_swq_queued); i++) {
189+
if (!n_swq_queued[i])
190+
continue;
191+
192+
dev->q_tx[i].swq_queued -= n_swq_queued[i];
193+
}
194+
187195
if (flush)
188196
mt76_dma_sync_idx(dev, q);
189197

0 commit comments

Comments
 (0)