reads OK
On 2021-12-04 20:40 +01, Stefan Sperling <s...@openbsd.org> wrote: > On Sat, Dec 04, 2021 at 09:32:40PM +0300, Vitaliy Makkoveev wrote: >> I think rtm_80211info() could follow the if_link_state_change() >> way and use task for that. > > Indeed. I did not realize that if_link_state_change() schedules a task. > > This means ieee80211_set_link_state() is already deferring some of its > work to a task. The patch below defers sending the 80211info message > to a task as well. > > I am keeping things simple for now and use systq (kernel-locked) instead > of copying the argument-passing approach used by if_link_state_change(). > > Tested on iwm(4) 8265 with 'route monitor'. > > ok? > > diff 0b61c8235787960f0010ef627ea5b2c6309a81f0 > de98c050ea709bdb8e26be40ab0cc82ef9afed80 > blob - 7bb68194dd78417b06c59f81d1ebbff4165203d8 > blob + 5b9a969258074fde29e21a33ac035cf170ec3b03 > --- sys/net80211/ieee80211.c > +++ sys/net80211/ieee80211.c > @@ -193,6 +193,7 @@ ieee80211_ifattach(struct ifnet *ifp) > if_addgroup(ifp, "wlan"); > ifp->if_priority = IF_WIRELESS_DEFAULT_PRIORITY; > > + task_set(&ic->ic_rtm_80211info_task, ieee80211_rtm_80211info_task, ic); > ieee80211_set_link_state(ic, LINK_STATE_DOWN); > > timeout_set(&ic->ic_bgscan_timeout, ieee80211_bgscan_timeout, ifp); > @@ -203,6 +204,7 @@ ieee80211_ifdetach(struct ifnet *ifp) > { > struct ieee80211com *ic = (void *)ifp; > > + task_del(systq, &ic->ic_rtm_80211info_task); > timeout_del(&ic->ic_bgscan_timeout); > > /* > blob - 447a2676bfb250b7f917206549679d6ae68de1f6 > blob + 7e10fc1336067542c13d5607602e658ce2b3926b > --- sys/net80211/ieee80211_proto.c > +++ sys/net80211/ieee80211_proto.c > @@ -1288,6 +1288,31 @@ justcleanup: > } > > void > +ieee80211_rtm_80211info_task(void *arg) > +{ > + struct ieee80211com *ic = arg; > + struct ifnet *ifp = &ic->ic_if; > + struct if_ieee80211_data ifie; > + int s = splnet(); > + > + if (LINK_STATE_IS_UP(ifp->if_link_state)) { > + memset(&ifie, 0, sizeof(ifie)); > + ifie.ifie_nwid_len = ic->ic_bss->ni_esslen; > + memcpy(ifie.ifie_nwid, ic->ic_bss->ni_essid, > + sizeof(ifie.ifie_nwid)); > + memcpy(ifie.ifie_addr, ic->ic_bss->ni_bssid, > + sizeof(ifie.ifie_addr)); > + ifie.ifie_channel = ieee80211_chan2ieee(ic, > + ic->ic_bss->ni_chan); > + ifie.ifie_flags = ic->ic_flags; > + ifie.ifie_xflags = ic->ic_xflags; > + rtm_80211info(&ic->ic_if, &ifie); > + } > + > + splx(s); > +} > + > +void > ieee80211_set_link_state(struct ieee80211com *ic, int nstate) > { > struct ifnet *ifp = &ic->ic_if; > @@ -1307,20 +1332,8 @@ ieee80211_set_link_state(struct ieee80211com *ic, int > } > if (nstate != ifp->if_link_state) { > ifp->if_link_state = nstate; > - if (LINK_STATE_IS_UP(nstate)) { > - struct if_ieee80211_data ifie; > - memset(&ifie, 0, sizeof(ifie)); > - ifie.ifie_nwid_len = ic->ic_bss->ni_esslen; > - memcpy(ifie.ifie_nwid, ic->ic_bss->ni_essid, > - sizeof(ifie.ifie_nwid)); > - memcpy(ifie.ifie_addr, ic->ic_bss->ni_bssid, > - sizeof(ifie.ifie_addr)); > - ifie.ifie_channel = ieee80211_chan2ieee(ic, > - ic->ic_bss->ni_chan); > - ifie.ifie_flags = ic->ic_flags; > - ifie.ifie_xflags = ic->ic_xflags; > - rtm_80211info(&ic->ic_if, &ifie); > - } > + if (LINK_STATE_IS_UP(nstate)) > + task_add(systq, &ic->ic_rtm_80211info_task); > if_link_state_change(ifp); > } > } > blob - 7208e5dc0be1983a31d7f74142e87581bea95d13 > blob + ce6d1ad91f391cb16c7f0bbfa79210401d5dc7eb > --- sys/net80211/ieee80211_proto.h > +++ sys/net80211/ieee80211_proto.h > @@ -63,6 +63,7 @@ extern void ieee80211_proto_detach(struct ifnet *); > struct ieee80211_node; > struct ieee80211_rxinfo; > struct ieee80211_rsnparams; > +extern void ieee80211_rtm_80211info_task(void *); > extern void ieee80211_set_link_state(struct ieee80211com *, int); > extern u_int ieee80211_get_hdrlen(const struct ieee80211_frame *); > extern int ieee80211_classify(struct ieee80211com *, struct mbuf *); > blob - dd17ed76031db17bd86cd75a5c1eec659dbd3f30 > blob + 641419331ed3f65fbc9272c055948438b28f1025 > --- sys/net80211/ieee80211_var.h > +++ sys/net80211/ieee80211_var.h > @@ -306,6 +306,7 @@ struct ieee80211com { > struct timeout ic_inact_timeout; /* node inactivity timeout */ > struct timeout ic_node_cache_timeout; > #endif > + struct task ic_rtm_80211info_task; > int ic_des_esslen; > u_int8_t ic_des_essid[IEEE80211_NWID_LEN]; > struct ieee80211_channel *ic_des_chan; /* desired channel */ > > -- I'm not entirely sure you are real.