From: Vitaliy Makkoveev Subject: Re: unlock igmp slow timeout To: Alexander Bluhm Cc: tech@openbsd.org Date: Tue, 18 Nov 2025 00:46:44 +0300 On Thu, Nov 13, 2025 at 05:43:37PM +0100, Alexander Bluhm wrote: > On Wed, Nov 12, 2025 at 06:22:26PM +0100, Alexander Bluhm wrote: > > On Tue, Nov 11, 2025 at 10:49:59AM +0100, Alexander Bluhm wrote: > > > I would like to remove net lock from igmp_slowtimo(). Replace it > > > with a mutex that protects the router_info list. > > Remaining part after IGMP cleanup has been commited. > > ok? > ok mvs > bluhm > > Index: netinet/igmp.c > =================================================================== > RCS file: /cvs/src/sys/netinet/igmp.c,v > diff -u -p -r1.91 igmp.c > --- netinet/igmp.c 13 Nov 2025 15:49:50 -0000 1.91 > +++ netinet/igmp.c 13 Nov 2025 15:59:54 -0000 > @@ -77,6 +77,7 @@ > > #include > #include > +#include > #include > #include > #include > @@ -95,17 +96,25 @@ > #define IP_MULTICASTOPTS 0 > > /* > + * Locks used to protect global data and struct members: > + * I immutable after creation > + * a atomic > + * G global igmp mutex igmp_mtx > + */ > + > +/* > * Per-interface router version information. > */ > struct router_info { > - LIST_ENTRY(router_info) rti_list; > - unsigned int rti_ifidx; > - int rti_type; /* type of router on this interface */ > - int rti_age; /* time since last v1 query */ > + LIST_ENTRY(router_info) rti_list; /* [G] */ > + unsigned int rti_ifidx; /* [I] */ > + int rti_type; /* [G] type of router on interface */ > + int rti_age; /* [G] time since last v1 query */ > }; > > int igmp_timers_are_running; /* [a] shortcut for fast timer */ > -static LIST_HEAD(, router_info) rti_head; > +struct mutex igmp_mtx = MUTEX_INITIALIZER(IPL_SOFTNET); > +static LIST_HEAD(, router_info) rti_head; /* [G] */ > static struct mbuf *router_alert; > struct cpumem *igmpcounters; > > @@ -152,6 +161,8 @@ rti_find(unsigned int ifidx) > { > struct router_info *rti; > > + MUTEX_ASSERT_LOCKED(&igmp_mtx); > + > LIST_FOREACH(rti, &rti_head, rti_list) { > if (rti->rti_ifidx == ifidx) > return (rti); > @@ -162,29 +173,38 @@ rti_find(unsigned int ifidx) > int > rti_fill(struct in_multi *inm) > { > - struct router_info *rti, *new_rti; > + struct router_info *rti, *new_rti = NULL; > + int type; > > + mtx_enter(&igmp_mtx); > rti = rti_find(inm->inm_ifidx); > if (rti != NULL) > goto found; > + mtx_leave(&igmp_mtx); > > new_rti = malloc(sizeof(*rti), M_MRTABLE, M_WAITOK); > - /* check again after potential sleep */ > + > + mtx_enter(&igmp_mtx); > + /* check again after unlock and lock */ > rti = rti_find(inm->inm_ifidx); > - if (rti != NULL) { > - free(new_rti, M_MRTABLE, sizeof(*rti)); > + if (rti != NULL) > goto found; > - } > rti = new_rti; > rti->rti_ifidx = inm->inm_ifidx; > rti->rti_type = IGMP_v2_ROUTER; > LIST_INSERT_HEAD(&rti_head, rti, rti_list); > inm->inm_rti = rti; > + mtx_leave(&igmp_mtx); > + > return (IGMP_v2_HOST_MEMBERSHIP_REPORT); > > found: > inm->inm_rti = rti; > - return (rti->rti_type == IGMP_v1_ROUTER ? > + type = rti->rti_type; > + mtx_leave(&igmp_mtx); > + > + free(new_rti, M_MRTABLE, sizeof(*rti)); > + return (type == IGMP_v1_ROUTER ? > IGMP_v1_HOST_MEMBERSHIP_REPORT : IGMP_v2_HOST_MEMBERSHIP_REPORT); > } > > @@ -193,18 +213,23 @@ rti_reset(struct ifnet *ifp) > { > struct router_info *rti; > > + mtx_enter(&igmp_mtx); > rti = rti_find(ifp->if_index); > if (rti != NULL) > goto found; > > rti = malloc(sizeof(*rti), M_MRTABLE, M_NOWAIT); > - if (rti == NULL) > + if (rti == NULL) { > + mtx_leave(&igmp_mtx); > return (ENOBUFS); > + } > rti->rti_ifidx = ifp->if_index; > LIST_INSERT_HEAD(&rti_head, rti, rti_list); > found: > rti->rti_type = IGMP_v1_ROUTER; > rti->rti_age = 0; > + mtx_leave(&igmp_mtx); > + > return (0); > } > > @@ -213,11 +238,13 @@ rti_delete(struct ifnet *ifp) > { > struct router_info *rti; > > + mtx_enter(&igmp_mtx); > rti = rti_find(ifp->if_index); > - if (rti != NULL) { > + if (rti != NULL) > LIST_REMOVE(rti, rti_list); > - free(rti, M_MRTABLE, sizeof(*rti)); > - } > + mtx_leave(&igmp_mtx); > + > + free(rti, M_MRTABLE, sizeof(*rti)); > } > > int > @@ -622,16 +649,14 @@ igmp_slowtimo(void) > { > struct router_info *rti; > > - NET_LOCK(); > - > + mtx_enter(&igmp_mtx); > LIST_FOREACH(rti, &rti_head, rti_list) { > if (rti->rti_type == IGMP_v1_ROUTER && > ++rti->rti_age >= IGMP_AGE_THRESHOLD) { > rti->rti_type = IGMP_v2_ROUTER; > } > } > - > - NET_UNLOCK(); > + mtx_leave(&igmp_mtx); > } > > void >