Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mvpp2: Use relaxed I/O in data path

Use relaxed I/O on the hot path. This achieves significant performance
improvements. On a 10G link, this makes a basic iperf TCP test go from
an average of 4.5 Gbits/sec to about 9.40 Gbits/sec.

Signed-off-by: Yan Markman <ymarkman@marvell.com>
[Maxime: Commit message, cosmetic changes]
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Yan Markman and committed by
David S. Miller
cdcfeb0f 5f75a186

+30 -13
+30 -13
drivers/net/ethernet/marvell/mvpp2.c
··· 1359 1359 return readl(priv->swth_base[0] + offset); 1360 1360 } 1361 1361 1362 + static u32 mvpp2_read_relaxed(struct mvpp2 *priv, u32 offset) 1363 + { 1364 + return readl_relaxed(priv->swth_base[0] + offset); 1365 + } 1362 1366 /* These accessors should be used to access: 1363 1367 * 1364 1368 * - per-CPU registers, where each CPU has its own copy of the ··· 1409 1405 u32 offset) 1410 1406 { 1411 1407 return readl(priv->swth_base[cpu] + offset); 1408 + } 1409 + 1410 + static void mvpp2_percpu_write_relaxed(struct mvpp2 *priv, int cpu, 1411 + u32 offset, u32 data) 1412 + { 1413 + writel_relaxed(data, priv->swth_base[cpu] + offset); 1414 + } 1415 + 1416 + static u32 mvpp2_percpu_read_relaxed(struct mvpp2 *priv, int cpu, 1417 + u32 offset) 1418 + { 1419 + return readl_relaxed(priv->swth_base[cpu] + offset); 1412 1420 } 1413 1421 1414 1422 static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port, ··· 4458 4442 << MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT) & 4459 4443 MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK; 4460 4444 4461 - mvpp2_percpu_write(port->priv, cpu, 4462 - MVPP22_BM_ADDR_HIGH_RLS_REG, val); 4445 + mvpp2_percpu_write_relaxed(port->priv, cpu, 4446 + MVPP22_BM_ADDR_HIGH_RLS_REG, val); 4463 4447 } 4464 4448 4465 4449 /* MVPP2_BM_VIRT_RLS_REG is not interpreted by HW, and simply ··· 4467 4451 * descriptor. Instead of storing the virtual address, we 4468 4452 * store the physical address 4469 4453 */ 4470 - mvpp2_percpu_write(port->priv, cpu, 4471 - MVPP2_BM_VIRT_RLS_REG, buf_phys_addr); 4472 - mvpp2_percpu_write(port->priv, cpu, 4473 - MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr); 4454 + mvpp2_percpu_write_relaxed(port->priv, cpu, 4455 + MVPP2_BM_VIRT_RLS_REG, buf_phys_addr); 4456 + mvpp2_percpu_write_relaxed(port->priv, cpu, 4457 + MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr); 4474 4458 4475 4459 put_cpu(); 4476 4460 } ··· 5562 5546 if ((aggr_txq->count + num) > MVPP2_AGGR_TXQ_SIZE) { 5563 5547 /* Update number of occupied aggregated Tx descriptors */ 5564 5548 int cpu = smp_processor_id(); 5565 - u32 val = mvpp2_read(priv, MVPP2_AGGR_TXQ_STATUS_REG(cpu)); 5549 + u32 val = mvpp2_read_relaxed(priv, 5550 + MVPP2_AGGR_TXQ_STATUS_REG(cpu)); 5566 5551 5567 5552 aggr_txq->count = val & MVPP2_AGGR_TXQ_PENDING_MASK; 5568 5553 } ··· 5587 5570 int cpu = smp_processor_id(); 5588 5571 5589 5572 val = (txq->id << MVPP2_TXQ_RSVD_REQ_Q_OFFSET) | num; 5590 - mvpp2_percpu_write(priv, cpu, MVPP2_TXQ_RSVD_REQ_REG, val); 5573 + mvpp2_percpu_write_relaxed(priv, cpu, MVPP2_TXQ_RSVD_REQ_REG, val); 5591 5574 5592 - val = mvpp2_percpu_read(priv, cpu, MVPP2_TXQ_RSVD_RSLT_REG); 5575 + val = mvpp2_percpu_read_relaxed(priv, cpu, MVPP2_TXQ_RSVD_RSLT_REG); 5593 5576 5594 5577 return val & MVPP2_TXQ_RSVD_RSLT_MASK; 5595 5578 } ··· 5694 5677 u32 val; 5695 5678 5696 5679 /* Reading status reg resets transmitted descriptor counter */ 5697 - val = mvpp2_percpu_read(port->priv, smp_processor_id(), 5698 - MVPP2_TXQ_SENT_REG(txq->id)); 5680 + val = mvpp2_percpu_read_relaxed(port->priv, smp_processor_id(), 5681 + MVPP2_TXQ_SENT_REG(txq->id)); 5699 5682 5700 5683 return (val & MVPP2_TRANSMITTED_COUNT_MASK) >> 5701 5684 MVPP2_TRANSMITTED_COUNT_OFFSET; ··· 7061 7044 * 7062 7045 * Each CPU has its own Rx/Tx cause register 7063 7046 */ 7064 - cause_rx_tx = mvpp2_percpu_read(port->priv, qv->sw_thread_id, 7065 - MVPP2_ISR_RX_TX_CAUSE_REG(port->id)); 7047 + cause_rx_tx = mvpp2_percpu_read_relaxed(port->priv, qv->sw_thread_id, 7048 + MVPP2_ISR_RX_TX_CAUSE_REG(port->id)); 7066 7049 7067 7050 cause_misc = cause_rx_tx & MVPP2_CAUSE_MISC_SUM_MASK; 7068 7051 if (cause_misc) {