ena module for Driver Update Program
CentOS Sources
2019-01-09 fc384122a7a805dde4dbbf3c4c4ef94a5ca0f2fe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
Date: Tue, 30 Oct 2018 13:25:16 -0400
From: linville@redhat.com
To: rhkernel-list@redhat.com
Cc: Lin Liu <linl@redhat.com>
Subject: [RHEL7 01/28] net: ena: Eliminate duplicate barriers on
 weakly-ordered archs
 
From: "John W. Linville" <linville@redhat.com>
 
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1633418
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=18850510
 
Code includes barrier() 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 barrier().
 
Since code already has an explicit barrier call, changing writel() to
writel_relaxed() and adding mmiowb() for ordering protection.
 
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 6d2e1a8d5e25e5f4563f5ea24bcb5da1ae261b26)
Signed-off-by: John W. Linville <linville@redhat.com>
---
 drivers/net/ethernet/amazon/ena/ena_com.c     | 8 ++++++--
 drivers/net/ethernet/amazon/ena/ena_eth_com.h | 8 ++++++--
 drivers/net/ethernet/amazon/ena/ena_netdev.c  | 5 +++--
 3 files changed, 15 insertions(+), 6 deletions(-)
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
index bf2de5298005..1b9d3130af4d 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -631,8 +631,10 @@ static u32 ena_com_reg_bar_read32(struct ena_com_dev *ena_dev, u16 offset)
      */
     wmb();
 
-    writel(mmio_read_reg, ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
+    writel_relaxed(mmio_read_reg,
+               ena_dev->reg_bar + ENA_REGS_MMIO_REG_READ_OFF);
 
+    mmiowb();
     for (i = 0; i < timeout; i++) {
         if (read_resp->req_id == mmio_read->seq_num)
             break;
@@ -1826,7 +1828,9 @@ void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data)
 
     /* write the aenq doorbell after all AENQ descriptors were read */
     mb();
-    writel((u32)aenq->head, dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
+    writel_relaxed((u32)aenq->head,
+               dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
+    mmiowb();
 }
 
 int ena_com_dev_reset(struct ena_com_dev *ena_dev,
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
index 2f7657227cfe..6fdc753d9483 100644
--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -107,7 +107,8 @@ static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq)
     return io_sq->q_depth - 1 - cnt;
 }
 
-static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
+static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq,
+                        bool relaxed)
 {
     u16 tail;
 
@@ -116,7 +117,10 @@ static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
     pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
          io_sq->qid, tail);
 
-    writel(tail, io_sq->db_addr);
+    if (relaxed)
+        writel_relaxed(tail, io_sq->db_addr);
+    else
+        writel(tail, io_sq->db_addr);
 
     return 0;
 }
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index c8da977ca435..4ae8749699bb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -556,7 +556,8 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
          * issue a doorbell
          */
         wmb();
-        ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq);
+        ena_com_write_sq_doorbell(rx_ring->ena_com_io_sq, true);
+        mmiowb();
     }
 
     rx_ring->next_to_use = next_to_use;
@@ -2144,7 +2145,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
     if (netif_xmit_stopped(txq) || !skb->xmit_more) {
         /* trigger the dma engine */
-        ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
+        ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq, false);
         u64_stats_update_begin(&tx_ring->syncp);
         tx_ring->tx_stats.doorbells++;
         u64_stats_update_end(&tx_ring->syncp);
-- 
2.17.1