@@ -1025,12 +1025,38 @@ static void bond_do_fail_over_mac(struct bonding *bond,
10251025
10261026}
10271027
1028+ /**
1029+ * bond_choose_primary_or_current - select the primary or high priority slave
1030+ * @bond: our bonding struct
1031+ *
1032+ * - Check if there is a primary link. If the primary link was set and is up,
1033+ * go on and do link reselection.
1034+ *
1035+ * - If primary link is not set or down, find the highest priority link.
1036+ * If the highest priority link is not current slave, set it as primary
1037+ * link and do link reselection.
1038+ */
10281039static struct slave * bond_choose_primary_or_current (struct bonding * bond )
10291040{
10301041 struct slave * prim = rtnl_dereference (bond -> primary_slave );
10311042 struct slave * curr = rtnl_dereference (bond -> curr_active_slave );
1043+ struct slave * slave , * hprio = NULL ;
1044+ struct list_head * iter ;
10321045
10331046 if (!prim || prim -> link != BOND_LINK_UP ) {
1047+ bond_for_each_slave (bond , slave , iter ) {
1048+ if (slave -> link == BOND_LINK_UP ) {
1049+ hprio = hprio ?: slave ;
1050+ if (slave -> prio > hprio -> prio )
1051+ hprio = slave ;
1052+ }
1053+ }
1054+
1055+ if (hprio && hprio != curr ) {
1056+ prim = hprio ;
1057+ goto link_reselect ;
1058+ }
1059+
10341060 if (!curr || curr -> link != BOND_LINK_UP )
10351061 return NULL ;
10361062 return curr ;
@@ -1041,6 +1067,7 @@ static struct slave *bond_choose_primary_or_current(struct bonding *bond)
10411067 return prim ;
10421068 }
10431069
1070+ link_reselect :
10441071 if (!curr || curr -> link != BOND_LINK_UP )
10451072 return prim ;
10461073
@@ -2626,8 +2653,11 @@ static void bond_miimon_link_change(struct bonding *bond,
26262653
26272654static void bond_miimon_commit (struct bonding * bond )
26282655{
2656+ struct slave * slave , * primary , * active ;
2657+ bool do_failover = false;
26292658 struct list_head * iter ;
2630- struct slave * slave , * primary ;
2659+
2660+ ASSERT_RTNL ();
26312661
26322662 bond_for_each_slave (bond , slave , iter ) {
26332663 switch (slave -> link_new_state ) {
@@ -2671,8 +2701,9 @@ static void bond_miimon_commit(struct bonding *bond)
26712701
26722702 bond_miimon_link_change (bond , slave , BOND_LINK_UP );
26732703
2674- if (!bond -> curr_active_slave || slave == primary )
2675- goto do_failover ;
2704+ active = rtnl_dereference (bond -> curr_active_slave );
2705+ if (!active || slave == primary || slave -> prio > active -> prio )
2706+ do_failover = true;
26762707
26772708 continue ;
26782709
@@ -2693,7 +2724,7 @@ static void bond_miimon_commit(struct bonding *bond)
26932724 bond_miimon_link_change (bond , slave , BOND_LINK_DOWN );
26942725
26952726 if (slave == rcu_access_pointer (bond -> curr_active_slave ))
2696- goto do_failover ;
2727+ do_failover = true ;
26972728
26982729 continue ;
26992730
@@ -2704,8 +2735,9 @@ static void bond_miimon_commit(struct bonding *bond)
27042735
27052736 continue ;
27062737 }
2738+ }
27072739
2708- do_failover :
2740+ if ( do_failover ) {
27092741 block_netpoll_tx ();
27102742 bond_select_active_slave (bond );
27112743 unblock_netpoll_tx ();
@@ -3503,6 +3535,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
35033535 */
35043536static void bond_ab_arp_commit (struct bonding * bond )
35053537{
3538+ bool do_failover = false;
35063539 struct list_head * iter ;
35073540 unsigned long last_tx ;
35083541 struct slave * slave ;
@@ -3532,8 +3565,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
35323565 slave_info (bond -> dev , slave -> dev , "link status definitely up\n" );
35333566
35343567 if (!rtnl_dereference (bond -> curr_active_slave ) ||
3535- slave == rtnl_dereference (bond -> primary_slave ))
3536- goto do_failover ;
3568+ slave == rtnl_dereference (bond -> primary_slave ) ||
3569+ slave -> prio > rtnl_dereference (bond -> curr_active_slave )-> prio )
3570+ do_failover = true;
35373571
35383572 }
35393573
@@ -3552,7 +3586,7 @@ static void bond_ab_arp_commit(struct bonding *bond)
35523586
35533587 if (slave == rtnl_dereference (bond -> curr_active_slave )) {
35543588 RCU_INIT_POINTER (bond -> current_arp_slave , NULL );
3555- goto do_failover ;
3589+ do_failover = true ;
35563590 }
35573591
35583592 continue ;
@@ -3576,8 +3610,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
35763610 slave -> link_new_state );
35773611 continue ;
35783612 }
3613+ }
35793614
3580- do_failover :
3615+ if ( do_failover ) {
35813616 block_netpoll_tx ();
35823617 bond_select_active_slave (bond );
35833618 unblock_netpoll_tx ();
0 commit comments