Search Linux Wireless

Re: [PATCH v2 13/21] wifi: rtl8xxxu: support multiple interfaces in watchdog_callback()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2023-12-22 at 09:25 +0100, Martin Kaistra wrote:
> 
> Am 22.12.23 um 09:05 schrieb Martin Kaistra:
> > Am 22.12.23 um 02:45 schrieb Ping-Ke Shih:
> > > On Fri, Dec 22, 2023 at 12:45 AM Martin Kaistra
> > > <martin.kaistra@xxxxxxxxxxxxx> wrote:
> > > > Check first whether priv->vifs[0] exists and is of type STATION, then go
> > > > to priv->vifs[1]. Make sure to call refresh_rate_mask for both
> > > > interfaces.
> > > > 
> > > > Signed-off-by: Martin Kaistra <martin.kaistra@xxxxxxxxxxxxx>
> > > > ---
> > > >   .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 19 +++++++++++--------
> > > >   1 file changed, 11 insertions(+), 8 deletions(-)
> > > > 
> > > > diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> > > > b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> > > > index c5b71892369c9..fd0108668bcda 100644
> > > > --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> > > > +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> > > > @@ -7200,11 +7200,15 @@ static void rtl8xxxu_watchdog_callback(struct
> > > > work_struct *work)
> > > >   {
> > > >          struct ieee80211_vif *vif;
> > > >          struct rtl8xxxu_priv *priv;
> > > > +       int i;
> > > > 
> > > >          priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
> > > > -       vif = priv->vif;
> > > > +       for (i = 0; i < ARRAY_SIZE(priv->vifs); i++) {
> > > > +               vif = priv->vifs[i];
> > > > +
> > > > +               if (!vif || vif->type != NL80211_IFTYPE_STATION)
> > > > +                       continue;
> > > 
> > > Currently, this loop becomes to get RSSI and update rate mask, but only for
> > > station mode. That means we don't update them for peer stations in AP mode.
> > > Maybe, we need ieee80211_iterate_stations_atomic() for all stations, but
> > > ieee80211_ave_rssi() is only for 'vif', so we need to add a driver level
> > > RSSI for all stations (macid). Also, we need to extend priv->rssi_level for
> > > all macid as well.
> > > 
> > > I suppose _default_ value can work to stations in AP mode, so you can decide
> > > if you will defer this support temporarily.
> > > 
> > > (Sorry, I don't dig rtl8xxxu very deeply, so I'm not able to tell you all
> > > things in one go.)
> > 
> > It probably makes sense to fix this, however if it's ok for you, I would like to
> > do it separatly from this series.

Ok to me. :-)

> > 
> > 
> > > > -       if (vif && vif->type == NL80211_IFTYPE_STATION) {
> > > >                  int signal;
> > > >                  struct ieee80211_sta *sta;
> > > > 
> > > > @@ -7215,22 +7219,21 @@ static void rtl8xxxu_watchdog_callback(struct
> > > > work_struct *work)
> > > > 
> > > >                          dev_dbg(dev, "%s: no sta found\n", __func__);
> > > >                          rcu_read_unlock();
> > > > -                       goto out;
> > > > +                       continue;
> > > >                  }
> > > >                  rcu_read_unlock();
> > > > 
> > > >                  signal = ieee80211_ave_rssi(vif);
> > > > 
> > > > -               priv->fops->report_rssi(priv, 0,
> > > > +               priv->fops->report_rssi(priv, rtl8xxxu_get_macid(priv, sta),
> > > >                                          rtl8xxxu_signal_to_snr(signal));
> > > > 
> > > > -               if (priv->fops->set_crystal_cap)
> > > > -                       rtl8xxxu_track_cfo(priv);
> > > > -
> > > >                  rtl8xxxu_refresh_rate_mask(priv, signal, sta, false);
> > > 
> > > It seems like 'sta' isn't protected by RCU read lock.
> > > (an existing bug, not introduced by this patch)
> > 
> > I will add a patch which moves the rcu_read_unlock() to fix this.
> 
> Actually, looking at the code again, rtl8xxxu_refresh_rate_mask() seems to
> already contain calls to rcu_read_lock(). Just the call to
> rtl8xxxu_get_macid(priv, sta) in there might need additional protection.
> 


We must use RCU lock to protect 'sta' from dereference to whole access, but
it looks like

rtl8xxxu_watchdog_callback()

	rcu_read_lock();
	sta = ...
	rcu_read_unlock() // after this point, use 'sta' is unsafe..

	rtl8xxxu_refresh_rate_mask(sta)
		rcu_read_lock();
		rate_bitmap = sta->... 
		rcu_read_unlock();










[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux