Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bonding: 3ad: implement proper RCU rules for port->aggregator

syzbot found a data-race in bond_3ad_get_active_agg_info /
bond_3ad_state_machine_handler [1] which hints at lack of proper
RCU implementation.

Add __rcu qualifier to port->aggregator, and add proper RCU API.

[1]

BUG: KCSAN: data-race in bond_3ad_get_active_agg_info / bond_3ad_state_machine_handler

write to 0xffff88813cf5c4b0 of 8 bytes by task 36 on cpu 0:
ad_port_selection_logic drivers/net/bonding/bond_3ad.c:1659 [inline]
bond_3ad_state_machine_handler+0x9d5/0x2d60 drivers/net/bonding/bond_3ad.c:2569
process_one_work kernel/workqueue.c:3302 [inline]
process_scheduled_works+0x4f0/0x9c0 kernel/workqueue.c:3385
worker_thread+0x58a/0x780 kernel/workqueue.c:3466
kthread+0x22a/0x280 kernel/kthread.c:436
ret_from_fork+0x146/0x330 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

read to 0xffff88813cf5c4b0 of 8 bytes by task 22063 on cpu 1:
__bond_3ad_get_active_agg_info drivers/net/bonding/bond_3ad.c:2858 [inline]
bond_3ad_get_active_agg_info+0x8c/0x230 drivers/net/bonding/bond_3ad.c:2881
bond_fill_info+0xe0f/0x10f0 drivers/net/bonding/bond_netlink.c:853
rtnl_link_info_fill net/core/rtnetlink.c:906 [inline]
rtnl_link_fill+0x1d7/0x4e0 net/core/rtnetlink.c:927
rtnl_fill_ifinfo+0xf8e/0x1380 net/core/rtnetlink.c:2168
rtmsg_ifinfo_build_skb+0x11c/0x1b0 net/core/rtnetlink.c:4453
rtmsg_ifinfo_event net/core/rtnetlink.c:4486 [inline]
rtmsg_ifinfo+0x6d/0x110 net/core/rtnetlink.c:4495
__dev_notify_flags+0x76/0x390 net/core/dev.c:9790
netif_change_flags+0xac/0xd0 net/core/dev.c:9823
do_setlink+0x905/0x2950 net/core/rtnetlink.c:3180
rtnl_group_changelink net/core/rtnetlink.c:3813 [inline]
__rtnl_newlink net/core/rtnetlink.c:3981 [inline]
rtnl_newlink+0xf55/0x1400 net/core/rtnetlink.c:4109
rtnetlink_rcv_msg+0x64b/0x720 net/core/rtnetlink.c:6995
netlink_rcv_skb+0x123/0x220 net/netlink/af_netlink.c:2550
rtnetlink_rcv+0x1c/0x30 net/core/rtnetlink.c:7022
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x5a8/0x680 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x5c8/0x6f0 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x563/0x5b0 net/socket.c:2698
___sys_sendmsg+0x195/0x1e0 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0xd4/0x160 net/socket.c:2787
x64_sys_call+0x194c/0x3020 arch/x86/include/generated/asm/syscalls_64.h:47
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x12c/0x3b0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f

value changed: 0x0000000000000000 -> 0xffff88813cf5c400

Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 22063 Comm: syz.0.31122 Tainted: G W syzkaller #0 PREEMPT(full)
Tainted: [W]=WARN
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026

Fixes: 47e91f56008b ("bonding: use RCU protection for 3ad xmit path")
Reported-by: syzbot+9bb2ff2a4ab9e17307e1@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/69f0a82f.050a0220.3aadc4.0000.GAE@google.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jay Vosburgh <jv@jvosburgh.net>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Link: https://patch.msgid.link/20260428123207.3809211-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
c4f050ce 4ca01292

