Index: sys/kern/uipc_domain.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/kern/uipc_domain.c,v diff -u -p -u -p -r1.65 uipc_domain.c --- sys/kern/uipc_domain.c 11 Jan 2024 14:15:11 -0000 1.65 +++ sys/kern/uipc_domain.c 12 Aug 2024 13:50:30 -0000 @@ -90,8 +90,10 @@ domaininit(void) max_linkhdr = 64; max_hdr = max_linkhdr + max_protohdr; - timeout_set_proc(&pffast_timeout, pffasttimo, &pffast_timeout); - timeout_set_proc(&pfslow_timeout, pfslowtimo, &pfslow_timeout); + timeout_set_flags(&pffast_timeout, pffasttimo, &pffast_timeout, + KCLOCK_NONE, TIMEOUT_PROC | TIMEOUT_MPSAFE); + timeout_set_flags(&pfslow_timeout, pfslowtimo, &pfslow_timeout, + KCLOCK_NONE, TIMEOUT_PROC | TIMEOUT_MPSAFE); timeout_add(&pffast_timeout, 1); timeout_add(&pfslow_timeout, 1); } Index: sys/netinet/igmp.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet/igmp.c,v diff -u -p -u -p -r1.83 igmp.c --- sys/netinet/igmp.c 16 Sep 2023 09:33:27 -0000 1.83 +++ sys/netinet/igmp.c 12 Aug 2024 13:50:30 -0000 @@ -96,12 +96,12 @@ #define IP_MULTICASTOPTS 0 -int igmp_timers_are_running; /* [N] shortcut for fast timer */ +int igmp_timers_are_running; /* [a] shortcut for fast timer */ static LIST_HEAD(, router_info) rti_head; static struct mbuf *router_alert; struct cpumem *igmpcounters; -void igmp_checktimer(struct ifnet *); +int igmp_checktimer(struct ifnet *); void igmp_sendpkt(struct ifnet *, struct in_multi *, int, in_addr_t); int rti_fill(struct in_multi *); struct router_info * rti_find(struct ifnet *); @@ -228,7 +228,7 @@ igmp_input_if(struct ifnet *ifp, struct struct in_multi *inm; struct router_info *rti; struct in_ifaddr *ia; - int timer; + int timer, running = 0; igmplen = ntohs(ip->ip_len) - iphlen; @@ -300,7 +300,7 @@ igmp_input_if(struct ifnet *ifp, struct inm->inm_state = IGMP_DELAYING_MEMBER; inm->inm_timer = IGMP_RANDOM_DELAY( IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ); - igmp_timers_are_running = 1; + running = 1; } } } else { @@ -341,7 +341,7 @@ igmp_input_if(struct ifnet *ifp, struct IGMP_DELAYING_MEMBER; inm->inm_timer = IGMP_RANDOM_DELAY(timer); - igmp_timers_are_running = 1; + running = 1; break; case IGMP_SLEEPING_MEMBER: inm->inm_state = @@ -475,6 +475,11 @@ igmp_input_if(struct ifnet *ifp, struct } + if (running) { + membar_producer(); + atomic_store_int(&igmp_timers_are_running, running); + } + /* * Pass all valid IGMP packets up to any process(es) listening * on a raw IGMP socket. @@ -485,7 +490,7 @@ igmp_input_if(struct ifnet *ifp, struct void igmp_joingroup(struct in_multi *inm, struct ifnet *ifp) { - int i; + int i, running = 0; inm->inm_state = IGMP_IDLE_MEMBER; @@ -496,9 +501,14 @@ igmp_joingroup(struct in_multi *inm, str inm->inm_state = IGMP_DELAYING_MEMBER; inm->inm_timer = IGMP_RANDOM_DELAY( IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ); - igmp_timers_are_running = 1; + running = 1; } else inm->inm_timer = 0; + + if (running) { + membar_producer(); + atomic_store_int(&igmp_timers_are_running, running); + } } void @@ -525,6 +535,7 @@ void igmp_fasttimo(void) { struct ifnet *ifp; + int running = 0; /* * Quick check to see if any work needs to be done, in order @@ -533,23 +544,29 @@ igmp_fasttimo(void) * lock intentionally. In case it is not set due to MP races, we may * miss to check the timers. Then run the loop at next fast timeout. */ - if (!igmp_timers_are_running) + if (!atomic_load_int(&igmp_timers_are_running)) return; + membar_consumer(); NET_LOCK(); - igmp_timers_are_running = 0; - TAILQ_FOREACH(ifp, &ifnetlist, if_list) - igmp_checktimer(ifp); + TAILQ_FOREACH(ifp, &ifnetlist, if_list) { + if (igmp_checktimer(ifp)) + running = 1; + } + + membar_producer(); + atomic_store_int(&igmp_timers_are_running, running); NET_UNLOCK(); } -void +int igmp_checktimer(struct ifnet *ifp) { struct in_multi *inm; struct ifmaddr *ifma; + int running = 0; NET_ASSERT_LOCKED(); @@ -570,9 +587,11 @@ igmp_checktimer(struct ifnet *ifp) inm->inm_state = IGMP_IDLE_MEMBER; } } else { - igmp_timers_are_running = 1; + running = 1; } } + + return (running); } void Index: sys/netinet6/icmp6.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/icmp6.c,v diff -u -p -u -p -r1.254 icmp6.c --- sys/netinet6/icmp6.c 14 Jul 2024 18:53:39 -0000 1.254 +++ sys/netinet6/icmp6.c 12 Aug 2024 13:50:30 -0000 @@ -1198,7 +1198,6 @@ icmp6_reflect(struct mbuf **mp, size_t o void icmp6_fasttimo(void) { - mld6_fasttimeo(); } Index: sys/netinet6/mld6.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/netinet6/mld6.c,v diff -u -p -u -p -r1.62 mld6.c --- sys/netinet6/mld6.c 13 Feb 2024 12:22:09 -0000 1.62 +++ sys/netinet6/mld6.c 12 Aug 2024 13:50:30 -0000 @@ -85,9 +85,9 @@ #include static struct ip6_pktopts ip6_opts; -int mld6_timers_are_running; /* [N] shortcut for fast timer */ +int mld6_timers_are_running; /* [a] shortcut for fast timer */ -void mld6_checktimer(struct ifnet *); +int mld6_checktimer(struct ifnet *); static void mld6_sendpkt(struct in6_multi *, int, const struct in6_addr *); void @@ -118,6 +118,7 @@ mld6_start_listening(struct in6_multi *i { /* XXX: These are necessary for KAME's link-local hack */ struct in6_addr all_nodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + int running = 0; /* * RFC2710 page 10: @@ -138,7 +139,12 @@ mld6_start_listening(struct in6_multi *i MLD_RANDOM_DELAY(MLD_V1_MAX_RI * PR_FASTHZ); in6m->in6m_state = MLD_IREPORTEDLAST; - mld6_timers_are_running = 1; + running = 1; + } + + if (running) { + membar_producer(); + atomic_store_int(&mld6_timers_are_running, running); } } @@ -169,6 +175,7 @@ mld6_input(struct mbuf *m, int off) struct in6_multi *in6m; struct ifmaddr *ifma; int timer; /* timer value in the MLD query header */ + int running = 0; /* XXX: These are necessary for KAME's link-local hack */ struct in6_addr all_nodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; @@ -272,7 +279,7 @@ mld6_input(struct mbuf *m, int off) in6m->in6m_timer > timer) { in6m->in6m_timer = MLD_RANDOM_DELAY(timer); - mld6_timers_are_running = 1; + running = 1; } } } @@ -323,8 +330,13 @@ mld6_input(struct mbuf *m, int off) #endif break; } - if_put(ifp); + if (running) { + membar_producer(); + atomic_store_int(&mld6_timers_are_running, running); + } + + if_put(ifp); m_freem(m); } @@ -332,6 +344,7 @@ void mld6_fasttimeo(void) { struct ifnet *ifp; + int running; /* * Quick check to see if any work needs to be done, in order @@ -340,23 +353,29 @@ mld6_fasttimeo(void) * lock intentionally. In case it is not set due to MP races, we may * miss to check the timers. Then run the loop at next fast timeout. */ - if (!mld6_timers_are_running) + if (!atomic_load_int(&mld6_timers_are_running)) return; + membar_consumer(); NET_LOCK(); - mld6_timers_are_running = 0; - TAILQ_FOREACH(ifp, &ifnetlist, if_list) - mld6_checktimer(ifp); + TAILQ_FOREACH(ifp, &ifnetlist, if_list) { + if (mld6_checktimer(ifp)) + running = 1; + } + + membar_producer(); + atomic_store_int(&mld6_timers_are_running, running); NET_UNLOCK(); } -void +int mld6_checktimer(struct ifnet *ifp) { struct in6_multi *in6m; struct ifmaddr *ifma; + int running = 0; NET_ASSERT_LOCKED(); @@ -370,9 +389,11 @@ mld6_checktimer(struct ifnet *ifp) mld6_sendpkt(in6m, MLD_LISTENER_REPORT, NULL); in6m->in6m_state = MLD_IREPORTEDLAST; } else { - mld6_timers_are_running = 1; + running = 1; } } + + return (running); } static void