Nikolay Aleksandrov <razor@xxxxxxxxxxxxx> writes: > On 26/01/2023 19:01, Petr Machata wrote: >> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c >> index de531109b947..04261dd2380b 100644 >> --- a/net/bridge/br_multicast.c >> +++ b/net/bridge/br_multicast.c >> @@ -766,6 +766,102 @@ static void br_multicast_port_ngroups_dec(struct net_bridge_port *port, u16 vid) >> br_multicast_port_ngroups_dec_one(&port->multicast_ctx); >> } >> >> +static int >> +br_multicast_pmctx_ngroups_set_max(struct net_bridge_mcast_port *pmctx, >> + u32 max, struct netlink_ext_ack *extack) >> +{ >> + if (max && max < pmctx->mdb_n_entries) { >> + NL_SET_ERR_MSG_FMT_MOD(extack, "Can't set mcast_max_groups=%u, which is below mcast_n_groups=%u", >> + max, pmctx->mdb_n_entries); > > Why not? All new entries will be rejected anyway, at most some will expire and make room. Yeah, as I wrote in the other thread, I can relax the relationship between max and n. >> + return -EINVAL; >> + } >> + >> + pmctx->mdb_max_entries = max; >> + return 0; >> +} >> + >> +u32 br_multicast_port_ngroups_get(const struct net_bridge_port *port) >> +{ >> + u32 n; >> + >> + spin_lock_bh(&port->br->multicast_lock); >> + n = port->multicast_ctx.mdb_n_entries; >> + spin_unlock_bh(&port->br->multicast_lock); > > This is too much just to read the value, we block all IGMP/MLD processing and potentially > block packet processing on the same core just to read it. These reads are done for notifications, > getlink and also for fill_slave_info. I think we can just use WRITE/READ_ONCE helpers to access > it. Especially since the lock is taken for both values (max and current count). We still get a > snapshop that can be wrong by the time it's returned and about changing it we'll start enforcing > the new limit with a minor delay which is not a big deal. Makes sense. >> + >> + return n; >> +} >> + >> +int br_multicast_vlan_ngroups_get(struct net_bridge *br, >> + const struct net_bridge_vlan *v, >> + u32 *n) >> +{ >> + if (br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx)) >> + return -EINVAL; >> + >> + spin_lock_bh(&br->multicast_lock); >> + *n = v->port_mcast_ctx.mdb_n_entries; >> + spin_unlock_bh(&br->multicast_lock); >> + > > ditto and for all accesses below that require the lock.. Yah.