[RFC PATCH 20/30] tg3: Prepare tg3_full_[un]lock() for handling softirq mask

From: Frederic Weisbecker
Date: Wed Oct 10 2018 - 19:13:38 EST


This pair of function is implemented on top of spin_[un]lock_bh() that
is going to handle a softirq mask in order to apply finegrained vector
disablement. The lock function is going to return the previous vectors
enabled mask prior to the last call to local_bh_disable(), following a
similar model to that of local_irq_save/restore. Subsequent calls to
local_bh_disable() and friends can then stack up:

bh = local_bh_disable(vec_mask);
bh2 = tg3_full_lock(...) {
return spin_lock_bh(...)
}
...
tg3_full_unlock(..., bh2) {
spin_unlock_bh(bh2, ...);
}
local_bh_enable(bh);

To prepare for that, make tg3_full_lock() able to return a saved vector
enabled mask and pass it back to tg3_full_unlock(). We'll plug it to
spin_lock_bh() in a subsequent patch.

Signed-off-by: Frederic Weisbecker <frederic@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: David S. Miller <davem@xxxxxxxxxxxxx>
Cc: Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxxxxx>
Cc: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/broadcom/tg3.c | 160 +++++++++++++++++++++---------------
1 file changed, 95 insertions(+), 65 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index e6f28c7..765185c 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6156,8 +6156,8 @@ static void tg3_refclk_write(struct tg3 *tp, u64 newval)
tw32_f(TG3_EAV_REF_CLCK_CTL, clock_ctl | TG3_EAV_REF_CLCK_CTL_RESUME);
}