+89 -66
+60 -49
drivers/net/bonding/bond_3ad.c
··· 1029 1029 static void ad_mux_machine(struct port *port, bool *update_slave_arr) 1030 1030 { 1031 1031 struct bonding *bond = __get_bond_by_port(port); 1032 + struct aggregator *aggregator; 1032 1033 mux_states_t last_state; 1033 1034 1034 1035 /* keep current State Machine state to compare later if it was ··· 1037 1036 */ 1038 1037 last_state = port->sm_mux_state; 1039 1038 1039 + aggregator = rcu_dereference(port->aggregator); 1040 1040 if (port->sm_vars & AD_PORT_BEGIN) { 1041 1041 port->sm_mux_state = AD_MUX_DETACHED; 1042 1042 } else { ··· 1057 1055 * cycle to update ready variable, we check 1058 1056 * READY_N and update READY here 1059 1057 */ 1060 - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); 1058 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1061 1059 port->sm_mux_state = AD_MUX_DETACHED; 1062 1060 break; 1063 1061 } ··· 1072 1070 * update ready variable, we check READY_N and update 1073 1071 * READY here 1074 1072 */ 1075 - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); 1073 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1076 1074 1077 1075 /* if the wait_while_timer expired, and the port is 1078 1076 * in READY state, move to ATTACHED state ··· 1088 1086 if ((port->sm_vars & AD_PORT_SELECTED) && 1089 1087 (port->partner_oper.port_state & LACP_STATE_SYNCHRONIZATION) && 1090 1088 !__check_agg_selection_timer(port)) { 1091 - if (port->aggregator->is_active) { 1089 + if (aggregator->is_active) { 1092 1090 int state = AD_MUX_COLLECTING_DISTRIBUTING; 1093 1091 1094 1092 if (!bond->params.coupled_control) ··· 1104 1102 * cycle to update ready variable, we check 1105 1103 * READY_N and update READY here 1106 1104 */ 1107 - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); 1105 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1108 1106 port->sm_mux_state = AD_MUX_DETACHED; 1109 - } else if (port->aggregator->is_active) { 1107 + } else if (aggregator->is_active) { 1110 1108 port->actor_oper_port_state |= 1111 1109 LACP_STATE_SYNCHRONIZATION; 1112 1110 } ··· 1117 1115 * sure that a collecting distributing 1118 1116 * port in an active aggregator is enabled 1119 1117 */ 1120 - if (port->aggregator->is_active && 1118 + if (aggregator->is_active && 1121 1119 !__port_is_collecting_distributing(port)) { 1122 1120 __enable_port(port); 1123 1121 *update_slave_arr = true; ··· 1136 1134 */ 1137 1135 struct slave *slave = port->slave; 1138 1136 1139 - if (port->aggregator->is_active && 1137 + if (aggregator->is_active && 1140 1138 bond_is_slave_rx_disabled(slave)) { 1141 1139 ad_enable_collecting(port); 1142 1140 *update_slave_arr = true; ··· 1156 1154 * sure that a collecting distributing 1157 1155 * port in an active aggregator is enabled 1158 1156 */ 1159 - if (port->aggregator && 1160 - port->aggregator->is_active && 1157 + if (aggregator && 1158 + aggregator->is_active && 1161 1159 !__port_is_collecting_distributing(port)) { 1162 1160 __enable_port(port); 1163 1161 *update_slave_arr = true; ··· 1189 1187 port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0); 1190 1188 break; 1191 1189 case AD_MUX_ATTACHED: 1192 - if (port->aggregator->is_active) 1190 + if (aggregator->is_active) 1193 1191 port->actor_oper_port_state |= 1194 1192 LACP_STATE_SYNCHRONIZATION; 1195 1193 else ··· 1563 1561 bond = __get_bond_by_port(port); 1564 1562 1565 1563 /* if the port is connected to other aggregator, detach it */ 1566 - if (port->aggregator) { 1564 + temp_aggregator = rcu_dereference(port->aggregator); 1565 + if (temp_aggregator) { 1567 1566 /* detach the port from its former aggregator */ 1568 - temp_aggregator = port->aggregator; 1569 1567 for (curr_port = temp_aggregator->lag_ports; curr_port; 1570 1568 last_port = curr_port, 1571 1569 curr_port = curr_port->next_port_in_aggregator) { ··· 1588 1586 /* clear the port's relations to this 1589 1587 * aggregator 1590 1588 */ 1591 - port->aggregator = NULL; 1589 + RCU_INIT_POINTER(port->aggregator, NULL); 1592 1590 port->next_port_in_aggregator = NULL; 1593 1591 port->actor_port_aggregator_identifier = 0; 1594 1592 ··· 1611 1609 port->slave->bond->dev->name, 1612 1610 port->slave->dev->name, 1613 1611 port->actor_port_number, 1614 - port->aggregator->aggregator_identifier); 1612 + temp_aggregator->aggregator_identifier); 1615 1613 } 1616 1614 } 1617 1615 /* search on all aggregators for a suitable aggregator for this port */ ··· 1635 1633 ) 1636 1634 ) { 1637 1635 /* attach to the founded aggregator */ 1638 - port->aggregator = aggregator; 1636 + rcu_assign_pointer(port->aggregator, aggregator); 1639 1637 port->actor_port_aggregator_identifier = 1640 - port->aggregator->aggregator_identifier; 1638 + aggregator->aggregator_identifier; 1641 1639 port->next_port_in_aggregator = aggregator->lag_ports; 1642 - port->aggregator->num_of_ports++; 1640 + aggregator->num_of_ports++; 1643 1641 aggregator->lag_ports = port; 1644 1642 slave_dbg(bond->dev, slave->dev, "Port %d joined LAG %d (existing LAG)\n", 1645 1643 port->actor_port_number, 1646 - port->aggregator->aggregator_identifier); 1644 + aggregator->aggregator_identifier); 1647 1645 1648 1646 /* mark this port as selected */ 1649 1647 port->sm_vars |= AD_PORT_SELECTED; ··· 1658 1656 if (!found) { 1659 1657 if (free_aggregator) { 1660 1658 /* assign port a new aggregator */ 1661 - port->aggregator = free_aggregator; 1662 1659 port->actor_port_aggregator_identifier = 1663 - port->aggregator->aggregator_identifier; 1660 + free_aggregator->aggregator_identifier; 1664 1661 1665 1662 /* update the new aggregator's parameters 1666 1663 * if port was responsed from the end-user 1667 1664 */ 1668 1665 if (port->actor_oper_port_key & AD_DUPLEX_KEY_MASKS) 1669 1666 /* if port is full duplex */ 1670 - port->aggregator->is_individual = false; 1667 + free_aggregator->is_individual = false; 1671 1668 else 1672 - port->aggregator->is_individual = true; 1669 + free_aggregator->is_individual = true; 1673 1670 1674 - port->aggregator->actor_admin_aggregator_key = 1671 + free_aggregator->actor_admin_aggregator_key = 1675 1672 port->actor_admin_port_key; 1676 - port->aggregator->actor_oper_aggregator_key = 1673 + free_aggregator->actor_oper_aggregator_key = 1677 1674 port->actor_oper_port_key; 1678 - port->aggregator->partner_system = 1675 + free_aggregator->partner_system = 1679 1676 port->partner_oper.system; 1680 - port->aggregator->partner_system_priority = 1677 + free_aggregator->partner_system_priority = 1681 1678 port->partner_oper.system_priority; 1682 - port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; 1683 - port->aggregator->receive_state = 1; 1684 - port->aggregator->transmit_state = 1; 1685 - port->aggregator->lag_ports = port; 1686 - port->aggregator->num_of_ports++; 1679 + free_aggregator->partner_oper_aggregator_key = port->partner_oper.key; 1680 + free_aggregator->receive_state = 1; 1681 + free_aggregator->transmit_state = 1; 1682 + free_aggregator->lag_ports = port; 1683 + free_aggregator->num_of_ports++; 1684 + 1685 + rcu_assign_pointer(port->aggregator, free_aggregator); 1687 1686 1688 1687 /* mark this port as selected */ 1689 1688 port->sm_vars |= AD_PORT_SELECTED; 1690 1689 1691 1690 slave_dbg(bond->dev, port->slave->dev, "Port %d joined LAG %d (new LAG)\n", 1692 1691 port->actor_port_number, 1693 - port->aggregator->aggregator_identifier); 1692 + free_aggregator->aggregator_identifier); 1694 1693 } else { 1695 1694 slave_err(bond->dev, port->slave->dev, 1696 1695 "Port %d did not find a suitable aggregator\n", ··· 1703 1700 * in all aggregator's ports, else set ready=FALSE in all 1704 1701 * aggregator's ports 1705 1702 */ 1706 - __set_agg_ports_ready(port->aggregator, 1707 - __agg_ports_are_ready(port->aggregator)); 1703 + aggregator = rcu_dereference(port->aggregator); 1704 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1708 1705 1709 - aggregator = __get_first_agg(port); 1710 - ad_agg_selection_logic(aggregator, update_slave_arr); 1706 + ad_agg_selection_logic(__get_first_agg(port), update_slave_arr); 1711 1707 1712 - if (!port->aggregator->is_active) 1708 + if (!aggregator->is_active) 1713 1709 port->actor_oper_port_state &= ~LACP_STATE_SYNCHRONIZATION; 1714 1710 } 1715 1711 ··· 2077 2075 */ 2078 2076 static void ad_enable_collecting(struct port *port) 2079 2077 { 2080 - if (port->aggregator->is_active) { 2078 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2079 + 2080 + if (aggregator->is_active) { 2081 2081 struct slave *slave = port->slave; 2082 2082 2083 2083 slave_dbg(slave->bond->dev, slave->dev, 2084 2084 "Enabling collecting on port %d (LAG %d)\n", 2085 2085 port->actor_port_number, 2086 - port->aggregator->aggregator_identifier); 2086 + aggregator->aggregator_identifier); 2087 2087 __enable_collecting_port(port); 2088 2088 } 2089 2089 } ··· 2097 2093 */ 2098 2094 static void ad_disable_distributing(struct port *port, bool *update_slave_arr) 2099 2095 { 2100 - if (port->aggregator && __agg_has_partner(port->aggregator)) { 2096 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2097 + 2098 + if (aggregator && __agg_has_partner(aggregator)) { 2101 2099 slave_dbg(port->slave->bond->dev, port->slave->dev, 2102 2100 "Disabling distributing on port %d (LAG %d)\n", 2103 2101 port->actor_port_number, 2104 - port->aggregator->aggregator_identifier); 2102 + aggregator->aggregator_identifier); 2105 2103 __disable_distributing_port(port); 2106 2104 /* Slave array needs an update */ 2107 2105 *update_slave_arr = true; ··· 2120 2114 static void ad_enable_collecting_distributing(struct port *port, 2121 2115 bool *update_slave_arr) 2122 2116 { 2123 - if (port->aggregator->is_active) { 2117 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2118 + 2119 + if (aggregator->is_active) { 2124 2120 slave_dbg(port->slave->bond->dev, port->slave->dev, 2125 2121 "Enabling port %d (LAG %d)\n", 2126 2122 port->actor_port_number, 2127 - port->aggregator->aggregator_identifier); 2123 + aggregator->aggregator_identifier); 2128 2124 __enable_port(port); 2129 2125 /* Slave array needs update */ 2130 2126 *update_slave_arr = true; ··· 2143 2135 static void ad_disable_collecting_distributing(struct port *port, 2144 2136 bool *update_slave_arr) 2145 2137 { 2146 - if (port->aggregator && __agg_has_partner(port->aggregator)) { 2138 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2139 + 2140 + if (aggregator && __agg_has_partner(aggregator)) { 2147 2141 slave_dbg(port->slave->bond->dev, port->slave->dev, 2148 2142 "Disabling port %d (LAG %d)\n", 2149 2143 port->actor_port_number, 2150 - port->aggregator->aggregator_identifier); 2144 + aggregator->aggregator_identifier); 2151 2145 __disable_port(port); 2152 2146 /* Slave array needs an update */ 2153 2147 *update_slave_arr = true; ··· 2389 2379 */ 2390 2380 for (temp_port = aggregator->lag_ports; temp_port; 2391 2381 temp_port = temp_port->next_port_in_aggregator) { 2392 - temp_port->aggregator = new_aggregator; 2382 + rcu_assign_pointer(temp_port->aggregator, new_aggregator); 2393 2383 temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; 2394 2384 } 2395 2385 ··· 2858 2848 int __bond_3ad_get_active_agg_info(struct bonding *bond, 2859 2849 struct ad_info *ad_info) 2860 2850 { 2861 - struct aggregator *aggregator = NULL; 2851 + struct aggregator *aggregator = NULL, *tmp; 2862 2852 struct list_head *iter; 2863 2853 struct slave *slave; 2864 2854 struct port *port; 2865 2855 2866 2856 bond_for_each_slave_rcu(bond, slave, iter) { 2867 2857 port = &(SLAVE_AD_INFO(slave)->port); 2868 - if (port->aggregator && port->aggregator->is_active) { 2869 - aggregator = port->aggregator; 2858 + tmp = rcu_dereference(port->aggregator); 2859 + if (tmp && tmp->is_active) { 2860 + aggregator = tmp; 2870 2861 break; 2871 2862 } 2872 2863 }
+5 -3
drivers/net/bonding/bond_main.c
··· 1433 1433 1434 1434 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 1435 1435 struct aggregator *agg = 1436 - SLAVE_AD_INFO(slave)->port.aggregator; 1436 + rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 1437 1437 1438 1438 if (agg && 1439 1439 agg->aggregator_identifier != ad_info.aggregator_id) ··· 5179 5179 spin_unlock_bh(&bond->mode_lock); 5180 5180 agg_id = ad_info.aggregator_id; 5181 5181 } 5182 + rcu_read_lock(); 5182 5183 bond_for_each_slave(bond, slave, iter) { 5183 5184 if (skipslave == slave) 5184 5185 continue; 5185 5186 5186 5187 all_slaves->arr[all_slaves->count++] = slave; 5187 5188 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 5188 - struct aggregator *agg; 5189 + const struct aggregator *agg; 5189 5190 5190 - agg = SLAVE_AD_INFO(slave)->port.aggregator; 5191 + agg = rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 5191 5192 if (!agg || agg->aggregator_identifier != agg_id) 5192 5193 continue; 5193 5194 } ··· 5200 5199 5201 5200 usable_slaves->arr[usable_slaves->count++] = slave; 5202 5201 } 5202 + rcu_read_unlock(); 5203 5203 5204 5204 bond_set_slave_arr(bond, usable_slaves, all_slaves); 5205 5205 return ret;
+10 -6
drivers/net/bonding/bond_netlink.c
··· 66 66 const struct port *ad_port; 67 67 68 68 ad_port = &SLAVE_AD_INFO(slave)->port; 69 - agg = SLAVE_AD_INFO(slave)->port.aggregator; 69 + rcu_read_lock(); 70 + agg = rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 70 71 if (agg) { 71 72 if (nla_put_u16(skb, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, 72 73 agg->aggregator_identifier)) 73 - goto nla_put_failure; 74 + goto nla_put_failure_rcu; 74 75 if (nla_put_u8(skb, 75 76 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, 76 77 ad_port->actor_oper_port_state)) 77 - goto nla_put_failure; 78 + goto nla_put_failure_rcu; 78 79 if (nla_put_u16(skb, 79 80 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, 80 81 ad_port->partner_oper.port_state)) 81 - goto nla_put_failure; 82 + goto nla_put_failure_rcu; 82 83 83 84 if (nla_put_u8(skb, IFLA_BOND_SLAVE_AD_CHURN_ACTOR_STATE, 84 85 ad_port->sm_churn_actor_state)) 85 - goto nla_put_failure; 86 + goto nla_put_failure_rcu; 86 87 if (nla_put_u8(skb, IFLA_BOND_SLAVE_AD_CHURN_PARTNER_STATE, 87 88 ad_port->sm_churn_partner_state)) 88 - goto nla_put_failure; 89 + goto nla_put_failure_rcu; 89 90 } 91 + rcu_read_unlock(); 90 92 91 93 if (nla_put_u16(skb, IFLA_BOND_SLAVE_ACTOR_PORT_PRIO, 92 94 SLAVE_AD_INFO(slave)->port_priority)) ··· 97 95 98 96 return 0; 99 97 98 + nla_put_failure_rcu: 99 + rcu_read_unlock(); 100 100 nla_put_failure: 101 101 return -EMSGSIZE; 102 102 }
+2 -1
drivers/net/bonding/bond_procfs.c
··· 188 188 } 189 189 } 190 190 191 + /* Note: runs under rcu_read_lock() */ 191 192 static void bond_info_show_slave(struct seq_file *seq, 192 193 const struct slave *slave) 193 194 { ··· 215 214 216 215 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 217 216 const struct port *port = &SLAVE_AD_INFO(slave)->port; 218 - const struct aggregator *agg = port->aggregator; 217 + const struct aggregator *agg = rcu_dereference(port->aggregator); 219 218 220 219 if (agg) { 221 220 seq_printf(seq, "Aggregator ID: %d\n",
+11 -6
drivers/net/bonding/bond_sysfs_slave.c
··· 62 62 const struct aggregator *agg; 63 63 64 64 if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { 65 - agg = SLAVE_AD_INFO(slave)->port.aggregator; 66 - if (agg) 67 - return sysfs_emit(buf, "%d\n", 68 - agg->aggregator_identifier); 65 + rcu_read_lock(); 66 + agg = rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 67 + if (agg) { 68 + ssize_t res = sysfs_emit(buf, "%d\n", 69 + agg->aggregator_identifier); 70 + rcu_read_unlock(); 71 + return res; 72 + } 73 + rcu_read_unlock(); 69 74 } 70 75 71 76 return sysfs_emit(buf, "N/A\n"); ··· 83 78 84 79 if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { 85 80 ad_port = &SLAVE_AD_INFO(slave)->port; 86 - if (ad_port->aggregator) 81 + if (rcu_access_pointer(ad_port->aggregator)) 87 82 return sysfs_emit(buf, "%u\n", 88 83 ad_port->actor_oper_port_state); 89 84 } ··· 98 93 99 94 if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { 100 95 ad_port = &SLAVE_AD_INFO(slave)->port; 101 - if (ad_port->aggregator) 96 + if (rcu_access_pointer(ad_port->aggregator)) 102 97 return sysfs_emit(buf, "%u\n", 103 98 ad_port->partner_oper.port_state); 104 99 }
+1 -1
include/net/bond_3ad.h
··· 243 243 churn_state_t sm_churn_actor_state; 244 244 churn_state_t sm_churn_partner_state; 245 245 struct slave *slave; /* pointer to the bond slave that this port belongs to */ 246 - struct aggregator *aggregator; /* pointer to an aggregator that this port related to */ 246 + struct aggregator __rcu *aggregator; /* pointer to an aggregator that this port related to */ 247 247 struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */ 248 248 u32 transaction_id; /* continuous number for identification of Marker PDU's; */ 249 249 struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */