From b4468cc6f2aeccaea74baa3b211a49851fd84158 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 7 Apr 2015 16:55:14 -0700 Subject: [PATCH 1/3] sungem, sunhme, sunvnet: Update drivers to use dma_wmb/rmb This patch goes through and replaces wmb/rmb with dma_wmb/dma_rmb in cases where the barrier is being used to order writes or reads to just memory and doesn't involve any programmed I/O. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sungem.c | 14 +++++++------- drivers/net/ethernet/sun/sunhme.c | 16 ++++++++-------- drivers/net/ethernet/sun/sunvnet.c | 6 +++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 74e9b148378c..e23a642357e7 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -718,7 +718,7 @@ static __inline__ void gem_post_rxds(struct gem *gp, int limit) cluster_start = curr = (gp->rx_new & ~(4 - 1)); count = 0; kick = -1; - wmb(); + dma_wmb(); while (curr != limit) { curr = NEXT_RX(curr); if (++count == 4) { @@ -1038,7 +1038,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, if (gem_intme(entry)) ctrl |= TXDCTRL_INTME; txd->buffer = cpu_to_le64(mapping); - wmb(); + dma_wmb(); txd->control_word = cpu_to_le64(ctrl); entry = NEXT_TX(entry); } else { @@ -1076,7 +1076,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, txd = &gp->init_block->txd[entry]; txd->buffer = cpu_to_le64(mapping); - wmb(); + dma_wmb(); txd->control_word = cpu_to_le64(this_ctrl | len); if (gem_intme(entry)) @@ -1086,7 +1086,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, } txd = &gp->init_block->txd[first_entry]; txd->buffer = cpu_to_le64(first_mapping); - wmb(); + dma_wmb(); txd->control_word = cpu_to_le64(ctrl | TXDCTRL_SOF | intme | first_len); } @@ -1585,7 +1585,7 @@ static void gem_clean_rings(struct gem *gp) gp->rx_skbs[i] = NULL; } rxd->status_word = 0; - wmb(); + dma_wmb(); rxd->buffer = 0; } @@ -1647,7 +1647,7 @@ static void gem_init_rings(struct gem *gp) RX_BUF_ALLOC_SIZE(gp), PCI_DMA_FROMDEVICE); rxd->buffer = cpu_to_le64(dma_addr); - wmb(); + dma_wmb(); rxd->status_word = cpu_to_le64(RXDCTRL_FRESH(gp)); skb_reserve(skb, RX_OFFSET); } @@ -1656,7 +1656,7 @@ static void gem_init_rings(struct gem *gp) struct gem_txd *txd = &gb->txd[i]; txd->control_word = 0; - wmb(); + dma_wmb(); txd->buffer = 0; } wmb(); diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 7a8ca2c7b7df..cf4dcff051d5 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -196,14 +196,14 @@ static u32 sbus_hme_read32(void __iomem *reg) static void sbus_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) { rxd->rx_addr = (__force hme32)addr; - wmb(); + dma_wmb(); rxd->rx_flags = (__force hme32)flags; } static void sbus_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) { txd->tx_addr = (__force hme32)addr; - wmb(); + dma_wmb(); txd->tx_flags = (__force hme32)flags; } @@ -225,14 +225,14 @@ static u32 pci_hme_read32(void __iomem *reg) static void pci_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr) { rxd->rx_addr = (__force hme32)cpu_to_le32(addr); - wmb(); + dma_wmb(); rxd->rx_flags = (__force hme32)cpu_to_le32(flags); } static void pci_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr) { txd->tx_addr = (__force hme32)cpu_to_le32(addr); - wmb(); + dma_wmb(); txd->tx_flags = (__force hme32)cpu_to_le32(flags); } @@ -268,12 +268,12 @@ static u32 pci_hme_read_desc32(hme32 *p) sbus_readl(__reg) #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ do { (__rxd)->rx_addr = (__force hme32)(u32)(__addr); \ - wmb(); \ + dma_wmb(); \ (__rxd)->rx_flags = (__force hme32)(u32)(__flags); \ } while(0) #define hme_write_txd(__hp, __txd, __flags, __addr) \ do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \ - wmb(); \ + dma_wmb(); \ (__txd)->tx_flags = (__force hme32)(u32)(__flags); \ } while(0) #define hme_read_desc32(__hp, __p) ((__force u32)(hme32)*(__p)) @@ -293,12 +293,12 @@ do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \ readl(__reg) #define hme_write_rxd(__hp, __rxd, __flags, __addr) \ do { (__rxd)->rx_addr = (__force hme32)cpu_to_le32(__addr); \ - wmb(); \ + dma_wmb(); \ (__rxd)->rx_flags = (__force hme32)cpu_to_le32(__flags); \ } while(0) #define hme_write_txd(__hp, __txd, __flags, __addr) \ do { (__txd)->tx_addr = (__force hme32)cpu_to_le32(__addr); \ - wmb(); \ + dma_wmb(); \ (__txd)->tx_flags = (__force hme32)cpu_to_le32(__flags); \ } while(0) static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p) diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 401abf7254d3..53fe200e0b79 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -519,7 +519,7 @@ static int vnet_walk_rx_one(struct vnet_port *port, if (desc->hdr.state != VIO_DESC_READY) return 1; - rmb(); + dma_rmb(); viodbg(DATA, "vio_walk_rx_one desc[%02x:%02x:%08x:%08x:%llx:%llx]\n", desc->hdr.state, desc->hdr.ack, @@ -1380,7 +1380,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* This has to be a non-SMP write barrier because we are writing * to memory which is shared with the peer LDOM. */ - wmb(); + dma_wmb(); d->hdr.state = VIO_DESC_READY; @@ -1395,7 +1395,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) * is marked READY, but start_cons was false. * If so, vnet_ack() should send out the missed "start" trigger. * - * Note that the wmb() above makes sure the cookies et al. are + * Note that the dma_wmb() above makes sure the cookies et al. are * not globally visible before the VIO_DESC_READY, and that the * stores are ordered correctly by the compiler. The consumer will * not proceed until the VIO_DESC_READY is visible assuring that From 03cc864a2571af278fc83d24b6a78d8424f92736 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 7 Apr 2015 16:55:21 -0700 Subject: [PATCH 2/3] s2io: Update driver to use dma_wmb This change updates several spots where a wmb was being used to instead use a dma_wmb to flush out writes before updating the control portion of the descriptor. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- drivers/net/ethernet/neterion/s2io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 092dcae0d4a9..1e0f72b65459 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -2520,7 +2520,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, DBG_PRINT(INFO_DBG, "%s: Could not allocate skb\n", ring->dev->name); if (first_rxdp) { - wmb(); + dma_wmb(); first_rxdp->Control_1 |= RXD_OWN_XENA; } swstats->mem_alloc_fail_cnt++; @@ -2634,7 +2634,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, rxdp->Control_2 |= SET_RXD_MARKER; if (!(alloc_tab & ((1 << rxsync_frequency) - 1))) { if (first_rxdp) { - wmb(); + dma_wmb(); first_rxdp->Control_1 |= RXD_OWN_XENA; } first_rxdp = rxdp; @@ -2649,7 +2649,7 @@ end: * and other fields are seen by adapter correctly. */ if (first_rxdp) { - wmb(); + dma_wmb(); first_rxdp->Control_1 |= RXD_OWN_XENA; } @@ -6950,7 +6950,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) } set_rxd_buffer_size(sp, rxdp, size); - wmb(); + dma_wmb(); /* flip the Ownership bit to Hardware */ rxdp->Control_1 |= RXD_OWN_XENA; } From 837a1dba0078d0bad755f6cb13a48c1623d11ff5 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 7 Apr 2015 16:55:27 -0700 Subject: [PATCH 3/3] e1000, e1000e: Use dma_rmb instead of rmb for descriptor read ordering This change replaces calls to rmb with dma_rmb in the case where we want to order all follow-on descriptor reads after the check for the descriptor status bit. Signed-off-by: Alexander Duyck Acked-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/e1000/e1000_main.c | 6 +++--- drivers/net/ethernet/intel/e1000e/netdev.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index b548ef0cf56b..983eb4e6f7aa 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -3856,7 +3856,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && (count < tx_ring->count)) { bool cleaned = false; - rmb(); /* read buffer_info after eop_desc */ + dma_rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { tx_desc = E1000_TX_DESC(*tx_ring, i); buffer_info = &tx_ring->buffer_info[i]; @@ -4154,7 +4154,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, if (*work_done >= work_to_do) break; (*work_done)++; - rmb(); /* read descriptor and rx_buffer_info after status DD */ + dma_rmb(); /* read descriptor and rx_buffer_info after status DD */ status = rx_desc->status; @@ -4375,7 +4375,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, if (*work_done >= work_to_do) break; (*work_done)++; - rmb(); /* read descriptor and rx_buffer_info after status DD */ + dma_rmb(); /* read descriptor and rx_buffer_info after status DD */ status = rx_desc->status; length = le16_to_cpu(rx_desc->length); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 4e56c3195989..74ec185a697f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -947,7 +947,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, if (*work_done >= work_to_do) break; (*work_done)++; - rmb(); /* read descriptor and rx_buffer_info after status DD */ + dma_rmb(); /* read descriptor and rx_buffer_info after status DD */ skb = buffer_info->skb; buffer_info->skb = NULL; @@ -1232,7 +1232,7 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring) (count < tx_ring->count)) { bool cleaned = false; - rmb(); /* read buffer_info after eop_desc */ + dma_rmb(); /* read buffer_info after eop_desc */ for (; !cleaned; count++) { tx_desc = E1000_TX_DESC(*tx_ring, i); buffer_info = &tx_ring->buffer_info[i]; @@ -1332,7 +1332,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, break; (*work_done)++; skb = buffer_info->skb; - rmb(); /* read descriptor and rx_buffer_info after status DD */ + dma_rmb(); /* read descriptor and rx_buffer_info after status DD */ /* in the packet split case this is header only */ prefetch(skb->data - NET_IP_ALIGN); @@ -1536,7 +1536,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, if (*work_done >= work_to_do) break; (*work_done)++; - rmb(); /* read descriptor and rx_buffer_info after status DD */ + dma_rmb(); /* read descriptor and rx_buffer_info after status DD */ skb = buffer_info->skb; buffer_info->skb = NULL;