Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e42d8cee authored by Sinan Kaya's avatar Sinan Kaya Committed by David S. Miller
Browse files

net: qlge: Eliminate duplicate barriers on weakly-ordered archs



Code includes wmb() followed by writel(). 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.

Create a new wrapper function with relaxed write operator. Use the new
wrapper when a write is following a wmb().

Signed-off-by: default avatarSinan Kaya <okaya@codeaurora.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7f883c77
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -2184,6 +2184,22 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr)
	mmiowb();
}

/*
 * Doorbell Registers:
 * Doorbell registers are virtual registers in the PCI memory space.
 * The space is allocated by the chip during PCI initialization.  The
 * device driver finds the doorbell address in BAR 3 in PCI config space.
 * The registers are used to control outbound and inbound queues. For
 * example, the producer index for an outbound queue.  Each queue uses
 * 1 4k chunk of memory.  The lower half of the space is for outbound
 * queues. The upper half is for inbound queues.
 * Caller has to guarantee ordering.
 */
static inline void ql_write_db_reg_relaxed(u32 val, void __iomem *addr)
{
	writel_relaxed(val, addr);
}

/*
 * Shadow Registers:
 * Outbound queues have a consumer index that is maintained by the chip.
+2 −1
Original line number Diff line number Diff line
@@ -2700,7 +2700,8 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
		tx_ring->prod_idx = 0;
	wmb();

	ql_write_db_reg(tx_ring->prod_idx, tx_ring->prod_idx_db_reg);
	ql_write_db_reg_relaxed(tx_ring->prod_idx, tx_ring->prod_idx_db_reg);
	mmiowb();
	netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
		     "tx queued, slot %d, len %d\n",
		     tx_ring->prod_idx, skb->len);