mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Merge branch 'bridge-prepare-lockless-br_port_fill_attrs-i'
Eric Dumazet says: ==================== bridge: prepare lockless br_port_fill_attrs() (I) medium-term goal is to allow "ip link show" dump commands to run without RTNL. This round of patches adds/fixes some lockess accesses in bridge. This is not complete, more patches will come later. Ultimately all changes to p->flags should use set_bit()/clear_bit(). I repeat (AI agents might read this cover ?): Many p->flags accesses are racy, and will hopefully be fixed in a future series. ==================== Link: https://patch.msgid.link/20260604141343.2124500-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
ffb64a86ba
|
|
@ -36,32 +36,60 @@ struct br_ip_list {
|
|||
struct br_ip addr;
|
||||
};
|
||||
|
||||
#define BR_HAIRPIN_MODE BIT(0)
|
||||
#define BR_BPDU_GUARD BIT(1)
|
||||
#define BR_ROOT_BLOCK BIT(2)
|
||||
#define BR_MULTICAST_FAST_LEAVE BIT(3)
|
||||
#define BR_ADMIN_COST BIT(4)
|
||||
#define BR_LEARNING BIT(5)
|
||||
#define BR_FLOOD BIT(6)
|
||||
enum bridge_flags_bit {
|
||||
BR_HAIRPIN_MODE_BIT,
|
||||
BR_BPDU_GUARD_BIT,
|
||||
BR_ROOT_BLOCK_BIT,
|
||||
BR_MULTICAST_FAST_LEAVE_BIT,
|
||||
BR_ADMIN_COST_BIT,
|
||||
BR_LEARNING_BIT,
|
||||
BR_FLOOD_BIT,
|
||||
BR_PROMISC_BIT,
|
||||
BR_PROXYARP_BIT,
|
||||
BR_LEARNING_SYNC_BIT,
|
||||
BR_PROXYARP_WIFI_BIT,
|
||||
BR_MCAST_FLOOD_BIT,
|
||||
BR_MULTICAST_TO_UNICAST_BIT,
|
||||
BR_VLAN_TUNNEL_BIT,
|
||||
BR_BCAST_FLOOD_BIT,
|
||||
BR_NEIGH_SUPPRESS_BIT,
|
||||
BR_ISOLATED_BIT,
|
||||
BR_MRP_AWARE_BIT,
|
||||
BR_MRP_LOST_CONT_BIT,
|
||||
BR_MRP_LOST_IN_CONT_BIT,
|
||||
BR_TX_FWD_OFFLOAD_BIT,
|
||||
BR_PORT_LOCKED_BIT,
|
||||
BR_PORT_MAB_BIT,
|
||||
BR_NEIGH_VLAN_SUPPRESS_BIT,
|
||||
BR_NEIGH_FORWARD_GRAT_BIT,
|
||||
};
|
||||
|
||||
#define BR_HAIRPIN_MODE BIT(BR_HAIRPIN_MODE_BIT)
|
||||
#define BR_BPDU_GUARD BIT(BR_BPDU_GUARD_BIT)
|
||||
#define BR_ROOT_BLOCK BIT(BR_ROOT_BLOCK_BIT)
|
||||
#define BR_MULTICAST_FAST_LEAVE BIT(BR_MULTICAST_FAST_LEAVE_BIT)
|
||||
#define BR_ADMIN_COST BIT(BR_ADMIN_COST_BIT)
|
||||
#define BR_LEARNING BIT(BR_LEARNING_BIT)
|
||||
#define BR_FLOOD BIT(BR_FLOOD_BIT)
|
||||
#define BR_AUTO_MASK (BR_FLOOD | BR_LEARNING)
|
||||
#define BR_PROMISC BIT(7)
|
||||
#define BR_PROXYARP BIT(8)
|
||||
#define BR_LEARNING_SYNC BIT(9)
|
||||
#define BR_PROXYARP_WIFI BIT(10)
|
||||
#define BR_MCAST_FLOOD BIT(11)
|
||||
#define BR_MULTICAST_TO_UNICAST BIT(12)
|
||||
#define BR_VLAN_TUNNEL BIT(13)
|
||||
#define BR_BCAST_FLOOD BIT(14)
|
||||
#define BR_NEIGH_SUPPRESS BIT(15)
|
||||
#define BR_ISOLATED BIT(16)
|
||||
#define BR_MRP_AWARE BIT(17)
|
||||
#define BR_MRP_LOST_CONT BIT(18)
|
||||
#define BR_MRP_LOST_IN_CONT BIT(19)
|
||||
#define BR_TX_FWD_OFFLOAD BIT(20)
|
||||
#define BR_PORT_LOCKED BIT(21)
|
||||
#define BR_PORT_MAB BIT(22)
|
||||
#define BR_NEIGH_VLAN_SUPPRESS BIT(23)
|
||||
#define BR_NEIGH_FORWARD_GRAT BIT(24)
|
||||
#define BR_PROMISC BIT(BR_PROMISC_BIT)
|
||||
#define BR_PROXYARP BIT(BR_PROXYARP_BIT)
|
||||
#define BR_LEARNING_SYNC BIT(BR_LEARNING_SYNC_BIT)
|
||||
#define BR_PROXYARP_WIFI BIT(BR_PROXYARP_WIFI_BIT)
|
||||
#define BR_MCAST_FLOOD BIT(BR_MCAST_FLOOD_BIT)
|
||||
#define BR_MULTICAST_TO_UNICAST BIT(BR_MULTICAST_TO_UNICAST_BIT)
|
||||
#define BR_VLAN_TUNNEL BIT(BR_VLAN_TUNNEL_BIT)
|
||||
#define BR_BCAST_FLOOD BIT(BR_BCAST_FLOOD_BIT)
|
||||
#define BR_NEIGH_SUPPRESS BIT(BR_NEIGH_SUPPRESS_BIT)
|
||||
#define BR_ISOLATED BIT(BR_ISOLATED_BIT)
|
||||
#define BR_MRP_AWARE BIT(BR_MRP_AWARE_BIT)
|
||||
#define BR_MRP_LOST_CONT BIT(BR_MRP_LOST_CONT_BIT)
|
||||
#define BR_MRP_LOST_IN_CONT BIT(BR_MRP_LOST_IN_CONT_BIT)
|
||||
#define BR_TX_FWD_OFFLOAD BIT(BR_TX_FWD_OFFLOAD_BIT)
|
||||
#define BR_PORT_LOCKED BIT(BR_PORT_LOCKED_BIT)
|
||||
#define BR_PORT_MAB BIT(BR_PORT_MAB_BIT)
|
||||
#define BR_NEIGH_VLAN_SUPPRESS BIT(BR_NEIGH_VLAN_SUPPRESS_BIT)
|
||||
#define BR_NEIGH_FORWARD_GRAT BIT(BR_NEIGH_FORWARD_GRAT_BIT)
|
||||
|
||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||
|
||||
|
|
|
|||
|
|
@ -76,9 +76,9 @@ void br_port_carrier_check(struct net_bridge_port *p, bool *notified)
|
|||
struct net_device *dev = p->dev;
|
||||
struct net_bridge *br = p->br;
|
||||
|
||||
if (!(p->flags & BR_ADMIN_COST) &&
|
||||
if (!test_bit(BR_ADMIN_COST_BIT, &p->flags) &&
|
||||
netif_running(dev) && netif_oper_up(dev))
|
||||
p->path_cost = port_cost(dev);
|
||||
WRITE_ONCE(p->path_cost, port_cost(dev));
|
||||
|
||||
*notified = false;
|
||||
if (!netif_running(br->dev))
|
||||
|
|
@ -111,7 +111,7 @@ static void br_port_set_promisc(struct net_bridge_port *p)
|
|||
return;
|
||||
|
||||
br_fdb_unsync_static(p->br, p);
|
||||
p->flags |= BR_PROMISC;
|
||||
set_bit(BR_PROMISC_BIT, &p->flags);
|
||||
}
|
||||
|
||||
static void br_port_clear_promisc(struct net_bridge_port *p)
|
||||
|
|
@ -134,7 +134,7 @@ static void br_port_clear_promisc(struct net_bridge_port *p)
|
|||
return;
|
||||
|
||||
dev_set_promiscuity(p->dev, -1);
|
||||
p->flags &= ~BR_PROMISC;
|
||||
clear_bit(BR_PROMISC_BIT, &p->flags);
|
||||
}
|
||||
|
||||
/* When a port is added or removed or when certain port flags
|
||||
|
|
|
|||
|
|
@ -257,13 +257,13 @@ int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
|
|||
memset(&p, 0, sizeof(struct __port_info));
|
||||
memcpy(&p.designated_root, &pt->designated_root, 8);
|
||||
memcpy(&p.designated_bridge, &pt->designated_bridge, 8);
|
||||
p.port_id = pt->port_id;
|
||||
p.designated_port = pt->designated_port;
|
||||
p.path_cost = pt->path_cost;
|
||||
p.designated_cost = pt->designated_cost;
|
||||
p.port_id = READ_ONCE(pt->port_id);
|
||||
p.designated_port = READ_ONCE(pt->designated_port);
|
||||
p.path_cost = READ_ONCE(pt->path_cost);
|
||||
p.designated_cost = READ_ONCE(pt->designated_cost);
|
||||
p.state = pt->state;
|
||||
p.top_change_ack = pt->topology_change_ack;
|
||||
p.config_pending = pt->config_pending;
|
||||
p.config_pending = READ_ONCE(pt->config_pending);
|
||||
p.message_age_timer_value = br_timer_value(&pt->message_age_timer);
|
||||
p.forward_delay_timer_value = br_timer_value(&pt->forward_delay_timer);
|
||||
p.hold_timer_value = br_timer_value(&pt->hold_timer);
|
||||
|
|
|
|||
|
|
@ -234,58 +234,61 @@ static inline size_t br_nlmsg_size(struct net_device *dev, u32 filter_mask)
|
|||
static int br_port_fill_attrs(struct sk_buff *skb,
|
||||
const struct net_bridge_port *p)
|
||||
{
|
||||
u8 mode = !!(p->flags & BR_HAIRPIN_MODE);
|
||||
unsigned long flags = READ_ONCE(p->flags);
|
||||
u8 mode = !!(flags & BR_HAIRPIN_MODE);
|
||||
struct net_bridge_port *backup_p;
|
||||
u64 timerval;
|
||||
|
||||
if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) ||
|
||||
nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_PRIORITY, READ_ONCE(p->priority)) ||
|
||||
nla_put_u32(skb, IFLA_BRPORT_COST, READ_ONCE(p->path_cost)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MODE, mode) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(flags & BR_BPDU_GUARD)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_PROTECT,
|
||||
!!(p->flags & BR_ROOT_BLOCK)) ||
|
||||
!!(flags & BR_ROOT_BLOCK)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE,
|
||||
!!(p->flags & BR_MULTICAST_FAST_LEAVE)) ||
|
||||
!!(flags & BR_MULTICAST_FAST_LEAVE)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MCAST_TO_UCAST,
|
||||
!!(p->flags & BR_MULTICAST_TO_UNICAST)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) ||
|
||||
!!(flags & BR_MULTICAST_TO_UNICAST)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(flags & BR_LEARNING)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
|
||||
!!(p->flags & BR_FLOOD)) ||
|
||||
!!(flags & BR_FLOOD)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MCAST_FLOOD,
|
||||
!!(p->flags & BR_MCAST_FLOOD)) ||
|
||||
!!(flags & BR_MCAST_FLOOD)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_BCAST_FLOOD,
|
||||
!!(p->flags & BR_BCAST_FLOOD)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP)) ||
|
||||
!!(flags & BR_BCAST_FLOOD)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(flags & BR_PROXYARP)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_PROXYARP_WIFI,
|
||||
!!(p->flags & BR_PROXYARP_WIFI)) ||
|
||||
!!(flags & BR_PROXYARP_WIFI)) ||
|
||||
nla_put(skb, IFLA_BRPORT_ROOT_ID, sizeof(struct ifla_bridge_id),
|
||||
&p->designated_root) ||
|
||||
nla_put(skb, IFLA_BRPORT_BRIDGE_ID, sizeof(struct ifla_bridge_id),
|
||||
&p->designated_bridge) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_PORT, p->designated_port) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_COST, p->designated_cost) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_ID, p->port_id) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_PORT,
|
||||
READ_ONCE(p->designated_port)) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_DESIGNATED_COST,
|
||||
READ_ONCE(p->designated_cost)) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_ID, READ_ONCE(p->port_id)) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_NO, p->port_no) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
|
||||
p->topology_change_ack) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
|
||||
nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, READ_ONCE(p->config_pending)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(flags &
|
||||
BR_VLAN_TUNNEL)) ||
|
||||
nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_NEIGH_SUPPRESS,
|
||||
!!(p->flags & BR_NEIGH_SUPPRESS)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(p->flags &
|
||||
!!(flags & BR_NEIGH_SUPPRESS)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(flags &
|
||||
BR_MRP_LOST_CONT)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
|
||||
!!(p->flags & BR_MRP_LOST_IN_CONT)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MAB, !!(p->flags & BR_PORT_MAB)) ||
|
||||
!!(flags & BR_MRP_LOST_IN_CONT)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(flags & BR_ISOLATED)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(flags & BR_PORT_LOCKED)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_MAB, !!(flags & BR_PORT_MAB)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
|
||||
!!(p->flags & BR_NEIGH_VLAN_SUPPRESS)) ||
|
||||
!!(flags & BR_NEIGH_VLAN_SUPPRESS)) ||
|
||||
nla_put_u8(skb, IFLA_BRPORT_NEIGH_FORWARD_GRAT,
|
||||
!!(p->flags & BR_NEIGH_FORWARD_GRAT)))
|
||||
!!(flags & BR_NEIGH_FORWARD_GRAT)))
|
||||
return -EMSGSIZE;
|
||||
|
||||
timerval = br_timer_value(&p->message_age_timer);
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ struct net_bridge_port {
|
|||
#define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj)
|
||||
|
||||
#define br_auto_port(p) ((p)->flags & BR_AUTO_MASK)
|
||||
#define br_promisc_port(p) ((p)->flags & BR_PROMISC)
|
||||
#define br_promisc_port(p) test_bit(BR_PROMISC_BIT, &(p)->flags)
|
||||
|
||||
static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -102,8 +102,9 @@ struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no)
|
|||
static int br_should_become_root_port(const struct net_bridge_port *p,
|
||||
u16 root_port)
|
||||
{
|
||||
struct net_bridge *br;
|
||||
u32 p_path_cost, rp_path_cost, p_designated_cost, rp_designated_cost;
|
||||
struct net_bridge_port *rp;
|
||||
struct net_bridge *br;
|
||||
int t;
|
||||
|
||||
br = p->br;
|
||||
|
|
@ -125,11 +126,16 @@ static int br_should_become_root_port(const struct net_bridge_port *p,
|
|||
else if (t > 0)
|
||||
return 0;
|
||||
|
||||
if (p->designated_cost + p->path_cost <
|
||||
rp->designated_cost + rp->path_cost)
|
||||
p_path_cost = READ_ONCE(p->path_cost);
|
||||
rp_path_cost = READ_ONCE(rp->path_cost);
|
||||
p_designated_cost = READ_ONCE(p->designated_cost);
|
||||
rp_designated_cost = READ_ONCE(rp->designated_cost);
|
||||
|
||||
if (p_designated_cost + p_path_cost <
|
||||
rp_designated_cost + rp_path_cost)
|
||||
return 1;
|
||||
else if (p->designated_cost + p->path_cost >
|
||||
rp->designated_cost + rp->path_cost)
|
||||
else if (p_designated_cost + p_path_cost >
|
||||
rp_designated_cost + rp_path_cost)
|
||||
return 0;
|
||||
|
||||
t = memcmp(&p->designated_bridge, &rp->designated_bridge, 8);
|
||||
|
|
@ -187,7 +193,8 @@ static void br_root_selection(struct net_bridge *br)
|
|||
} else {
|
||||
p = br_get_port(br, root_port);
|
||||
br->designated_root = p->designated_root;
|
||||
br->root_path_cost = p->designated_cost + p->path_cost;
|
||||
br->root_path_cost = READ_ONCE(p->designated_cost) +
|
||||
READ_ONCE(p->path_cost);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +220,7 @@ void br_transmit_config(struct net_bridge_port *p)
|
|||
struct net_bridge *br;
|
||||
|
||||
if (timer_pending(&p->hold_timer)) {
|
||||
p->config_pending = 1;
|
||||
WRITE_ONCE(p->config_pending, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +247,7 @@ void br_transmit_config(struct net_bridge_port *p)
|
|||
if (bpdu.message_age < br->max_age) {
|
||||
br_send_config_bpdu(p, &bpdu);
|
||||
p->topology_change_ack = 0;
|
||||
p->config_pending = 0;
|
||||
WRITE_ONCE(p->config_pending, 0);
|
||||
if (p->br->stp_enabled == BR_KERNEL_STP)
|
||||
mod_timer(&p->hold_timer,
|
||||
round_jiffies(jiffies + BR_HOLD_TIME));
|
||||
|
|
@ -252,9 +259,9 @@ static void br_record_config_information(struct net_bridge_port *p,
|
|||
const struct br_config_bpdu *bpdu)
|
||||
{
|
||||
p->designated_root = bpdu->root;
|
||||
p->designated_cost = bpdu->root_path_cost;
|
||||
WRITE_ONCE(p->designated_cost, bpdu->root_path_cost);
|
||||
p->designated_bridge = bpdu->bridge_id;
|
||||
p->designated_port = bpdu->port_id;
|
||||
WRITE_ONCE(p->designated_port, bpdu->port_id);
|
||||
p->designated_age = jiffies - bpdu->message_age;
|
||||
|
||||
mod_timer(&p->message_age_timer, jiffies
|
||||
|
|
@ -288,6 +295,7 @@ void br_transmit_tcn(struct net_bridge *br)
|
|||
static int br_should_become_designated_port(const struct net_bridge_port *p)
|
||||
{
|
||||
struct net_bridge *br;
|
||||
u32 p_designated_cost;
|
||||
int t;
|
||||
|
||||
br = p->br;
|
||||
|
|
@ -297,9 +305,10 @@ static int br_should_become_designated_port(const struct net_bridge_port *p)
|
|||
if (memcmp(&p->designated_root, &br->designated_root, 8))
|
||||
return 1;
|
||||
|
||||
if (br->root_path_cost < p->designated_cost)
|
||||
p_designated_cost = READ_ONCE(p->designated_cost);
|
||||
if (br->root_path_cost < p_designated_cost)
|
||||
return 1;
|
||||
else if (br->root_path_cost > p->designated_cost)
|
||||
else if (br->root_path_cost > p_designated_cost)
|
||||
return 0;
|
||||
|
||||
t = memcmp(&br->bridge_id, &p->designated_bridge, 8);
|
||||
|
|
@ -331,6 +340,7 @@ static void br_designated_port_selection(struct net_bridge *br)
|
|||
static int br_supersedes_port_info(const struct net_bridge_port *p,
|
||||
const struct br_config_bpdu *bpdu)
|
||||
{
|
||||
u32 p_designated_cost;
|
||||
int t;
|
||||
|
||||
t = memcmp(&bpdu->root, &p->designated_root, 8);
|
||||
|
|
@ -339,9 +349,10 @@ static int br_supersedes_port_info(const struct net_bridge_port *p,
|
|||
else if (t > 0)
|
||||
return 0;
|
||||
|
||||
if (bpdu->root_path_cost < p->designated_cost)
|
||||
p_designated_cost = READ_ONCE(p->designated_cost);
|
||||
if (bpdu->root_path_cost < p_designated_cost)
|
||||
return 1;
|
||||
else if (bpdu->root_path_cost > p->designated_cost)
|
||||
else if (bpdu->root_path_cost > p_designated_cost)
|
||||
return 0;
|
||||
|
||||
t = memcmp(&bpdu->bridge_id, &p->designated_bridge, 8);
|
||||
|
|
@ -421,9 +432,9 @@ void br_become_designated_port(struct net_bridge_port *p)
|
|||
|
||||
br = p->br;
|
||||
p->designated_root = br->designated_root;
|
||||
p->designated_cost = br->root_path_cost;
|
||||
WRITE_ONCE(p->designated_cost, br->root_path_cost);
|
||||
p->designated_bridge = br->bridge_id;
|
||||
p->designated_port = p->port_id;
|
||||
WRITE_ONCE(p->designated_port, p->port_id);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -479,14 +490,14 @@ void br_port_state_selection(struct net_bridge *br)
|
|||
/* Don't change port states if userspace is handling STP */
|
||||
if (br->stp_enabled != BR_USER_STP) {
|
||||
if (p->port_no == br->root_port) {
|
||||
p->config_pending = 0;
|
||||
WRITE_ONCE(p->config_pending, 0);
|
||||
p->topology_change_ack = 0;
|
||||
br_make_forwarding(p);
|
||||
} else if (br_is_designated_port(p)) {
|
||||
timer_delete(&p->message_age_timer);
|
||||
br_make_forwarding(p);
|
||||
} else {
|
||||
p->config_pending = 0;
|
||||
WRITE_ONCE(p->config_pending, 0);
|
||||
p->topology_change_ack = 0;
|
||||
br_make_blocking(p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ void br_init_port(struct net_bridge_port *p)
|
|||
{
|
||||
int err;
|
||||
|
||||
p->port_id = br_make_port_id(p->priority, p->port_no);
|
||||
WRITE_ONCE(p->port_id, br_make_port_id(p->priority, p->port_no));
|
||||
br_become_designated_port(p);
|
||||
br_set_state(p, BR_STATE_BLOCKING);
|
||||
p->topology_change_ack = 0;
|
||||
p->config_pending = 0;
|
||||
WRITE_ONCE(p->config_pending, 0);
|
||||
|
||||
err = __set_ageing_time(p->dev, p->br->ageing_time);
|
||||
if (err)
|
||||
|
|
@ -105,7 +105,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
|
|||
br_become_designated_port(p);
|
||||
br_set_state(p, BR_STATE_DISABLED);
|
||||
p->topology_change_ack = 0;
|
||||
p->config_pending = 0;
|
||||
WRITE_ONCE(p->config_pending, 0);
|
||||
|
||||
br_ifinfo_notify(RTM_NEWLINK, NULL, p);
|
||||
|
||||
|
|
@ -320,10 +320,10 @@ int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio)
|
|||
|
||||
new_port_id = br_make_port_id(newprio, p->port_no);
|
||||
if (br_is_designated_port(p))
|
||||
p->designated_port = new_port_id;
|
||||
WRITE_ONCE(p->designated_port, new_port_id);
|
||||
|
||||
p->port_id = new_port_id;
|
||||
p->priority = newprio;
|
||||
WRITE_ONCE(p->port_id, new_port_id);
|
||||
WRITE_ONCE(p->priority, newprio);
|
||||
if (!memcmp(&p->br->bridge_id, &p->designated_bridge, 8) &&
|
||||
p->port_id < p->designated_port) {
|
||||
br_become_designated_port(p);
|
||||
|
|
@ -340,8 +340,8 @@ int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost)
|
|||
path_cost > BR_MAX_PATH_COST)
|
||||
return -ERANGE;
|
||||
|
||||
p->flags |= BR_ADMIN_COST;
|
||||
p->path_cost = path_cost;
|
||||
set_bit(BR_ADMIN_COST_BIT, &p->flags);
|
||||
WRITE_ONCE(p->path_cost, path_cost);
|
||||
br_configuration_update(p->br);
|
||||
br_port_state_selection(p->br);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -160,5 +160,5 @@ void br_stp_port_timer_init(struct net_bridge_port *p)
|
|||
unsigned long br_timer_value(const struct timer_list *timer)
|
||||
{
|
||||
return timer_pending(timer)
|
||||
? jiffies_delta_to_clock_t(timer->expires - jiffies) : 0;
|
||||
? jiffies_delta_to_clock_t(READ_ONCE(timer->expires) - jiffies) : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static int store_flag(struct net_bridge_port *p, unsigned long v,
|
|||
|
||||
static ssize_t show_path_cost(struct net_bridge_port *p, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%d\n", p->path_cost);
|
||||
return sysfs_emit(buf, "%d\n", READ_ONCE(p->path_cost));
|
||||
}
|
||||
|
||||
static int store_path_cost(struct net_bridge_port *p, unsigned long v)
|
||||
|
|
@ -100,7 +100,7 @@ static BRPORT_ATTR(path_cost, 0644, show_path_cost, store_path_cost);
|
|||
|
||||
static ssize_t show_priority(struct net_bridge_port *p, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%d\n", p->priority);
|
||||
return sysfs_emit(buf, "%d\n", READ_ONCE(p->priority));
|
||||
}
|
||||
|
||||
static int store_priority(struct net_bridge_port *p, unsigned long v)
|
||||
|
|
@ -129,19 +129,19 @@ static BRPORT_ATTR(designated_bridge, 0444, show_designated_bridge, NULL);
|
|||
|
||||
static ssize_t show_designated_port(struct net_bridge_port *p, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%d\n", p->designated_port);
|
||||
return sysfs_emit(buf, "%d\n", READ_ONCE(p->designated_port));
|
||||
}
|
||||
static BRPORT_ATTR(designated_port, 0444, show_designated_port, NULL);
|
||||
|
||||
static ssize_t show_designated_cost(struct net_bridge_port *p, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%d\n", p->designated_cost);
|
||||
return sysfs_emit(buf, "%d\n", READ_ONCE(p->designated_cost));
|
||||
}
|
||||
static BRPORT_ATTR(designated_cost, 0444, show_designated_cost, NULL);
|
||||
|
||||
static ssize_t show_port_id(struct net_bridge_port *p, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "0x%x\n", p->port_id);
|
||||
return sysfs_emit(buf, "0x%x\n", READ_ONCE(p->port_id));
|
||||
}
|
||||
static BRPORT_ATTR(port_id, 0444, show_port_id, NULL);
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ static BRPORT_ATTR(change_ack, 0444, show_change_ack, NULL);
|
|||
|
||||
static ssize_t show_config_pending(struct net_bridge_port *p, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%d\n", p->config_pending);
|
||||
return sysfs_emit(buf, "%d\n", READ_ONCE(p->config_pending));
|
||||
}
|
||||
static BRPORT_ATTR(config_pending, 0444, show_config_pending, NULL);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user