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>
This commit is contained in:
parent
3dfcb4f56f
commit
6bc80629ee
|
@ -271,22 +271,25 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
|
||||||
static u32
|
static u32
|
||||||
bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
|
bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
spin_lock_bh(&bp->indirect_lock);
|
spin_lock_irqsave(&bp->indirect_lock, flags);
|
||||||
BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
|
BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
|
||||||
val = BNX2_RD(bp, BNX2_PCICFG_REG_WINDOW);
|
val = BNX2_RD(bp, BNX2_PCICFG_REG_WINDOW);
|
||||||
spin_unlock_bh(&bp->indirect_lock);
|
spin_unlock_irqrestore(&bp->indirect_lock, flags);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
|
bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
|
||||||
{
|
{
|
||||||
spin_lock_bh(&bp->indirect_lock);
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&bp->indirect_lock, flags);
|
||||||
BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
|
BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
|
||||||
BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
|
BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
|
||||||
spin_unlock_bh(&bp->indirect_lock);
|
spin_unlock_irqrestore(&bp->indirect_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -304,8 +307,10 @@ bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
|
||||||
static void
|
static void
|
||||||
bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
|
bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
offset += cid_addr;
|
offset += cid_addr;
|
||||||
spin_lock_bh(&bp->indirect_lock);
|
spin_lock_irqsave(&bp->indirect_lock, flags);
|
||||||
if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
|
if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -322,7 +327,7 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
|
||||||
BNX2_WR(bp, BNX2_CTX_DATA_ADR, offset);
|
BNX2_WR(bp, BNX2_CTX_DATA_ADR, offset);
|
||||||
BNX2_WR(bp, BNX2_CTX_DATA, val);
|
BNX2_WR(bp, BNX2_CTX_DATA, val);
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&bp->indirect_lock);
|
spin_unlock_irqrestore(&bp->indirect_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BCM_CNIC
|
#ifdef BCM_CNIC
|
||||||
|
|
Loading…
Reference in New Issue