Skip to content

Commit 90c00f8

Browse files
committed
Merge branch 'net-driver-barriers'
Sinan Kaya says: ==================== netdev: Eliminate duplicate barriers on weakly-ordered archs Code includes wmb() followed by writel() in multiple places. writel() already has a barrier on some architectures like arm64. This ends up CPU observing two barriers back to back before executing the register write. Since code already has an explicit barrier call, changing writel() to writel_relaxed(). I did a regex search for wmb() followed by writel() in each drivers directory. I scrubbed the ones I care about in this series. I considered "ease of change", "popular usage" and "performance critical path" as the determining criteria for my filtering. We used relaxed API heavily on ARM for a long time but it did not exist on other architectures. For this reason, relaxed architectures have been paying double penalty in order to use the common drivers. Now that relaxed API is present on all architectures, we can go and scrub all drivers to see what needs to change and what can remain. We start with mostly used ones and hope to increase the coverage over time. It will take a while to cover all drivers. Feel free to apply patches individually. Changes since v6: - bring back amazon ena and add mmiowb, remove ena_com_write_sq_doorbell_rel(). - remove extra mmiowb in bnx2x - correct spelling mistake in bnx2x: Replace doorbell barrier() with wmb() ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 14ef85b + 6d2e1a8 commit 90c00f8

File tree

15 files changed

+68
-24
lines changed

15 files changed

+68
-24
lines changed

drivers/net/ethernet/amazon/ena/ena_com.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,10 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
631631
*/
632632
wmb();
633633

634-
writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
634+
writel_relaxed(mmio_read_reg,
635+
ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
635636

637+
mmiowb();
636638
for (i = 0; i < timeout; i++) {
637639
if (read_resp->req_id == mmio_read->seq_num)
638640
break;
@@ -1826,7 +1828,9 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
18261828

18271829
/* write the aenq doorbell after all AENQ descriptors were read */
18281830
mb();
1829-
writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
1831+
writel_relaxed((u32)aenq->head,
1832+
dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
1833+
mmiowb();
18301834
}
18311835

18321836
int ena_com_dev_reset(struct ena_com_dev *ena_dev,

drivers/net/ethernet/amazon/ena/ena_eth_com.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq)
107107
return io_sq->q_depth - 1 - cnt;
108108
}
109109

110-
static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
110+
static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq,
111+
bool relaxed)
111112
{
112113
u16 tail;
113114

@@ -116,7 +117,10 @@ static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
116117
pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
117118
io_sq->qid, tail);
118119

119-
writel(tail, io_sq->db_addr);
120+
if (relaxed)
121+
writel_relaxed(tail, io_sq->db_addr);
122+
else
123+
writel(tail, io_sq->db_addr);
120124

121125
return 0;
122126
}

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
556556
* issue a doorbell
557557
*/
558558
wmb();
559-
ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
559+
ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq, true);
560+
mmiowb();
560561
}
561562

562563
rx_ring->next_to_use = next_to_use;
@@ -2151,7 +2152,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
21512152

21522153
if (netif_xmit_stopped(txq) || !skb->xmit_more) {
21532154
/* trigger the dma engine */
2154-
ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
2155+
ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq, false);
21552156
u64_stats_update_begin(&tx_ring->syncp);
21562157
tx_ring->tx_stats.doorbells++;
21572158
u64_stats_update_end(&tx_ring->syncp);

drivers/net/ethernet/broadcom/bnx2x/bnx2x.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ do { \
166166
#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
167167
#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset))
168168

169+
#define REG_WR_RELAXED(bp, offset, val) \
170+
writel_relaxed((u32)val, REG_ADDR(bp, offset))
171+
172+
#define REG_WR16_RELAXED(bp, offset, val) \
173+
writew_relaxed((u16)val, REG_ADDR(bp, offset))
174+
169175
#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
170176
#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
171177
#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
@@ -758,10 +764,8 @@ struct bnx2x_fastpath {
758764
#if (BNX2X_DB_SHIFT < BNX2X_DB_MIN_SHIFT)
759765
#error "Min DB doorbell stride is 8"
760766
#endif
761-
#define DOORBELL(bp, cid, val) \
762-
do { \
763-
writel((u32)(val), bp->doorbells + (bp->db_size * (cid))); \
764-
} while (0)
767+
#define DOORBELL_RELAXED(bp, cid, val) \
768+
writel_relaxed((u32)(val), (bp)->doorbells + ((bp)->db_size * (cid)))
765769

766770
/* TX CSUM helpers */
767771
#define SKB_CS_OFF(skb) (offsetof(struct tcphdr, check) - \

drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4153,9 +4153,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
41534153
wmb();
41544154

41554155
txdata->tx_db.data.prod += nbd;
4156-
barrier();
4156+
/* make sure descriptor update is observed by HW */
4157+
wmb();
41574158

4158-
DOORBELL(bp, txdata->cid, txdata->tx_db.raw);
4159+
DOORBELL_RELAXED(bp, txdata->cid, txdata->tx_db.raw);
41594160

41604161
mmiowb();
41614162

drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
522522
wmb();
523523

524524
for (i = 0; i < sizeof(rx_prods)/4; i++)
525-
REG_WR(bp, fp->ustorm_rx_prods_offset + i*4,
526-
((u32 *)&rx_prods)[i]);
525+
REG_WR_RELAXED(bp, fp->ustorm_rx_prods_offset + i * 4,
526+
((u32 *)&rx_prods)[i]);
527527

528528
mmiowb(); /* keep prod updates ordered */
529529

drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,8 +2591,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
25912591
wmb();
25922592

25932593
txdata->tx_db.data.prod += 2;
2594-
barrier();
2595-
DOORBELL(bp, txdata->cid, txdata->tx_db.raw);
2594+
/* make sure descriptor update is observed by the HW */
2595+
wmb();
2596+
DOORBELL_RELAXED(bp, txdata->cid, txdata->tx_db.raw);
25962597

25972598
mmiowb();
25982599
barrier();

drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,8 +3817,8 @@ static void bnx2x_sp_prod_update(struct bnx2x *bp)
38173817
*/
38183818
mb();
38193819

3820-
REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
3821-
bp->spq_prod_idx);
3820+
REG_WR16_RELAXED(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
3821+
bp->spq_prod_idx);
38223822
mmiowb();
38233823
}
38243824

drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping)
170170
wmb();
171171

172172
/* Trigger the PF FW */
173-
writeb(1, &zone_data->trigger.vf_pf_channel.addr_valid);
173+
writeb_relaxed(1, &zone_data->trigger.vf_pf_channel.addr_valid);
174+
175+
mmiowb();
174176

175177
/* Wait for PF to complete */
176178
while ((tout >= 0) && (!*done)) {

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1922,7 +1922,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
19221922
/* Sync BD data before updating doorbell */
19231923
wmb();
19241924

1925-
bnxt_db_write(bp, db, DB_KEY_TX | prod);
1925+
bnxt_db_write_relaxed(bp, db, DB_KEY_TX | prod);
19261926
}
19271927

19281928
cpr->cp_raw_cons = raw_cons;

0 commit comments

Comments
 (0)