aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2.c
diff options
context:
space:
mode:
authorIvan Vecera <ivecera@redhat.com>2016-10-18 02:16:03 -0400
committerDavid S. Miller <davem@davemloft.net>2016-10-18 10:01:51 -0400
commit6bc80629eefc3731f5881092bed610d994e05763 (patch)
tree47a8fc55a1b12951ac92df7f658d5babb6cf31a5 /drivers/net/ethernet/broadcom/bnx2.c
parent3dfcb4f56f35663bdf0629d066bfde665b1ddff9 (diff)
bnx2: fix locking when netconsole is used
Functions bnx2_reg_rd_ind(), bnx2_reg_wr_ind() and bnx2_ctx_wr() can be called with IRQs disabled when netconsole is enabled. So they should use spin_{,un}lock_irq{save,restore} instead of _bh variants. Example call flow: bnx2_poll() ->bnx2_poll_link() ->bnx2_phy_int() ->bnx2_set_remote_link() ->bnx2_shmem_rd() ->bnx2_reg_rd_ind() -> spin_lock_bh(&bp->indirect_lock); spin_unlock_bh(&bp->indirect_lock); ... -> __local_bh_enable_ip static inline void __local_bh_enable_ip(unsigned long ip) WARN_ON_ONCE(in_irq() || irqs_disabled()); <<<<<< WARN Cc: Sony Chacko <sony.chacko@qlogic.com> Cc: Dept-HSGLinuxNICDev@qlogic.com Signed-off-by: Ivan Vecera <ivecera@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 27f11a5d5fe2..b3791b394715 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -271,22 +271,25 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
271static u32 271static u32
272bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) 272bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
273{ 273{
274 unsigned long flags;
274 u32 val; 275 u32 val;
275 276
276 spin_lock_bh(&bp->indirect_lock); 277 spin_lock_irqsave(&bp->indirect_lock, flags);
277 BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); 278 BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
278 val = BNX2_RD(bp, BNX2_PCICFG_REG_WINDOW); 279 val = BNX2_RD(bp, BNX2_PCICFG_REG_WINDOW);
279 spin_unlock_bh(&bp->indirect_lock); 280 spin_unlock_irqrestore(&bp->indirect_lock, flags);
280 return val; 281 return val;
281} 282}
282 283
283static void 284static void
284bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val) 285bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
285{ 286{
286 spin_lock_bh(&bp->indirect_lock); 287 unsigned long flags;
288
289 spin_lock_irqsave(&bp->indirect_lock, flags);
287 BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); 290 BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
288 BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, val); 291 BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
289 spin_unlock_bh(&bp->indirect_lock); 292 spin_unlock_irqrestore(&bp->indirect_lock, flags);
290} 293}
291 294
292static void 295static void
@@ -304,8 +307,10 @@ bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
304static void 307static void
305bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) 308bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
306{ 309{
310 unsigned long flags;
311
307 offset += cid_addr; 312 offset += cid_addr;
308 spin_lock_bh(&bp->indirect_lock); 313 spin_lock_irqsave(&bp->indirect_lock, flags);
309 if (BNX2_CHIP(bp) == BNX2_CHIP_5709) { 314 if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
310 int i; 315 int i;
311 316
@@ -322,7 +327,7 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
322 BNX2_WR(bp, BNX2_CTX_DATA_ADR, offset); 327 BNX2_WR(bp, BNX2_CTX_DATA_ADR, offset);
323 BNX2_WR(bp, BNX2_CTX_DATA, val); 328 BNX2_WR(bp, BNX2_CTX_DATA, val);
324 } 329 }
325 spin_unlock_bh(&bp->indirect_lock); 330 spin_unlock_irqrestore(&bp->indirect_lock, flags);
326} 331}
327 332
328#ifdef BCM_CNIC 333#ifdef BCM_CNIC