Download raw body.
unlock igmp slow timeout
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 <sys/param.h>
> #include <sys/mbuf.h>
> +#include <sys/mutex.h>
> #include <sys/systm.h>
> #include <sys/socket.h>
> #include <sys/protosw.h>
> @@ -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
>
unlock igmp slow timeout