bonding: couple of bug fixes
Subsystems (3)
v2 cover bonding: couple of bug fixes
From: Nikolay Aleksandrov <[email protected]>
Hello,
Patch 01 resets the master's mac if the first enslave fails and the slave's mac was set to the master's prior.
Patch 02 fixes a type bug of igmp_retrans (which is the counter of igmp_resend param and was silently not working if the value was >127) so it can go up to 255 (as per documentation). It also fixes two tricky race conditions which were hidden because of the previous bug.
V2: Updated patch 02 commit message as per Jay's comment
Best regards,
Nikolay Aleksandrov
Nikolay Aleksandrov (2):
bonding: reset master mac on first enslave failure
bonding: fix igmp_retrans type and two related races
drivers/net/bonding/bond_main.c | 19 +++++++++++++++---- drivers/net/bonding/bonding.h | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-)
Signature · 1 line
1.8.1.4
PATCH v2 1/2 bonding: reset master mac on first enslave failure
From: Nikolay Aleksandrov <[email protected]>
If the bond device is supposed to get the first slave's MAC address and the first enslavement fails then we need to reset the master's MAC otherwise it will stay the same as the failed slave device. We do it after err_undo_flags since that is the first place where the MAC can be changed and we check if it should've been the first slave and if the bond's MAC was set to it because that err place is used by multiple locations prior to changing the master's MAC address.
--- drivers/net/bonding/bond_main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/bonding/bond_main.c +4 -0
@@ -1957,6 +1957,10 @@ err_free: err_undo_flags:bond_compute_features (bond); +/* Enslave of first slave has failed and we need to fix master's mac */ +if (bond->slave_cnt ==0 && +ether_addr_equal (bond_dev->dev_addr, slave_dev->dev_addr)) +eth_hw_addr_random (bond_dev);return res; }
Signature · 1 line
1.8.1.4
PATCH v2 2/2 bonding: fix igmp_retrans type and two related races
In reply to [email protected]From: Nikolay Aleksandrov <[email protected]>
First the type of igmp_retrans (which is the actual counter of igmp_resend parameter) is changed to u8 to be able to store values up to 255 (as per documentation). There are two races that were hidden there and which are easy to trigger after the previous fix, the first is between bond_resend_igmp_join_requests and bond_change_active_slave where igmp_retrans is set and can be altered by the periodic. The second race condition is between multiple running instances of the periodic (upon execution it can be scheduled again for immediate execution which can cause the counter to go < 0 which in the unsigned case leads to unnecessary igmp retransmissions).
Since in bond_change_active_slave bond->lock is held for reading and curr_slave_lock for writing, we use curr_slave_lock for mutual exclusion. We can't drop them as there're cases where RTNL is not held when bond_change_active_slave is called. RCU is unlocked in bond_resend_igmp_join_requests before getting curr_slave_lock since we don't need it there and it's pointless to delay.
The decrement is moved inside the "if" block because if we decrement unconditionally there's still a possibility for a race condition although it is much more difficult to hit (many changes have to happen in a very short period in order to trigger) which in the case of 3 parallel running instances of this function and igmp_retrans == 1 (with check bond->igmp_retrans-- > 1) is:
f1 passes, doesn't re-schedule, but decrements - igmp_retrans = 0 f2 then passes, doesn't re-schedule, but decrements - igmp_retrans = 255 f3 does the unnecessary retransmissions.
---
v2: updated commit message
drivers/net/bonding/bond_main.c | 15 +++++++++++---- drivers/net/bonding/bonding.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-)
drivers/net/bonding/bond_main.c +11 -4
@@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)struct net_device *bond_dev, *vlan_dev, *upper_dev;struct vlan_entry *vlan; -rcu_read_lock ();read_lock (&bond->lock); +rcu_read_lock (); bond_dev = bond->dev;
@@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)if (vlan_dev)__bond_resend_igmp_join_requests (vlan_dev); } +rcu_read_unlock (); -if (--bond->igmp_retrans >0 ) +/* We use curr_slave_lock to protect against concurrent access to +* igmp_retrans from multiple running instances of this function and +* bond_change_active_slave +*/ +write_lock_bh (&bond->curr_slave_lock); +if (bond->igmp_retrans >1 ) { + bond->igmp_retrans--;queue_delayed_work (bond->wq, &bond->mcast_work,HZ /5 ); - + } +write_unlock_bh (&bond->curr_slave_lock);read_unlock (&bond->lock); -rcu_read_unlock (); }static void bond_resend_igmp_join_requests_delayed (struct work_struct *work)
drivers/net/bonding/bonding.h +1 -1
@@ -225,7 +225,7 @@ struct bonding {rwlock_t curr_slave_lock;u8 send_peer_notif;s8 setup_by_slave; -s8 igmp_retrans; +u8 igmp_retrans;#ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry;char proc_file_name[IFNAMSIZ ];
Signature · 1 line
1.8.1.4
Quoted 11 lines · [email protected] wrote:
From: Nikolay Aleksandrov <[email protected]>
Hello,
Patch 01 resets the master's mac if the first enslave fails and the slave's mac was set to the master's prior.
Patch 02 fixes a type bug ofigmp_retrans(which is the counter ofigmp_resendparam and was silently not working if the value was >127) so it can go up to 255 (as per documentation). It also fixes two tricky race conditions which were hidden because of the previous bug.V2: Updated patch 02 commit message as per Jay's comment
For both patches:
-J
---
-Jay Vosburgh, IBM Linux Technology Center, [email protected]
David Miller
maintainerFrom: Jay Vosburgh <[email protected]>
Date: Tue, 11 Jun 2013 15:14:04 -0700
Quoted 12 lines
Quoted 10 lines · [email protected] wrote:
From: Nikolay Aleksandrov <[email protected]>
Hello,
Patch 01 resets the master's mac if the first enslave fails and the slave's mac was set to the master's prior.
Patch 02 fixes a type bug ofigmp_retrans(which is the counter ofigmp_resendparam and was silently not working if the value was >127) so it can go up to 255 (as per documentation). It also fixes two tricky race conditions which were hidden because of the previous bug.
Quoted 5 lines
Quoted 1 line
V2: Updated patch 02 commit message as per Jay's comment
For both patches:
Signed-off-by Jay Vosburgh <[email protected]>
Series applied, thanks.