Search Linux Wireless

Re: [PATCH] mac80211: don't allocate mesh peer under RCU

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

 



On Tue, Oct 23, 2012 at 11:55 AM, Thomas Pedersen <thomas@xxxxxxxxxxx> wrote:
> mesh_plink_alloc() was being called with the RCU read lock held, which
> triggered warnings because various things inside this function must
> sleep. It doesn't make much sense to hold an RCU lock on a pointer we
> don't yet have anyway, so do rcu_read_unlock() if allocating and relock
> on insertion. This also means there is no need for
> cfg80211_notify_new_peer_candidate() to be atomic.
>
> Also balance the RCU lock if we are returning early.
>
> This warning was only visible with CONFIG_DEBUG_ATOMIC_SLEEP enabled.
>
> Reported-by: Bob Copeland <me@xxxxxxxxxxxxxxx>
> Signed-off-by: Thomas Pedersen <thomas@xxxxxxxxxxx>
Reviewed-by: Javier Cardona <javier@xxxxxxxxxxx>

Javier

> ---
>  net/mac80211/mesh_plink.c |   14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
> index 234fe75..427c87d 100644
> --- a/net/mac80211/mesh_plink.c
> +++ b/net/mac80211/mesh_plink.c
> @@ -346,7 +346,7 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
>         enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
>         struct ieee80211_supported_band *sband;
>         u32 rates, basic_rates = 0;
> -       struct sta_info *sta;
> +       struct sta_info *sta = NULL;
>         bool insert = false;
>
>         sband = local->hw.wiphy->bands[band];
> @@ -354,18 +354,19 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
>
>         sta = sta_info_get(sdata, addr);
>         if (!sta) {
> +               rcu_read_unlock();
>                 /* Userspace handles peer allocation when security is enabled */
>                 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
>                         cfg80211_notify_new_peer_candidate(sdata->dev, addr,
>                                                            elems->ie_start,
>                                                            elems->total_len,
> -                                                          GFP_ATOMIC);
> -                       return NULL;
> +                                                          GFP_KERNEL);
> +                       goto lock_out;
>                 }
>
>                 sta = mesh_plink_alloc(sdata, addr);
>                 if (!sta)
> -                       return NULL;
> +                       goto lock_out;
>                 insert = true;
>         }
>
> @@ -397,10 +398,13 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
>         rate_control_rate_init(sta);
>         spin_unlock_bh(&sta->lock);
>
> -       if (insert && sta_info_insert(sta))
> +       if (insert && sta_info_insert_rcu(sta))
>                 return NULL;
>
>         return sta;
> +lock_out:
> +       rcu_read_lock();
> +       return sta;
>  }
>
>  void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
> --
> 1.7.9.5
>
> _______________________________________________
> Devel mailing list
> Devel@xxxxxxxxxxxxxxxxxxxx
> http://lists.open80211s.org/cgi-bin/mailman/listinfo/devel



-- 
Javier Cardona
cozybit Inc.
http://www.cozybit.com
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux