diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 3e9b10f8abf1..2f9bb30e1a1f 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1441,16 +1441,17 @@ struct net_bridge_port_group *br_multicast_new_port_group( goto free_out; } - rcu_assign_pointer(p->next, next); timer_setup(&p->timer, br_multicast_port_group_expired, 0); timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0); - hlist_add_head(&p->mglist, &port->mglist); if (src) memcpy(p->eth_addr, src, ETH_ALEN); else eth_broadcast_addr(p->eth_addr); + RCU_INIT_POINTER(p->next, next); + hlist_add_head_rcu(&p->mglist, &port->mglist); + return p; free_out: @@ -1465,11 +1466,11 @@ void br_multicast_del_port_group(struct net_bridge_port_group *p) struct net_bridge_port *port = p->key.port; __u16 vid = p->key.addr.vid; - hlist_del_init(&p->mglist); + hlist_del_init_rcu(&p->mglist); if (!br_multicast_is_star_g(&p->key.addr)) rhashtable_remove_fast(&port->br->sg_port_tbl, &p->rhnode, br_sg_port_rht_params); - kfree(p); + kfree_rcu(p, rcu); br_multicast_port_ngroups_dec(port, vid); }