diff options
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 20 |
1 files changed, 4 insertions, 16 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 02872405d35d..5d79f5e529e0 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -1495,11 +1495,13 @@ void bond_alb_monitor(struct work_struct *work) | |||
1495 | struct list_head *iter; | 1495 | struct list_head *iter; |
1496 | struct slave *slave; | 1496 | struct slave *slave; |
1497 | 1497 | ||
1498 | read_lock(&bond->lock); | 1498 | if (!rtnl_trylock()) |
1499 | goto re_arm; | ||
1499 | 1500 | ||
1500 | if (!bond_has_slaves(bond)) { | 1501 | if (!bond_has_slaves(bond)) { |
1501 | bond_info->tx_rebalance_counter = 0; | 1502 | bond_info->tx_rebalance_counter = 0; |
1502 | bond_info->lp_counter = 0; | 1503 | bond_info->lp_counter = 0; |
1504 | rtnl_unlock(); | ||
1503 | goto re_arm; | 1505 | goto re_arm; |
1504 | } | 1506 | } |
1505 | 1507 | ||
@@ -1548,16 +1550,6 @@ void bond_alb_monitor(struct work_struct *work) | |||
1548 | if (bond_info->primary_is_promisc && | 1550 | if (bond_info->primary_is_promisc && |
1549 | (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) { | 1551 | (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) { |
1550 | 1552 | ||
1551 | /* | ||
1552 | * dev_set_promiscuity requires rtnl and | ||
1553 | * nothing else. Avoid race with bond_close. | ||
1554 | */ | ||
1555 | read_unlock(&bond->lock); | ||
1556 | if (!rtnl_trylock()) { | ||
1557 | read_lock(&bond->lock); | ||
1558 | goto re_arm; | ||
1559 | } | ||
1560 | |||
1561 | bond_info->rlb_promisc_timeout_counter = 0; | 1553 | bond_info->rlb_promisc_timeout_counter = 0; |
1562 | 1554 | ||
1563 | /* If the primary was set to promiscuous mode | 1555 | /* If the primary was set to promiscuous mode |
@@ -1566,9 +1558,6 @@ void bond_alb_monitor(struct work_struct *work) | |||
1566 | */ | 1558 | */ |
1567 | dev_set_promiscuity(bond->curr_active_slave->dev, -1); | 1559 | dev_set_promiscuity(bond->curr_active_slave->dev, -1); |
1568 | bond_info->primary_is_promisc = 0; | 1560 | bond_info->primary_is_promisc = 0; |
1569 | |||
1570 | rtnl_unlock(); | ||
1571 | read_lock(&bond->lock); | ||
1572 | } | 1561 | } |
1573 | 1562 | ||
1574 | if (bond_info->rlb_rebalance) { | 1563 | if (bond_info->rlb_rebalance) { |
@@ -1591,10 +1580,9 @@ void bond_alb_monitor(struct work_struct *work) | |||
1591 | } | 1580 | } |
1592 | } | 1581 | } |
1593 | 1582 | ||
1583 | rtnl_unlock(); | ||
1594 | re_arm: | 1584 | re_arm: |
1595 | queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); | 1585 | queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); |
1596 | |||
1597 | read_unlock(&bond->lock); | ||
1598 | } | 1586 | } |
1599 | 1587 | ||
1600 | /* assumption: called before the slave is attached to the bond | 1588 | /* assumption: called before the slave is attached to the bond |