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.

Reply via email to