-static inline void tg3_full_lock(struct tg3 *tp, int irq_sync);
-static inline void tg3_full_unlock(struct tg3 *tp);
+static inline unsigned int tg3_full_lock(struct tg3 *tp, int irq_sync);
+static inline void tg3_full_unlock(struct tg3 *tp, unsigned int bh);
static int tg3_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
{
struct tg3 *tp = netdev_priv(dev);
@@ -6189,6 +6189,7 @@ static int tg3_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
{
struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
+ unsigned int bh;
bool neg_adj = false;
u32 correction = 0;

@@ -6208,7 +6209,7 @@ static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
correction = div_u64((u64)ppb * (1 << 24), 1000000000ULL) &
TG3_EAV_REF_CLK_CORRECT_MASK;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

if (correction)
tw32(TG3_EAV_REF_CLK_CORRECT_CTL,
@@ -6217,7 +6218,7 @@ static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
else
tw32(TG3_EAV_REF_CLK_CORRECT_CTL, 0);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

return 0;
}
@@ -6225,10 +6226,11 @@ static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int tg3_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
+ unsigned int bh;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tp->ptp_adjust += delta;
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

return 0;
}
@@ -6236,12 +6238,13 @@ static int tg3_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
u64 ns;
+ unsigned int bh;
struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
ns = tg3_refclk_read(tp);
ns += tp->ptp_adjust;
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

*ts = ns_to_timespec64(ns);

@@ -6253,13 +6256,14 @@ static int tg3_ptp_settime(struct ptp_clock_info *ptp,
{
u64 ns;
struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
+ unsigned int bh;

ns = timespec64_to_ns(ts);

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_refclk_write(tp, ns);
tp->ptp_adjust = 0;
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

return 0;
}
@@ -6268,6 +6272,7 @@ static int tg3_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
+ unsigned int bh;
u32 clock_ctl;
int rval = 0;

@@ -6276,7 +6281,7 @@ static int tg3_ptp_enable(struct ptp_clock_info *ptp,
if (rq->perout.index != 0)
return -EINVAL;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
clock_ctl = tr32(TG3_EAV_REF_CLCK_CTL);
clock_ctl &= ~TG3_EAV_CTL_TSYNC_GPIO_MASK;

@@ -6313,7 +6318,7 @@ static int tg3_ptp_enable(struct ptp_clock_info *ptp,
}

err_out:
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
return rval;

default:
@@ -7428,7 +7433,7 @@ static inline void tg3_netif_start(struct tg3 *tp)
tg3_enable_ints(tp);
}

-static void tg3_irq_quiesce(struct tg3 *tp)
+static unsigned int tg3_irq_quiesce(struct tg3 *tp, unsigned int bh)
__releases(tp->lock)
__acquires(tp->lock)
{
@@ -7445,6 +7450,8 @@ static void tg3_irq_quiesce(struct tg3 *tp)
synchronize_irq(tp->napi[i].irq_vec);

spin_lock_bh(&tp->lock);
+
+ return 0;
}

/* Fully shutdown all tg3 driver activity elsewhere in the system.
@@ -7452,14 +7459,18 @@ static void tg3_irq_quiesce(struct tg3 *tp)
* with as well. Most of the time, this is not necessary except when
* shutting down the device.
*/
-static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
+static inline unsigned int tg3_full_lock(struct tg3 *tp, int irq_sync)
{
+ unsigned int bh = 0;
+
spin_lock_bh(&tp->lock);
if (irq_sync)
- tg3_irq_quiesce(tp);
+ bh = tg3_irq_quiesce(tp, bh);
+
+ return bh;
}

-static inline void tg3_full_unlock(struct tg3 *tp)
+static inline void tg3_full_unlock(struct tg3 *tp, unsigned int bh)
{
spin_unlock_bh(&tp->lock);
}
@@ -11184,10 +11195,11 @@ static int tg3_restart_hw(struct tg3 *tp, bool reset_phy)
static void tg3_reset_task(struct work_struct *work)
{
struct tg3 *tp = container_of(work, struct tg3, reset_task);
+ unsigned int bh;
int err;

rtnl_lock();
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

if (!netif_running(tp->dev)) {
tg3_flag_clear(tp, RESET_TASK_PENDING);
@@ -11219,7 +11231,7 @@ static void tg3_reset_task(struct work_struct *work)
tg3_netif_start(tp);

out:
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (!err)
tg3_phy_start(tp);
@@ -11350,6 +11362,7 @@ static int tg3_test_msi(struct tg3 *tp)
{
int err;
u16 pci_cmd;
+ unsigned int bh;

if (!tg3_flag(tp, USING_MSI))
return 0;
@@ -11391,12 +11404,12 @@ static int tg3_test_msi(struct tg3 *tp)
/* Need to reset the chip because the MSI cycle may have terminated
* with Master Abort.
*/
- tg3_full_lock(tp, 1);
+ bh = tg3_full_lock(tp, 1);

tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
err = tg3_init_hw(tp, true);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (err)
free_irq(tp->napi[0].irq_vec, &tp->napi[0]);
@@ -11565,6 +11578,7 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
bool init)
{
struct net_device *dev = tp->dev;
+ unsigned int bh;
int i, err;

/*
@@ -11598,7 +11612,7 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
}
}

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

if (init)
tg3_ape_driver_state_change(tp, RESET_KIND_INIT);
@@ -11609,7 +11623,7 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
tg3_free_rings(tp);
}

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (err)
goto out_free_irq;
@@ -11618,10 +11632,10 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
err = tg3_test_msi(tp);

if (err) {
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_free_rings(tp);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

goto out_napi_fini;
}
@@ -11638,7 +11652,7 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,

tg3_hwmon_open(tp);

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tg3_timer_start(tp);
tg3_flag_set(tp, INIT_COMPLETE);
@@ -11646,7 +11660,7 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,

tg3_ptp_resume(tp);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

netif_tx_start_all_queues(dev);

@@ -11679,6 +11693,7 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
static void tg3_stop(struct tg3 *tp)
{
int i;
+ unsigned int bh;

tg3_reset_task_cancel(tp);
tg3_netif_stop(tp);
@@ -11689,7 +11704,7 @@ static void tg3_stop(struct tg3 *tp)

tg3_phy_stop(tp);

- tg3_full_lock(tp, 1);
+ bh = tg3_full_lock(tp, 1);

tg3_disable_ints(tp);

@@ -11697,7 +11712,7 @@ static void tg3_stop(struct tg3 *tp)
tg3_free_rings(tp);
tg3_flag_clear(tp, INIT_COMPLETE);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

for (i = tp->irq_cnt - 1; i >= 0; i--) {
struct tg3_napi *tnapi = &tp->napi[i];
@@ -11714,6 +11729,7 @@ static void tg3_stop(struct tg3 *tp)
static int tg3_open(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
int err;

if (tp->pcierr_recovery) {
@@ -11750,12 +11766,12 @@ static int tg3_open(struct net_device *dev)
if (err)
return err;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tg3_disable_ints(tp);
tg3_flag_clear(tp, INIT_COMPLETE);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

err = tg3_start(tp,
!(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN),
@@ -11968,6 +11984,7 @@ static void tg3_get_regs(struct net_device *dev,
struct ethtool_regs *regs, void *_p)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;

regs->version = 0;

@@ -11976,11 +11993,11 @@ static void tg3_get_regs(struct net_device *dev,
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
return;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tg3_dump_legacy_regs(tp, (u32 *)_p);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
}

static int tg3_get_eeprom_len(struct net_device *dev)
@@ -12217,6 +12234,7 @@ static int tg3_set_link_ksettings(struct net_device *dev,
{
struct tg3 *tp = netdev_priv(dev);
u32 speed = cmd->base.speed;
+ unsigned int bh;
u32 advertising;

if (tg3_flag(tp, USE_PHYLIB)) {
@@ -12282,7 +12300,7 @@ static int tg3_set_link_ksettings(struct net_device *dev,
}
}

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tp->link_config.autoneg = cmd->base.autoneg;
if (cmd->base.autoneg == AUTONEG_ENABLE) {
@@ -12303,7 +12321,7 @@ static int tg3_set_link_ksettings(struct net_device *dev,
if (netif_running(dev))
tg3_setup_phy(tp, true);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

return 0;
}
@@ -12490,6 +12508,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
int err = 0;

if (tp->link_config.autoneg == AUTONEG_ENABLE)
@@ -12564,7 +12583,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
irq_sync = 1;
}

- tg3_full_lock(tp, irq_sync);
+ bh = tg3_full_lock(tp, irq_sync);

if (epause->autoneg)
tg3_flag_set(tp, PAUSE_AUTONEG);
@@ -12586,7 +12605,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
tg3_netif_start(tp);
}

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
}

tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED;
@@ -12662,6 +12681,7 @@ static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key,
const u8 hfunc)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
size_t i;

/* We require at least one supported parameter to be changed and no
@@ -12683,9 +12703,9 @@ static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key,
/* It is legal to write the indirection
* table while the device is running.
*/
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_rss_write_indir_tbl(tp);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, 0);

return 0;
}
@@ -13762,6 +13782,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
u64 *data)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
bool doextlpbk = etest->flags & ETH_TEST_FL_EXTERNAL_LB;

if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
@@ -13792,7 +13813,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
irq_sync = 1;
}

- tg3_full_lock(tp, irq_sync);
+ bh = tg3_full_lock(tp, irq_sync);
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
err = tg3_nvram_lock(tp);
tg3_halt_cpu(tp, RX_CPU_BASE);
@@ -13820,14 +13841,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
if (tg3_test_loopback(tp, data, doextlpbk))
etest->flags |= ETH_TEST_FL_FAILED;

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (tg3_test_interrupt(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED;
data[TG3_INTERRUPT_TEST] = 1;
}

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
@@ -13837,7 +13858,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_netif_start(tp);
}

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (irq_sync && !err2)
tg3_phy_start(tp);
@@ -14071,6 +14092,7 @@ static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0;
u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0;

@@ -14107,9 +14129,9 @@ static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs;

if (netif_running(dev)) {
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
__tg3_set_coalesce(tp, &tp->coal);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
}
return 0;
}
@@ -14117,6 +14139,7 @@ static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
static int tg3_set_eee(struct net_device *dev, struct ethtool_eee *edata)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;

if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) {
netdev_warn(tp->dev, "Board does not support EEE!\n");
@@ -14142,10 +14165,10 @@ static int tg3_set_eee(struct net_device *dev, struct ethtool_eee *edata)
tg3_warn_mgmt_link_flap(tp);

if (netif_running(tp->dev)) {
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_setup_eee(tp);
tg3_phy_reset(tp);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
}

return 0;
@@ -14221,13 +14244,14 @@ static void tg3_get_stats64(struct net_device *dev,
static void tg3_set_rx_mode(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;

if (!netif_running(dev))
return;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
__tg3_set_rx_mode(dev);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
}

static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
@@ -14256,6 +14280,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
struct tg3 *tp = netdev_priv(dev);
int err;
bool reset_phy = false;
+ unsigned int bh;

if (!netif_running(dev)) {
/* We'll just catch it later when the
@@ -14271,7 +14296,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)

tg3_set_mtu(dev, tp, new_mtu);

- tg3_full_lock(tp, 1);
+ bh = tg3_full_lock(tp, 1);

tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);

@@ -14289,7 +14314,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
if (!err)
tg3_netif_start(tp);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (!err)
tg3_phy_start(tp);
@@ -17663,6 +17688,7 @@ static int tg3_init_one(struct pci_dev *pdev,
char str[40];
u64 dma_mask, persist_dma_mask;
netdev_features_t features = 0;
+ unsigned int bh;

printk_once(KERN_INFO "%s\n", version);

@@ -17945,10 +17971,10 @@ static int tg3_init_one(struct pci_dev *pdev,
*/
if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
}

err = tg3_test_dma(tp);
@@ -18085,6 +18111,7 @@ static int tg3_suspend(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
int err = 0;

rtnl_lock();
@@ -18098,22 +18125,22 @@ static int tg3_suspend(struct device *device)

tg3_timer_stop(tp);

- tg3_full_lock(tp, 1);
+ bh= tg3_full_lock(tp, 1);
tg3_disable_ints(tp);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

netif_device_detach(dev);

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_flag_clear(tp, INIT_COMPLETE);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

err = tg3_power_down_prepare(tp);
if (err) {
int err2;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tg3_flag_set(tp, INIT_COMPLETE);
err2 = tg3_restart_hw(tp, true);
@@ -18126,7 +18153,7 @@ static int tg3_suspend(struct device *device)
tg3_netif_start(tp);

out:
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (!err2)
tg3_phy_start(tp);
@@ -18142,6 +18169,7 @@ static int tg3_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(dev);
+ unsigned int bh;
int err = 0;

rtnl_lock();
@@ -18151,7 +18179,7 @@ static int tg3_resume(struct device *device)

netif_device_attach(dev);

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);

tg3_ape_driver_state_change(tp, RESET_KIND_INIT);

@@ -18166,7 +18194,7 @@ static int tg3_resume(struct device *device)
tg3_netif_start(tp);

out:
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

if (!err)
tg3_phy_start(tp);
@@ -18210,6 +18238,7 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
struct net_device *netdev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(netdev);
pci_ers_result_t err = PCI_ERS_RESULT_NEED_RESET;
+ unsigned int bh;

netdev_info(netdev, "PCI I/O error detected\n");

@@ -18235,9 +18264,9 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
netif_device_detach(netdev);

/* Clean up software state, even if MMIO is blocked */
- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

done:
if (state == pci_channel_io_perm_failure) {
@@ -18315,6 +18344,7 @@ static void tg3_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(netdev);
+ unsigned int bh;
int err;

rtnl_lock();
@@ -18322,12 +18352,12 @@ static void tg3_io_resume(struct pci_dev *pdev)
if (!netdev || !netif_running(netdev))
goto done;

- tg3_full_lock(tp, 0);
+ bh = tg3_full_lock(tp, 0);
tg3_ape_driver_state_change(tp, RESET_KIND_INIT);
tg3_flag_set(tp, INIT_COMPLETE);
err = tg3_restart_hw(tp, true);
if (err) {
- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);
netdev_err(netdev, "Cannot restart hardware after reset.\n");
goto done;
}
@@ -18338,7 +18368,7 @@ static void tg3_io_resume(struct pci_dev *pdev)

tg3_netif_start(tp);

- tg3_full_unlock(tp);
+ tg3_full_unlock(tp, bh);

tg3_phy_start(tp);

--
2.7.4