* [PATCH v4 14/17] net: qlge: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Harish Patil,
Manish Chopra, Dept-GELinuxNICDev, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/qlogic/qlge/qlge.h | 18 ++++++++++++++++++
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 2 +-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h
index 84ac50f..1465986 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge.h
+++ b/drivers/net/ethernet/qlogic/qlge/qlge.h
@@ -2185,6 +2185,24 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr)
}
/*
+ * 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);
+ mmiowb();
+}
+
+
+/*
* Shadow Registers:
* Outbound queues have a consumer index that is maintained by the chip.
* Inbound queues have a producer index that is maintained by the chip.
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 50038d9..c222b7c 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -2700,7 +2700,7 @@ 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);
netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
"tx queued, slot %d, len %d\n",
tx_ring->prod_idx, skb->len);
--
2.7.4
^ permalink raw reply related
* [PATCH v4 13/17] net: cxgb3: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Santosh Raspatur,
linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/chelsio/cxgb3/adapter.h | 7 +++++++
drivers/net/ethernet/chelsio/cxgb3/sge.c | 19 ++++++++++---------
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/adapter.h b/drivers/net/ethernet/chelsio/cxgb3/adapter.h
index 087ff0f..0e21e66 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb3/adapter.h
@@ -281,6 +281,13 @@ static inline void t3_write_reg(struct adapter *adapter, u32 reg_addr, u32 val)
writel(val, adapter->regs + reg_addr);
}
+static inline void t3_write_reg_relaxed(struct adapter *adapter, u32 reg_addr,
+ u32 val)
+{
+ CH_DBG(adapter, MMIO, "setting register 0x%x to 0x%x\n", reg_addr, val);
+ writel_relaxed(val, adapter->regs + reg_addr);
+}
+
static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
{
return netdev_priv(adap->port[idx]);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/sge.c b/drivers/net/ethernet/chelsio/cxgb3/sge.c
index e988caa..0baab06 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c
@@ -487,7 +487,8 @@ static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
if (q->pend_cred >= q->credits / 4) {
q->pend_cred = 0;
wmb();
- t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+ t3_write_reg_relaxed(adap, A_SG_KDOORBELL,
+ V_EGRCNTX(q->cntxt_id));
}
}
@@ -1058,8 +1059,8 @@ static inline void check_ring_tx_db(struct adapter *adap, struct sge_txq *q)
}
#else
wmb(); /* write descriptors before telling HW */
- t3_write_reg(adap, A_SG_KDOORBELL,
- F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+ t3_write_reg_relaxed(adap, A_SG_KDOORBELL,
+ F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
#endif
}
@@ -1510,8 +1511,8 @@ static int ctrl_xmit(struct adapter *adap, struct sge_txq *q,
}
spin_unlock(&q->lock);
wmb();
- t3_write_reg(adap, A_SG_KDOORBELL,
- F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+ t3_write_reg_relaxed(adap, A_SG_KDOORBELL,
+ F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
return NET_XMIT_SUCCESS;
}
@@ -1554,8 +1555,8 @@ static void restart_ctrlq(unsigned long data)
spin_unlock(&q->lock);
wmb();
- t3_write_reg(qs->adap, A_SG_KDOORBELL,
- F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+ t3_write_reg_relaxed(qs->adap, A_SG_KDOORBELL,
+ F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}
/*
@@ -1793,8 +1794,8 @@ again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
#endif
wmb();
if (likely(written))
- t3_write_reg(adap, A_SG_KDOORBELL,
- F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
+ t3_write_reg_relaxed(adap, A_SG_KDOORBELL,
+ F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}
/**
--
2.7.4
^ permalink raw reply related
* [PATCH v4 12/17] net: cxgb4/cxgb4vf: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Ganesh Goudar,
Casey Leedom, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 6 ++++++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 13 +++++++------
drivers/net/ethernet/chelsio/cxgb4/sge.c | 12 ++++++------
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +-
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 14 ++++++++++++++
drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 18 ++++++++++--------
6 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 9040e13..6bde0b9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1202,6 +1202,12 @@ static inline void t4_write_reg(struct adapter *adap, u32 reg_addr, u32 val)
writel(val, adap->regs + reg_addr);
}
+static inline void t4_write_reg_relaxed(struct adapter *adap, u32 reg_addr,
+ u32 val)
+{
+ writel_relaxed(val, adap->regs + reg_addr);
+}
+
#ifndef readq
static inline u64 readq(const volatile void __iomem *addr)
{
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 7b452e8..276472d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1723,8 +1723,8 @@ int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx,
else
val = PIDX_T5_V(delta);
wmb();
- t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
- QID_V(qid) | val);
+ t4_write_reg_relaxed(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
+ QID_V(qid) | val);
}
out:
return ret;
@@ -1902,8 +1902,9 @@ static void enable_txq_db(struct adapter *adap, struct sge_txq *q)
* are committed before we tell HW about them.
*/
wmb();
- t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
- QID_V(q->cntxt_id) | PIDX_V(q->db_pidx_inc));
+ t4_write_reg_relaxed(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
+ QID_V(q->cntxt_id) |
+ PIDX_V(q->db_pidx_inc));
q->db_pidx_inc = 0;
}
q->db_disabled = 0;
@@ -2003,8 +2004,8 @@ static void sync_txq_pidx(struct adapter *adap, struct sge_txq *q)
else
val = PIDX_T5_V(delta);
wmb();
- t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
- QID_V(q->cntxt_id) | val);
+ t4_write_reg_relaxed(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
+ QID_V(q->cntxt_id) | val);
}
out:
q->db_disabled = 0;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 6e310a0..7388aac 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -530,11 +530,11 @@ static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
* mechanism.
*/
if (unlikely(q->bar2_addr == NULL)) {
- t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
- val | QID_V(q->cntxt_id));
+ t4_write_reg_relaxed(adap, MYPF_REG(SGE_PF_KDOORBELL_A),
+ val | QID_V(q->cntxt_id));
} else {
- writel(val | QID_V(q->bar2_qid),
- q->bar2_addr + SGE_UDB_KDOORBELL);
+ writel_relaxed(val | QID_V(q->bar2_qid),
+ q->bar2_addr + SGE_UDB_KDOORBELL);
/* This Write memory Barrier will force the write to
* the User Doorbell area to be flushed.
@@ -986,8 +986,8 @@ inline void cxgb4_ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
(q->bar2_addr + SGE_UDB_WCDOORBELL),
wr);
} else {
- writel(val | QID_V(q->bar2_qid),
- q->bar2_addr + SGE_UDB_KDOORBELL);
+ writel_relaxed(val | QID_V(q->bar2_qid),
+ q->bar2_addr + SGE_UDB_KDOORBELL);
}
/* This Write Memory Barrier will force the write to the User
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 920bccd..8b723a0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -139,7 +139,7 @@ void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
{
while (nregs--) {
t4_write_reg(adap, addr_reg, start_idx++);
- t4_write_reg(adap, data_reg, *vals++);
+ t4_write_reg_relaxed(adap, data_reg, *vals++);
}
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 5883f09..00247be4 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -442,6 +442,20 @@ static inline void t4_write_reg(struct adapter *adapter, u32 reg_addr, u32 val)
writel(val, adapter->regs + reg_addr);
}
+/**
+ * t4_write_reg_relaxed - write a HW register without ordering guarantees
+ * @adapter: the adapter
+ * @reg_addr: the register address
+ * @val: the value to write
+ *
+ * Write a 32-bit value into the given HW register.
+ */
+static inline void t4_write_reg_relaxed(struct adapter *adapter, u32 reg_addr,
+ u32 val)
+{
+ writel_relaxed(val, adapter->regs + reg_addr);
+}
+
#ifndef readq
static inline u64 readq(const volatile void __iomem *addr)
{
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index dfce5df..a3a420b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -546,12 +546,13 @@ static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl)
* mechanism.
*/
if (unlikely(fl->bar2_addr == NULL)) {
- t4_write_reg(adapter,
- T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
- QID_V(fl->cntxt_id) | val);
+ t4_write_reg_relaxed(adapter,
+ T4VF_SGE_BASE_ADDR +
+ SGE_VF_KDOORBELL,
+ QID_V(fl->cntxt_id) | val);
} else {
- writel(val | QID_V(fl->bar2_qid),
- fl->bar2_addr + SGE_UDB_KDOORBELL);
+ writel_relaxed(val | QID_V(fl->bar2_qid),
+ fl->bar2_addr + SGE_UDB_KDOORBELL);
/* This Write memory Barrier will force the write to
* the User Doorbell area to be flushed.
@@ -980,8 +981,9 @@ static inline void ring_tx_db(struct adapter *adapter, struct sge_txq *tq,
if (unlikely(tq->bar2_addr == NULL)) {
u32 val = PIDX_V(n);
- t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
- QID_V(tq->cntxt_id) | val);
+ t4_write_reg_relaxed(adapter,
+ T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL,
+ QID_V(tq->cntxt_id) | val);
} else {
u32 val = PIDX_T5_V(n);
@@ -1026,7 +1028,7 @@ static inline void ring_tx_db(struct adapter *adapter, struct sge_txq *tq,
count--;
}
} else
- writel(val | QID_V(tq->bar2_qid),
+ writel_relaxed(val | QID_V(tq->bar2_qid),
tq->bar2_addr + SGE_UDB_KDOORBELL);
/* This Write Memory Barrier will force the write to the User
--
2.7.4
^ permalink raw reply related
* [PATCH v4 11/17] bnx2x: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Ariel Elior,
everest-linux-l2, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 9 ++++++++-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 ++--
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 21 +++++++++++----------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 2 +-
5 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 352beff..ac38db9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -166,6 +166,12 @@ do { \
#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset))
+#define REG_WR_RELAXED(bp, offset, val) writel_relaxed((u32)val,\
+ REG_ADDR(bp, offset))
+
+#define REG_WR16_RELAXED(bp, offset, val) \
+ writew_relaxed((u16)val, REG_ADDR(bp, offset))
+
#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
@@ -760,7 +766,8 @@ struct bnx2x_fastpath {
#endif
#define DOORBELL(bp, cid, val) \
do { \
- writel((u32)(val), bp->doorbells + (bp->db_size * (cid))); \
+ writel_relaxed((u32)(val),\
+ bp->doorbells + (bp->db_size * (cid))); \
} while (0)
/* TX CSUM helpers */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index a5265e1..a8ce5c5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -522,8 +522,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
wmb();
for (i = 0; i < sizeof(rx_prods)/4; i++)
- REG_WR(bp, fp->ustorm_rx_prods_offset + i*4,
- ((u32 *)&rx_prods)[i]);
+ REG_WR_RELAXED(bp, fp->ustorm_rx_prods_offset + i * 4,
+ ((u32 *)&rx_prods)[i]);
mmiowb(); /* keep prod updates ordered */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 74fc9af..2dea1b6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -1608,8 +1608,8 @@ static void bnx2x_hc_int_enable(struct bnx2x *bp)
} else
val = 0xffff;
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
+ REG_WR_RELAXED(bp, HC_REG_TRAILING_EDGE_0 + port * 8, val);
+ REG_WR_RELAXED(bp, HC_REG_LEADING_EDGE_0 + port * 8, val);
}
/* Make sure that interrupts are indeed enabled from here on */
@@ -1672,8 +1672,8 @@ static void bnx2x_igu_int_enable(struct bnx2x *bp)
} else
val = 0xffff;
- REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val);
- REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val);
+ REG_WR_RELAXED(bp, IGU_REG_TRAILING_EDGE_LATCH, val);
+ REG_WR_RELAXED(bp, IGU_REG_LEADING_EDGE_LATCH, val);
/* Make sure that interrupts are indeed enabled from here on */
mmiowb();
@@ -3817,8 +3817,8 @@ static void bnx2x_sp_prod_update(struct bnx2x *bp)
*/
mb();
- REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
- bp->spq_prod_idx);
+ REG_WR16_RELAXED(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
+ bp->spq_prod_idx);
mmiowb();
}
@@ -7761,7 +7761,7 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, bool is_pf)
barrier();
DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
ctl, igu_addr_ctl);
- REG_WR(bp, igu_addr_ctl, ctl);
+ REG_WR_RELAXED(bp, igu_addr_ctl, ctl);
mmiowb();
barrier();
@@ -9720,13 +9720,14 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global)
barrier();
mmiowb();
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- reset_mask2 & (~stay_reset2));
+ REG_WR_RELAXED(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+ reset_mask2 & (~stay_reset2));
barrier();
mmiowb();
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1);
+ REG_WR_RELAXED(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+ reset_mask1);
mmiowb();
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index ffa7959..40e55d8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -105,7 +105,7 @@ static void bnx2x_vf_igu_ack_sb(struct bnx2x *bp, struct bnx2x_virtf *vf,
DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
ctl, igu_addr_ctl);
- REG_WR(bp, igu_addr_ctl, ctl);
+ REG_WR_RELAXED(bp, igu_addr_ctl, ctl);
mmiowb();
barrier();
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index 76a4668..3b2f1bd 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -170,7 +170,7 @@ static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping)
wmb();
/* Trigger the PF FW */
- writeb(1, &zone_data->trigger.vf_pf_channel.addr_valid);
+ writeb_relaxed(1, &zone_data->trigger.vf_pf_channel.addr_valid);
/* Wait for PF to complete */
while ((tout >= 0) && (!*done)) {
--
2.7.4
^ permalink raw reply related
* [PATCH v4 10/17] qlcnic: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Harish Patil,
Manish Chopra, Dept-GELinuxNICDev, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Acked-by: Manish Chopra <manish.chopra@cavium.com>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 46b0372..97c146e7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -478,7 +478,7 @@ irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
wmb();
/* clear the interrupt trigger control register */
- writel(0, adapter->isr_int_vec);
+ writel_relaxed(0, adapter->isr_int_vec);
intr_val = readl(adapter->isr_int_vec);
do {
intr_val = readl(adapter->tgt_status_reg);
--
2.7.4
^ permalink raw reply related
* [PATCH v4 09/17] net: qla3xxx: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Dept-GELinuxNICDev,
linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/qlogic/qla3xxx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 9e5264d..0e71b74 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -1858,8 +1858,8 @@ static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev)
qdev->small_buf_release_cnt -= 8;
}
wmb();
- writel(qdev->small_buf_q_producer_index,
- &port_regs->CommonRegs.rxSmallQProducerIndex);
+ writel_relaxed(qdev->small_buf_q_producer_index,
+ &port_regs->CommonRegs.rxSmallQProducerIndex);
}
}
--
2.7.4
^ permalink raw reply related
* [PATCH v4 08/17] drivers: net: cxgb: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: Kees Cook, Johannes Berg, linux-arm-msm, Allen Pais, linux-kernel,
Sinan Kaya, David S. Miller, linux-arm-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/chelsio/cxgb/sge.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c
index 30de26e..57891bd6 100644
--- a/drivers/net/ethernet/chelsio/cxgb/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c
@@ -495,7 +495,7 @@ static struct sk_buff *sched_skb(struct sge *sge, struct sk_buff *skb,
static inline void doorbell_pio(struct adapter *adapter, u32 val)
{
wmb();
- writel(val, adapter->regs + A_SG_DOORBELL);
+ writel_relaxed(val, adapter->regs + A_SG_DOORBELL);
}
/*
--
2.7.4
^ permalink raw reply related
* [PATCH v4 07/17] fm10k: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Jeff Kirsher,
intel-wired-lan, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index 8e12aae..eebef01 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -179,7 +179,7 @@ void fm10k_alloc_rx_buffers(struct fm10k_ring *rx_ring, u16 cleaned_count)
wmb();
/* notify hardware of new descriptors */
- writel(i, rx_ring->tail);
+ writel_relaxed(i, rx_ring->tail);
}
}
@@ -1054,7 +1054,7 @@ static void fm10k_tx_map(struct fm10k_ring *tx_ring,
/* notify HW of packet */
if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
- writel(i, tx_ring->tail);
+ writel_relaxed(i, tx_ring->tail);
/* we need this if more than one processor can write to our tail
* at a time, it synchronizes IO on IA64/Altix systems
--
2.7.4
^ permalink raw reply related
* [PATCH v4 06/17] ixgbevf: eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Jeff Kirsher,
intel-wired-lan, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 6bf778a..774b2a6 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -659,7 +659,7 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring,
* such as IA-64).
*/
wmb();
- writel(i, rx_ring->tail);
+ writel_relaxed(i, rx_ring->tail);
}
}
@@ -3644,7 +3644,7 @@ static void ixgbevf_tx_map(struct ixgbevf_ring *tx_ring,
tx_ring->next_to_use = i;
/* notify HW of packet */
- writel(i, tx_ring->tail);
+ writel_relaxed(i, tx_ring->tail);
return;
dma_error:
--
2.7.4
^ permalink raw reply related
* [PATCH v4 05/17] ixgbevf: keep writel() closer to wmb()
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-kernel, Sinan Kaya, intel-wired-lan,
Jeff Kirsher, linux-arm-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
Remove ixgbevf_write_tail() in favor of moving writel() close to
wmb().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 5 -----
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 ++--
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index f695242..11e893e 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -244,11 +244,6 @@ static inline u16 ixgbevf_desc_unused(struct ixgbevf_ring *ring)
return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
}
-static inline void ixgbevf_write_tail(struct ixgbevf_ring *ring, u32 value)
-{
- writel(value, ring->tail);
-}
-
#define IXGBEVF_RX_DESC(R, i) \
(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
#define IXGBEVF_TX_DESC(R, i) \
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 9b3d43d..6bf778a 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -659,7 +659,7 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_ring *rx_ring,
* such as IA-64).
*/
wmb();
- ixgbevf_write_tail(rx_ring, i);
+ writel(i, rx_ring->tail);
}
}
@@ -3644,7 +3644,7 @@ static void ixgbevf_tx_map(struct ixgbevf_ring *tx_ring,
tx_ring->next_to_use = i;
/* notify HW of packet */
- ixgbevf_write_tail(tx_ring, i);
+ writel(i, tx_ring->tail);
return;
dma_error:
--
2.7.4
^ permalink raw reply related
* [PATCH v4 04/17] igb: eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-kernel, Sinan Kaya, intel-wired-lan,
Jeff Kirsher, linux-arm-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/ethernet/intel/igb/igb_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index b88fae7..82aea92 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -5671,7 +5671,7 @@ static int igb_tx_map(struct igb_ring *tx_ring,
igb_maybe_stop_tx(tx_ring, DESC_NEEDED);
if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
- writel(i, tx_ring->tail);
+ writel_relaxed(i, tx_ring->tail);
/* we need this if more than one processor can write to our tail
* at a time, it synchronizes IO on IA64/Altix systems
@@ -8072,7 +8072,7 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
* such as IA-64).
*/
wmb();
- writel(i, rx_ring->tail);
+ writel_relaxed(i, rx_ring->tail);
}
}
--
2.7.4
^ permalink raw reply related
* [PATCH v4 03/17] igbvf: eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Jeff Kirsher,
intel-wired-lan, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/ethernet/intel/igbvf/netdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 4214c15..edb1c34 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -251,7 +251,7 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
* such as IA-64).
*/
wmb();
- writel(i, adapter->hw.hw_addr + rx_ring->tail);
+ writel_relaxed(i, adapter->hw.hw_addr + rx_ring->tail);
}
}
@@ -2297,7 +2297,7 @@ static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
tx_ring->buffer_info[first].next_to_watch = tx_desc;
tx_ring->next_to_use = i;
- writel(i, adapter->hw.hw_addr + tx_ring->tail);
+ writel_relaxed(i, adapter->hw.hw_addr + tx_ring->tail);
/* we need this if more than one processor can write to our tail
* at a time, it synchronizes IO on IA64/Altix systems
*/
--
2.7.4
^ permalink raw reply related
* [PATCH v4 02/17] ixgbe: eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Jeff Kirsher,
intel-wired-lan, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0da5aa2..58ed70f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1692,7 +1692,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
* such as IA-64).
*/
wmb();
- writel(i, rx_ring->tail);
+ writel_relaxed(i, rx_ring->tail);
}
}
@@ -2453,7 +2453,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
* know there are new descriptors to fetch.
*/
wmb();
- writel(ring->next_to_use, ring->tail);
+ writel_relaxed(ring->next_to_use, ring->tail);
xdp_do_flush_map();
}
@@ -8078,7 +8078,7 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
- writel(i, tx_ring->tail);
+ writel_relaxed(i, tx_ring->tail);
/* we need this if more than one processor can write to our tail
* at a time, it synchronizes IO on IA64/Altix systems
@@ -10014,7 +10014,7 @@ static void ixgbe_xdp_flush(struct net_device *dev)
* are new descriptors to fetch.
*/
wmb();
- writel(ring->next_to_use, ring->tail);
+ writel_relaxed(ring->next_to_use, ring->tail);
return;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v4 01/17] i40e/i40evf: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich
Cc: linux-arm-msm, linux-arm-kernel, Sinan Kaya, Jeff Kirsher,
intel-wired-lan, linux-kernel
In-Reply-To: <1521513753-7325-1-git-send-email-okaya@codeaurora.org>
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.
Since code already has an explicit barrier call, changing writel() to
writel_relaxed().
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 ++++----
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index e554aa6cf..9455869 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -185,7 +185,7 @@ static int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data,
/* Mark the data descriptor to be watched */
first->next_to_watch = tx_desc;
- writel(tx_ring->next_to_use, tx_ring->tail);
+ writel_relaxed(tx_ring->next_to_use, tx_ring->tail);
return 0;
dma_fail:
@@ -1375,7 +1375,7 @@ static inline void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)
* such as IA-64).
*/
wmb();
- writel(val, rx_ring->tail);
+ writel_relaxed(val, rx_ring->tail);
}
/**
@@ -2258,7 +2258,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
*/
wmb();
- writel(xdp_ring->next_to_use, xdp_ring->tail);
+ writel_relaxed(xdp_ring->next_to_use, xdp_ring->tail);
}
rx_ring->skb = skb;
@@ -3286,7 +3286,7 @@ static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
/* notify HW of packet */
if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
- writel(i, tx_ring->tail);
+ writel_relaxed(i, tx_ring->tail);
/* we need this if more than one processor can write to our tail
* at a time, it synchronizes IO on IA64/Altix systems
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 357d605..56eea20 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -667,7 +667,7 @@ static inline void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)
* such as IA-64).
*/
wmb();
- writel(val, rx_ring->tail);
+ writel_relaxed(val, rx_ring->tail);
}
/**
@@ -2243,7 +2243,7 @@ static inline void i40evf_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
/* notify HW of packet */
if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
- writel(i, tx_ring->tail);
+ writel_relaxed(i, tx_ring->tail);
/* we need this if more than one processor can write to our tail
* at a time, it synchronizes IO on IA64/Altix systems
--
2.7.4
^ permalink raw reply related
* [PATCH v4 00/17] netdev: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-20 2:42 UTC (permalink / raw)
To: netdev, timur, sulrich; +Cc: Sinan Kaya, linux-arm-msm, linux-arm-kernel
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 v3:
- https://www.spinics.net/lists/arm-kernel/msg641851.html
- group patches together into subsystems net:...
- collect reviewed and tested bys
- scrub barrier()
Sinan Kaya (17):
i40e/i40evf: Eliminate duplicate barriers on weakly-ordered archs
ixgbe: eliminate duplicate barriers on weakly-ordered archs
igbvf: eliminate duplicate barriers on weakly-ordered archs
igb: eliminate duplicate barriers on weakly-ordered archs
ixgbevf: keep writel() closer to wmb()
ixgbevf: eliminate duplicate barriers on weakly-ordered archs
fm10k: Eliminate duplicate barriers on weakly-ordered archs
drivers: net: cxgb: Eliminate duplicate barriers on weakly-ordered
archs
net: qla3xxx: Eliminate duplicate barriers on weakly-ordered archs
qlcnic: Eliminate duplicate barriers on weakly-ordered archs
bnx2x: Eliminate duplicate barriers on weakly-ordered archs
net: cxgb4/cxgb4vf: Eliminate duplicate barriers on weakly-ordered
archs
net: cxgb3: Eliminate duplicate barriers on weakly-ordered archs
net: qlge: Eliminate duplicate barriers on weakly-ordered archs
bnxt_en: Eliminate duplicate barriers on weakly-ordered archs
qed/qede: Eliminate duplicate barriers on weakly-ordered archs
net: ena: Eliminate duplicate barriers on weakly-ordered archs
drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++++--
drivers/net/ethernet/amazon/ena/ena_eth_com.h | 22 ++++++++++++++++++++--
drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++--
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 9 ++++++++-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 ++--
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 21 +++++++++++----------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 2 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 11 ++++++++++-
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +-
drivers/net/ethernet/chelsio/cxgb/sge.c | 2 +-
drivers/net/ethernet/chelsio/cxgb3/adapter.h | 7 +++++++
drivers/net/ethernet/chelsio/cxgb3/sge.c | 19 ++++++++++---------
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 6 ++++++
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 13 +++++++------
drivers/net/ethernet/chelsio/cxgb4/sge.c | 12 ++++++------
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +-
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 14 ++++++++++++++
drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 18 ++++++++++--------
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 4 ++--
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 ++++----
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 4 ++--
drivers/net/ethernet/intel/igb/igb_main.c | 4 ++--
drivers/net/ethernet/intel/igbvf/netdev.c | 4 ++--
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++----
drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 5 -----
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 ++--
drivers/net/ethernet/qlogic/qed/qed.h | 5 ++++-
drivers/net/ethernet/qlogic/qed/qed_hw.c | 12 ++++++++++++
drivers/net/ethernet/qlogic/qed/qed_hw.h | 14 ++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_int.c | 2 +-
drivers/net/ethernet/qlogic/qed/qed_l2.c | 2 +-
drivers/net/ethernet/qlogic/qed/qed_ll2.c | 2 +-
drivers/net/ethernet/qlogic/qed/qed_vf.c | 7 ++++---
drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 2 +-
drivers/net/ethernet/qlogic/qede/qede_fp.c | 4 ++--
drivers/net/ethernet/qlogic/qla3xxx.c | 4 ++--
.../net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 2 +-
drivers/net/ethernet/qlogic/qlge/qlge.h | 17 +++++++++++++++++
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 2 +-
include/linux/qed/qed_if.h | 17 +++++++++++++----
42 files changed, 215 insertions(+), 96 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [bpf-next V3 PATCH 00/15] XDP redirect memory return API
From: Jason Wang @ 2018-03-20 2:28 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: netdev, BjörnTöpel, magnus.karlsson, eugenia,
John Fastabend, Eran Ben Elisha, Saeed Mahameed, galp,
Daniel Borkmann, Alexei Starovoitov, Tariq Toukan
In-Reply-To: <20180319111057.12d3ee71@redhat.com>
On 2018年03月19日 18:10, Jesper Dangaard Brouer wrote:
> On Fri, 16 Mar 2018 17:04:17 +0800
> Jason Wang <jasowang@redhat.com> wrote:
>
>> Looks like the series forget to register memory model for tun and
>> virtio-net.
> Well, no. It is actually not strictly necessary to invoke
> xdp_rxq_info_reg_mem_model() because enum MEM_TYPE_PAGE_SHARED == 0.
> And if not passing an allocator pointer to the call, then an mem_id is
> not registered... and __xdp_return_frame() skips the rhashtable_lookup.
I see.
>
> I designed the API this way, because I want to support later adding an
> allocator even for the refcnt scheme MEM_TYPE_PAGE_SHARED. (As it
> would be a performance optimization to return the pages to the
> originating RX-CPU, and move the page refcnt dec back to that orig CPU).
>
> I did add an xdp_rxq_info_reg_mem_model() call to ixgbe, for human
> programmer "documentation" even-though it isn't strickly necessary. I
> guess, I could add similar calls to tun and virtio_net, and then we
> avoid any implicit assumptions. And makes it more clear that
> XDP_REDIRECT support use the memory model return API.
>
Yes, please do it or add a comment somewhere.
Thanks
^ permalink raw reply
* Re: [PATCH 12/36] fs: add new vfs_poll and file_can_poll helpers
From: Darrick J. Wong @ 2018-03-20 2:27 UTC (permalink / raw)
To: Christoph Hellwig
Cc: viro, Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180305212743.16664-13-hch@lst.de>
On Mon, Mar 05, 2018 at 01:27:19PM -0800, Christoph Hellwig wrote:
> These abstract out calls to the poll method in preparation for changes
> in how we poll.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> drivers/staging/comedi/drivers/serial2002.c | 4 ++--
> drivers/vfio/virqfd.c | 2 +-
> drivers/vhost/vhost.c | 2 +-
> fs/eventpoll.c | 5 ++---
> fs/select.c | 23 ++++++++---------------
> include/linux/poll.h | 12 ++++++++++++
> mm/memcontrol.c | 2 +-
For the fs/include/mm changes,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
The other conversions look fine to me too but I've never looked at them
before. :)
--D
> net/9p/trans_fd.c | 18 ++++--------------
> virt/kvm/eventfd.c | 2 +-
> 9 files changed, 32 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
> index b3f3b4a201af..5471b2212a62 100644
> --- a/drivers/staging/comedi/drivers/serial2002.c
> +++ b/drivers/staging/comedi/drivers/serial2002.c
> @@ -113,7 +113,7 @@ static void serial2002_tty_read_poll_wait(struct file *f, int timeout)
> long elapsed;
> __poll_t mask;
>
> - mask = f->f_op->poll(f, &table.pt);
> + mask = vfs_poll(f, &table.pt);
> if (mask & (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN |
> EPOLLHUP | EPOLLERR)) {
> break;
> @@ -136,7 +136,7 @@ static int serial2002_tty_read(struct file *f, int timeout)
>
> result = -1;
> if (!IS_ERR(f)) {
> - if (f->f_op->poll) {
> + if (file_can_poll(f)) {
> serial2002_tty_read_poll_wait(f, timeout);
>
> if (kernel_read(f, &ch, 1, &pos) == 1)
> diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c
> index 085700f1be10..2a1be859ee71 100644
> --- a/drivers/vfio/virqfd.c
> +++ b/drivers/vfio/virqfd.c
> @@ -166,7 +166,7 @@ int vfio_virqfd_enable(void *opaque,
> init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup);
> init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc);
>
> - events = irqfd.file->f_op->poll(irqfd.file, &virqfd->pt);
> + events = vfs_poll(irqfd.file, &virqfd->pt);
>
> /*
> * Check if there was an event already pending on the eventfd
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 1b3e8d2d5c8b..4d27e288bb1d 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -208,7 +208,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
> if (poll->wqh)
> return 0;
>
> - mask = file->f_op->poll(file, &poll->table);
> + mask = vfs_poll(file, &poll->table);
> if (mask)
> vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
> if (mask & EPOLLERR) {
> diff --git a/fs/eventpoll.c b/fs/eventpoll.c
> index 0f3494ed3ed0..2bebae5a38cf 100644
> --- a/fs/eventpoll.c
> +++ b/fs/eventpoll.c
> @@ -884,8 +884,7 @@ static __poll_t ep_item_poll(const struct epitem *epi, poll_table *pt,
>
> pt->_key = epi->event.events;
> if (!is_file_epoll(epi->ffd.file))
> - return epi->ffd.file->f_op->poll(epi->ffd.file, pt) &
> - epi->event.events;
> + return vfs_poll(epi->ffd.file, pt) & epi->event.events;
>
> ep = epi->ffd.file->private_data;
> poll_wait(epi->ffd.file, &ep->poll_wait, pt);
> @@ -2020,7 +2019,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
>
> /* The target file descriptor must support poll */
> error = -EPERM;
> - if (!tf.file->f_op->poll)
> + if (!file_can_poll(tf.file))
> goto error_tgt_fput;
>
> /* Check if EPOLLWAKEUP is allowed */
> diff --git a/fs/select.c b/fs/select.c
> index c6c504a814f9..ba91103707ea 100644
> --- a/fs/select.c
> +++ b/fs/select.c
> @@ -502,14 +502,10 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
> continue;
> f = fdget(i);
> if (f.file) {
> - const struct file_operations *f_op;
> - f_op = f.file->f_op;
> - mask = DEFAULT_POLLMASK;
> - if (f_op->poll) {
> - wait_key_set(wait, in, out,
> - bit, busy_flag);
> - mask = (*f_op->poll)(f.file, wait);
> - }
> + wait_key_set(wait, in, out, bit,
> + busy_flag);
> + mask = vfs_poll(f.file, wait);
> +
> fdput(f);
> if ((mask & POLLIN_SET) && (in & bit)) {
> res_in |= bit;
> @@ -819,13 +815,10 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
>
> /* userland u16 ->events contains POLL... bitmap */
> filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
> - mask = DEFAULT_POLLMASK;
> - if (f.file->f_op->poll) {
> - pwait->_key = filter | busy_flag;
> - mask = f.file->f_op->poll(f.file, pwait);
> - if (mask & busy_flag)
> - *can_busy_poll = true;
> - }
> + pwait->_key = filter | busy_flag;
> + mask = vfs_poll(f.file, pwait);
> + if (mask & busy_flag)
> + *can_busy_poll = true;
> mask &= filter; /* Mask out unneeded events. */
> fdput(f);
>
> diff --git a/include/linux/poll.h b/include/linux/poll.h
> index a3576da63377..7e0fdcf905d2 100644
> --- a/include/linux/poll.h
> +++ b/include/linux/poll.h
> @@ -74,6 +74,18 @@ static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
> pt->_key = ~(__poll_t)0; /* all events enabled */
> }
>
> +static inline bool file_can_poll(struct file *file)
> +{
> + return file->f_op->poll;
> +}
> +
> +static inline __poll_t vfs_poll(struct file *file, struct poll_table_struct *pt)
> +{
> + if (unlikely(!file->f_op->poll))
> + return DEFAULT_POLLMASK;
> + return file->f_op->poll(file, pt);
> +}
> +
> struct poll_table_entry {
> struct file *filp;
> __poll_t key;
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 670e99b68aa6..8774ece5c3c3 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -3849,7 +3849,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
> if (ret)
> goto out_put_css;
>
> - efile.file->f_op->poll(efile.file, &event->pt);
> + vfs_poll(efile.file, &event->pt);
>
> spin_lock(&memcg->event_list_lock);
> list_add(&event->list, &memcg->event_list);
> diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
> index 0cfba919d167..3811775692d0 100644
> --- a/net/9p/trans_fd.c
> +++ b/net/9p/trans_fd.c
> @@ -231,7 +231,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
> static __poll_t
> p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
> {
> - __poll_t ret, n;
> + __poll_t ret;
> struct p9_trans_fd *ts = NULL;
>
> if (client && client->status == Connected)
> @@ -243,19 +243,9 @@ p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
> return EPOLLERR;
> }
>
> - if (!ts->rd->f_op->poll)
> - ret = DEFAULT_POLLMASK;
> - else
> - ret = ts->rd->f_op->poll(ts->rd, pt);
> -
> - if (ts->rd != ts->wr) {
> - if (!ts->wr->f_op->poll)
> - n = DEFAULT_POLLMASK;
> - else
> - n = ts->wr->f_op->poll(ts->wr, pt);
> - ret = (ret & ~EPOLLOUT) | (n & ~EPOLLIN);
> - }
> -
> + ret = vfs_poll(ts->rd, pt);
> + if (ts->rd != ts->wr)
> + ret = (ret & ~EPOLLOUT) | (vfs_poll(ts->wr, pt) & ~EPOLLIN);
> return ret;
> }
>
> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
> index 6e865e8b5b10..90d30fbe95ae 100644
> --- a/virt/kvm/eventfd.c
> +++ b/virt/kvm/eventfd.c
> @@ -397,7 +397,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
> * Check if there was an event already pending on the eventfd
> * before we registered, and trigger it as if we didn't miss it.
> */
> - events = f.file->f_op->poll(f.file, &irqfd->pt);
> + events = vfs_poll(f.file, &irqfd->pt);
>
> if (events & EPOLLIN)
> schedule_work(&irqfd->inject);
> --
> 2.14.2
>
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [bpf-next V2 PATCH 10/15] xdp: rhashtable with allocator ID to pointer mapping
From: Jason Wang @ 2018-03-20 2:26 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: netdev, BjörnTöpel, magnus.karlsson, eugenia,
John Fastabend, Eran Ben Elisha, Saeed Mahameed, galp,
Daniel Borkmann, Alexei Starovoitov, Tariq Toukan
In-Reply-To: <20180319104858.4cba3a6b@redhat.com>
On 2018年03月19日 17:48, Jesper Dangaard Brouer wrote:
> On Fri, 16 Mar 2018 16:45:30 +0800
> Jason Wang <jasowang@redhat.com> wrote:
>
>> On 2018年03月10日 00:07, Jesper Dangaard Brouer wrote:
>>> On Fri, 9 Mar 2018 21:07:36 +0800
>>> Jason Wang <jasowang@redhat.com> wrote:
>>>
>>>>>>> Use the IDA infrastructure for getting a cyclic increasing ID number,
>>>>>>> that is used for keeping track of each registered allocator per
>>>>>>> RX-queue xdp_rxq_info.
>>>>>>>
>>>>>>> Signed-off-by: Jesper Dangaard Brouer<brouer@redhat.com>
>>>>>> A stupid question is, can we manage to unify this ID with NAPI id?
>>>>> Sorry I don't understand the question?
>>>> I mean can we associate page poll pointer to napi_struct, record NAPI id
>>>> in xdp_mem_info and do lookup through NAPI id?
>>> No. The driver can unreg/reg a new XDP memory model,
>> Is there an actual use case for this?
> I believe this is the common use case. When attaching an XDP/bpf prog,
> then the driver usually want to change the RX-ring memory model
> (different performance trade off).
Right, but a single driver should only have one XDP memory model. (Or
you want to all drivers to use this generic allocator?)
> When detaching XDP, then driver
> want to change back to old memory model. During this process, I
> believe, the NAPI-ID remains the same (right?).
Yes, but we can change the allocator pointer in the NAPI struct in this
case too.
Thanks
>
>>> without reloading
>>> the NAPI and generate a new NAPI id.
>>>
^ permalink raw reply
* Re: [PATCH 11/36] fs: update documentation for __poll_t
From: Darrick J. Wong @ 2018-03-20 2:19 UTC (permalink / raw)
To: Christoph Hellwig
Cc: viro, Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180305212743.16664-12-hch@lst.de>
On Mon, Mar 05, 2018 at 01:27:18PM -0800, Christoph Hellwig wrote:
No commit message... "Update documentation to match the headers"?
--D
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> Documentation/filesystems/Locking | 2 +-
> Documentation/filesystems/vfs.txt | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
> index 75d2d57e2c44..220bba28f72b 100644
> --- a/Documentation/filesystems/Locking
> +++ b/Documentation/filesystems/Locking
> @@ -439,7 +439,7 @@ prototypes:
> ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
> ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
> int (*iterate) (struct file *, struct dir_context *);
> - unsigned int (*poll) (struct file *, struct poll_table_struct *);
> + __poll_t (*poll) (struct file *, struct poll_table_struct *);
> long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
> long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
> int (*mmap) (struct file *, struct vm_area_struct *);
> diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
> index 5fd325df59e2..f608180ad59d 100644
> --- a/Documentation/filesystems/vfs.txt
> +++ b/Documentation/filesystems/vfs.txt
> @@ -856,7 +856,7 @@ struct file_operations {
> ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
> ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
> int (*iterate) (struct file *, struct dir_context *);
> - unsigned int (*poll) (struct file *, struct poll_table_struct *);
> + __poll_t (*poll) (struct file *, struct poll_table_struct *);
> long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
> long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
> int (*mmap) (struct file *, struct vm_area_struct *);
> --
> 2.14.2
>
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH 10/36] fs: cleanup do_pollfd
From: Darrick J. Wong @ 2018-03-20 2:14 UTC (permalink / raw)
To: Christoph Hellwig
Cc: viro, Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180305212743.16664-11-hch@lst.de>
On Mon, Mar 05, 2018 at 01:27:17PM -0800, Christoph Hellwig wrote:
> Use straigline code with failure handling gotos instead of a lot
> of nested conditionals.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks ok,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
--D
> ---
> fs/select.c | 48 +++++++++++++++++++++++-------------------------
> 1 file changed, 23 insertions(+), 25 deletions(-)
>
> diff --git a/fs/select.c b/fs/select.c
> index 686de7b3a1db..c6c504a814f9 100644
> --- a/fs/select.c
> +++ b/fs/select.c
> @@ -806,34 +806,32 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
> bool *can_busy_poll,
> __poll_t busy_flag)
> {
> - __poll_t mask;
> - int fd;
> -
> - mask = 0;
> - fd = pollfd->fd;
> - if (fd >= 0) {
> - struct fd f = fdget(fd);
> - mask = EPOLLNVAL;
> - if (f.file) {
> - /* userland u16 ->events contains POLL... bitmap */
> - __poll_t filter = demangle_poll(pollfd->events) |
> - EPOLLERR | EPOLLHUP;
> - mask = DEFAULT_POLLMASK;
> - if (f.file->f_op->poll) {
> - pwait->_key = filter;
> - pwait->_key |= busy_flag;
> - mask = f.file->f_op->poll(f.file, pwait);
> - if (mask & busy_flag)
> - *can_busy_poll = true;
> - }
> - /* Mask out unneeded events. */
> - mask &= filter;
> - fdput(f);
> - }
> + int fd = pollfd->fd;
> + __poll_t mask = 0, filter;
> + struct fd f;
> +
> + if (fd < 0)
> + goto out;
> + mask = EPOLLNVAL;
> + f = fdget(fd);
> + if (!f.file)
> + goto out;
> +
> + /* userland u16 ->events contains POLL... bitmap */
> + filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
> + mask = DEFAULT_POLLMASK;
> + if (f.file->f_op->poll) {
> + pwait->_key = filter | busy_flag;
> + mask = f.file->f_op->poll(f.file, pwait);
> + if (mask & busy_flag)
> + *can_busy_poll = true;
> }
> + mask &= filter; /* Mask out unneeded events. */
> + fdput(f);
> +
> +out:
> /* ... and so does ->revents */
> pollfd->revents = mangle_poll(mask);
> -
> return mask;
> }
>
> --
> 2.14.2
>
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH 09/36] fs: unexport poll_schedule_timeout
From: Darrick J. Wong @ 2018-03-20 2:13 UTC (permalink / raw)
To: Christoph Hellwig
Cc: viro, Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180305212743.16664-10-hch@lst.de>
On Mon, Mar 05, 2018 at 01:27:16PM -0800, Christoph Hellwig wrote:
> No users outside of select.c.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks ok,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
--D
> ---
> fs/select.c | 3 +--
> include/linux/poll.h | 2 --
> 2 files changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/fs/select.c b/fs/select.c
> index b6c36254028a..686de7b3a1db 100644
> --- a/fs/select.c
> +++ b/fs/select.c
> @@ -233,7 +233,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
> add_wait_queue(wait_address, &entry->wait);
> }
>
> -int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
> +static int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
> ktime_t *expires, unsigned long slack)
> {
> int rc = -EINTR;
> @@ -258,7 +258,6 @@ int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
>
> return rc;
> }
> -EXPORT_SYMBOL(poll_schedule_timeout);
>
> /**
> * poll_select_set_timeout - helper function to setup the timeout value
> diff --git a/include/linux/poll.h b/include/linux/poll.h
> index f45ebd017eaa..a3576da63377 100644
> --- a/include/linux/poll.h
> +++ b/include/linux/poll.h
> @@ -96,8 +96,6 @@ struct poll_wqueues {
>
> extern void poll_initwait(struct poll_wqueues *pwq);
> extern void poll_freewait(struct poll_wqueues *pwq);
> -extern int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
> - ktime_t *expires, unsigned long slack);
> extern u64 select_estimate_accuracy(struct timespec64 *tv);
>
> #define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1)
> --
> 2.14.2
>
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH 08/36] aio: implement io_pgetevents
From: Darrick J. Wong @ 2018-03-20 2:12 UTC (permalink / raw)
To: Christoph Hellwig
Cc: viro, Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180305212743.16664-9-hch@lst.de>
On Mon, Mar 05, 2018 at 01:27:15PM -0800, Christoph Hellwig wrote:
> This is the io_getevents equivalent of ppoll/pselect and allows to
> properly mix signals and aio completions (especially with IOCB_CMD_POLL)
> and atomically executes the following sequence:
>
> sigset_t origmask;
>
> pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
> ret = io_getevents(ctx, min_nr, nr, events, timeout);
> pthread_sigmask(SIG_SETMASK, &origmask, NULL);
>
> Note that unlike many other signal related calls we do not pass a sigmask
> size, as that would get us to 7 arguments, which aren't easily supported
> by the syscall infrastructure. It seems a lot less painful to just add a
> new syscall variant in the unlikely case we're going to increase the
> sigset size.
I'm assuming there's a proposed manpage update for this somewhere? :)
--D
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/x86/entry/syscalls/syscall_32.tbl | 1 +
> arch/x86/entry/syscalls/syscall_64.tbl | 1 +
> fs/aio.c | 114 ++++++++++++++++++++++++++++++---
> include/linux/compat.h | 7 ++
> include/linux/syscalls.h | 6 ++
> include/uapi/asm-generic/unistd.h | 4 +-
> include/uapi/linux/aio_abi.h | 6 ++
> kernel/sys_ni.c | 2 +
> 8 files changed, 130 insertions(+), 11 deletions(-)
>
> diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
> index 448ac2161112..5997c3e9ac3e 100644
> --- a/arch/x86/entry/syscalls/syscall_32.tbl
> +++ b/arch/x86/entry/syscalls/syscall_32.tbl
> @@ -391,3 +391,4 @@
> 382 i386 pkey_free sys_pkey_free
> 383 i386 statx sys_statx
> 384 i386 arch_prctl sys_arch_prctl compat_sys_arch_prctl
> +385 i386 io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents
> diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
> index 5aef183e2f85..e995cd2b4e65 100644
> --- a/arch/x86/entry/syscalls/syscall_64.tbl
> +++ b/arch/x86/entry/syscalls/syscall_64.tbl
> @@ -339,6 +339,7 @@
> 330 common pkey_alloc sys_pkey_alloc
> 331 common pkey_free sys_pkey_free
> 332 common statx sys_statx
> +333 common io_pgetevents sys_io_pgetevents
>
> #
> # x32-specific system call numbers start at 512 to avoid cache impact
> diff --git a/fs/aio.c b/fs/aio.c
> index 9d7d6e4cde87..da87cbf7c67a 100644
> --- a/fs/aio.c
> +++ b/fs/aio.c
> @@ -1291,10 +1291,6 @@ static long read_events(struct kioctx *ctx, long min_nr, long nr,
> wait_event_interruptible_hrtimeout(ctx->wait,
> aio_read_events(ctx, min_nr, nr, event, &ret),
> until);
> -
> - if (!ret && signal_pending(current))
> - ret = -EINTR;
> -
> return ret;
> }
>
> @@ -1874,13 +1870,60 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
> struct timespec __user *, timeout)
> {
> struct timespec64 ts;
> + int ret;
> +
> + if (timeout && unlikely(get_timespec64(&ts, timeout)))
> + return -EFAULT;
> +
> + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
> + if (!ret && signal_pending(current))
> + ret = -EINTR;
> + return ret;
> +}
> +
> +SYSCALL_DEFINE6(io_pgetevents,
> + aio_context_t, ctx_id,
> + long, min_nr,
> + long, nr,
> + struct io_event __user *, events,
> + struct timespec __user *, timeout,
> + const struct __aio_sigset __user *, usig)
> +{
> + struct __aio_sigset ksig = { NULL, };
> + sigset_t ksigmask, sigsaved;
> + struct timespec64 ts;
> + int ret;
> +
> + if (timeout && unlikely(get_timespec64(&ts, timeout)))
> + return -EFAULT;
>
> - if (timeout) {
> - if (unlikely(get_timespec64(&ts, timeout)))
> + if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
> + return -EFAULT;
> +
> + if (ksig.sigmask) {
> + if (ksig.sigsetsize != sizeof(sigset_t))
> + return -EINVAL;
> + if (copy_from_user(&ksigmask, ksig.sigmask, sizeof(ksigmask)))
> return -EFAULT;
> + sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
> + sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
> + }
> +
> + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
> + if (signal_pending(current)) {
> + if (ksig.sigmask) {
> + current->saved_sigmask = sigsaved;
> + set_restore_sigmask();
> + }
> +
> + if (!ret)
> + ret = -ERESTARTNOHAND;
> + } else {
> + if (ksig.sigmask)
> + sigprocmask(SIG_SETMASK, &sigsaved, NULL);
> }
>
> - return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
> + return ret;
> }
>
> #ifdef CONFIG_COMPAT
> @@ -1891,13 +1934,64 @@ COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
> struct compat_timespec __user *, timeout)
> {
> struct timespec64 t;
> + int ret;
> +
> + if (timeout && compat_get_timespec64(&t, timeout))
> + return -EFAULT;
> +
> + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
> + if (!ret && signal_pending(current))
> + ret = -EINTR;
> + return ret;
> +}
> +
> +
> +struct __compat_aio_sigset {
> + compat_sigset_t __user *sigmask;
> + compat_size_t sigsetsize;
> +};
> +
> +COMPAT_SYSCALL_DEFINE6(io_pgetevents,
> + compat_aio_context_t, ctx_id,
> + compat_long_t, min_nr,
> + compat_long_t, nr,
> + struct io_event __user *, events,
> + struct compat_timespec __user *, timeout,
> + const struct __compat_aio_sigset __user *, usig)
> +{
> + struct __compat_aio_sigset ksig = { NULL, };
> + sigset_t ksigmask, sigsaved;
> + struct timespec64 t;
> + int ret;
> +
> + if (timeout && compat_get_timespec64(&t, timeout))
> + return -EFAULT;
>
> - if (timeout) {
> - if (compat_get_timespec64(&t, timeout))
> + if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
> + return -EFAULT;
> +
> + if (ksig.sigmask) {
> + if (ksig.sigsetsize != sizeof(compat_sigset_t))
> + return -EINVAL;
> + if (get_compat_sigset(&ksigmask, ksig.sigmask))
> return -EFAULT;
> + sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
> + sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
> + }
>
> + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
> + if (signal_pending(current)) {
> + if (ksig.sigmask) {
> + current->saved_sigmask = sigsaved;
> + set_restore_sigmask();
> + }
> + if (!ret)
> + ret = -ERESTARTNOHAND;
> + } else {
> + if (ksig.sigmask)
> + sigprocmask(SIG_SETMASK, &sigsaved, NULL);
> }
>
> - return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
> + return ret;
> }
> #endif
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index 8a9643857c4a..bfb8a94fbabd 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -303,6 +303,7 @@ extern int put_compat_rusage(const struct rusage *,
> struct compat_rusage __user *);
>
> struct compat_siginfo;
> +struct __compat_aio_sigset;
>
> extern asmlinkage long compat_sys_waitid(int, compat_pid_t,
> struct compat_siginfo __user *, int,
> @@ -634,6 +635,12 @@ asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
> compat_long_t nr,
> struct io_event __user *events,
> struct compat_timespec __user *timeout);
> +asmlinkage long compat_sys_io_pgetevents(compat_aio_context_t ctx_id,
> + compat_long_t min_nr,
> + compat_long_t nr,
> + struct io_event __user *events,
> + struct compat_timespec __user *timeout,
> + const struct __compat_aio_sigset __user *usig);
> asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
> u32 __user *iocb);
> asmlinkage long compat_sys_mount(const char __user *dev_name,
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index a78186d826d7..8515ec53c81b 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -539,6 +539,12 @@ asmlinkage long sys_io_getevents(aio_context_t ctx_id,
> long nr,
> struct io_event __user *events,
> struct timespec __user *timeout);
> +asmlinkage long sys_io_pgetevents(aio_context_t ctx_id,
> + long min_nr,
> + long nr,
> + struct io_event __user *events,
> + struct timespec __user *timeout,
> + const struct __aio_sigset *sig);
> asmlinkage long sys_io_submit(aio_context_t, long,
> struct iocb __user * __user *);
> asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
> diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
> index 8b87de067bc7..ce2ebbeece10 100644
> --- a/include/uapi/asm-generic/unistd.h
> +++ b/include/uapi/asm-generic/unistd.h
> @@ -732,9 +732,11 @@ __SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
> __SYSCALL(__NR_pkey_free, sys_pkey_free)
> #define __NR_statx 291
> __SYSCALL(__NR_statx, sys_statx)
> +#define __NR_io_pgetevents 292
> +__SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents)
>
> #undef __NR_syscalls
> -#define __NR_syscalls 292
> +#define __NR_syscalls 293
>
> /*
> * All syscalls below here should go away really,
> diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h
> index a04adbc70ddf..2c0a3415beee 100644
> --- a/include/uapi/linux/aio_abi.h
> +++ b/include/uapi/linux/aio_abi.h
> @@ -29,6 +29,7 @@
>
> #include <linux/types.h>
> #include <linux/fs.h>
> +#include <linux/signal.h>
> #include <asm/byteorder.h>
>
> typedef __kernel_ulong_t aio_context_t;
> @@ -108,5 +109,10 @@ struct iocb {
> #undef IFBIG
> #undef IFLITTLE
>
> +struct __aio_sigset {
> + sigset_t __user *sigmask;
> + size_t sigsetsize;
> +};
> +
> #endif /* __LINUX__AIO_ABI_H */
>
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index b5189762d275..8f7705559b38 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -151,9 +151,11 @@ cond_syscall(sys_io_destroy);
> cond_syscall(sys_io_submit);
> cond_syscall(sys_io_cancel);
> cond_syscall(sys_io_getevents);
> +cond_syscall(sys_io_pgetevents);
> cond_syscall(compat_sys_io_setup);
> cond_syscall(compat_sys_io_submit);
> cond_syscall(compat_sys_io_getevents);
> +cond_syscall(compat_sys_io_pgetevents);
> cond_syscall(sys_sysfs);
> cond_syscall(sys_syslog);
> cond_syscall(sys_process_vm_readv);
> --
> 2.14.2
>
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH bpf] bpf: fix crash due to inode i_op mismatch with clang/llvm
From: Linus Torvalds @ 2018-03-20 2:06 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Alexei Starovoitov, psodagud, fengc, Network Development
In-Reply-To: <CA+55aFyjU4nLn4jykr1aYH7X7u-FruZjOLZ+OJnH_1RbfEimAQ@mail.gmail.com>
On Mon, Mar 19, 2018 at 6:50 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> Add it to everything. If it's an invalid optimization, it shouldn't be on.
IOW, why isn't this just something like
diff --git a/Makefile b/Makefile
index d65e2e229017..01abedc2e79f 100644
--- a/Makefile
+++ b/Makefile
@@ -826,6 +826,9 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
# disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
+# disable invalid optimization on clang
+KBUILD_CFLAGS += $(call cc-option,-fno-merge-all-constants)
+
# Make sure -fstack-check isn't enabled (like gentoo apparently did)
KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,)
(whitespace-damaged, but you get the gist of it).
We disable some optimizations that are technically _valid_, because
they are too dangerous and a bad idea.
Disabling an optimization that isn't valid EVEN IN THEORY is an
absolute no-brainer, particularly if it has already shown itself to
cause problems.
We have other situations where we generate multiple static structures
and expect them to be unique. I'm not sure any of them would trigger
the clang rules, but the clang rules are obviously complete garbage
anyway, so who knows?
That optimization seems to teuly be pure and utter garbage. Clang can
even *see* the address comparison happening in that file.
Some clang person needs to be publicly shamed for enabling this kind
of garbage by default, particularly since they apparently _knew_ it
was invalid.
Linus
^ permalink raw reply
* Re: [PATCH bpf] bpf: fix crash due to inode i_op mismatch with clang/llvm
From: Linus Torvalds @ 2018-03-20 1:50 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Alexei Starovoitov, psodagud, fengc, Network Development
In-Reply-To: <20180320011706.31793-1-daniel@iogearbox.net>
On Mon, Mar 19, 2018 at 6:17 PM, Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> Reason for this miscompilation is that clang has the more aggressive
> -fmerge-all-constants enabled by default. In fact, clang source code
> has an 'insightful' comment about it in its source code under
> lib/AST/ExprConstant.cpp:
>
> // Pointers with different bases cannot represent the same object.
> // (Note that clang defaults to -fmerge-all-constants, which can
> // lead to inconsistent results for comparisons involving the address
> // of a constant; this generally doesn't matter in practice.)
>
> gcc on the other hand does not enable -fmerge-all-constants by default
> and *explicitly* states in it's option description that using this
> flag results in non-conforming behavior, quote from man gcc:
>
> Languages like C or C++ require each variable, including multiple
> instances of the same variable in recursive calls, to have distinct
> locations, so using this option results in non-conforming behavior.
>
> Given there are users with clang/LLVM out there today that triggered
> this, fix this mess by explicitly adding -fno-merge-all-constants to
> inode.o as CFLAGS via Kbuild system.
Oh, please do *NOT* add it to just that one file.
Add it to everything. If it's an invalid optimization, it shouldn't be on.
And even if it happens to trigger in only that one file, then
disabling it globally is just the safe thing to do.
What is the code generation difference if you just enable it globally?
I would certainly _hope_ that it's not noticeable, but if it's
noticeable that would certainly imply that it's very dangerous
somewhere else too!
Linus
^ permalink raw reply
* [PATCH v2 3/3] net: phy: micrel: Use the general dummy stubs for MMD register access
From: Kevin Hao @ 2018-03-20 1:44 UTC (permalink / raw)
To: netdev; +Cc: Andrew Lunn, Florian Fainelli, Claudiu Manoil, Kevin Hao
In-Reply-To: <20180320014454.12697-1-haokexin@gmail.com>
The new general dummy stubs for MMD register access were introduced.
Use that for the codes reuse.
Signed-off-by: Kevin Hao <haokexin@gmail.com>
---
drivers/net/phy/micrel.c | 23 ++---------------------
1 file changed, 2 insertions(+), 21 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 49be85afbea9..f41b224a9cdb 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -635,25 +635,6 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev)
return 0;
}
-/* This routine returns -1 as an indication to the caller that the
- * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE
- * MMD extended PHY registers.
- */
-static int
-ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum)
-{
- return -1;
-}
-
-/* This routine does nothing since the Micrel ksz9021 does not support
- * standard IEEE MMD extended PHY registers.
- */
-static int
-ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum, u16 val)
-{
- return -1;
-}
-
static int kszphy_get_sset_count(struct phy_device *phydev)
{
return ARRAY_SIZE(kszphy_hw_stats);
@@ -946,8 +927,8 @@ static struct phy_driver ksphy_driver[] = {
.get_stats = kszphy_get_stats,
.suspend = genphy_suspend,
.resume = genphy_resume,
- .read_mmd = ksz9021_rd_mmd_phyreg,
- .write_mmd = ksz9021_wr_mmd_phyreg,
+ .read_mmd = genphy_read_mmd_unsupported,
+ .write_mmd = genphy_write_mmd_unsupported,
}, {
.phy_id = PHY_ID_KSZ9031,
.phy_id_mask = MICREL_PHY_ID_MASK,
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox