On Tue, Mar 22, 2016 at 09:25:43AM -0400, Bob Copeland wrote:
> On Tue, Mar 22, 2016 at 09:01:24AM -0400, Bob Copeland wrote:
> > I gave it some testing between an ath9k and ath9k_htc node this morning
> > and did not hit a crash, but I did find an issue reported by lockdep:
> 
> Spoke too soon, I can reproduce this here now.

This fixes it for me:

From: Bob Copeland <[email protected]>
Date: Tue, 22 Mar 2016 23:06:45 -0400
Subject: [PATCH] mac80211: mesh: fix cleanup for mesh pathtable

The mesh path table needs to be around for the entire time the
interface is in mesh mode, as users can perform an mpath dump
at any time.  The existing path table lifetime is instead tied
to the mesh BSS which can cause crashes when different MBSSes
are joined in the context of a single interface, or when the
path table is dumped when no MBSS is joined.

Introduce a new function to perform the final teardown of the
interface and perform path table cleanup there.  We already free
the individual path elements when the leaving the mesh.

Signed-off-by: Bob Copeland <[email protected]>
---
 net/mac80211/iface.c | 2 +-
 net/mac80211/mesh.c  | 7 ++++++-
 net/mac80211/mesh.h  | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 453b4e741780..097ece8b5c02 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1093,7 +1093,7 @@ static void ieee80211_teardown_sdata(struct 
ieee80211_sub_if_data *sdata)
        sdata->fragment_next = 0;
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
-               mesh_rmc_free(sdata);
+               ieee80211_mesh_teardown_sdata(sdata);
 }
 
 static void ieee80211_uninit(struct net_device *dev)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 1a2aaf461e98..dcc1facc807c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -905,7 +905,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data 
*sdata)
        /* flush STAs and mpaths on this iface */
        sta_info_flush(sdata);
        mesh_path_flush_by_iface(sdata);
-       mesh_pathtbl_unregister(sdata);
 
        /* free all potentially still buffered group-addressed frames */
        local->total_ps_buffered -= skb_queue_len(&ifmsh->ps.bc_buf);
@@ -1403,3 +1402,9 @@ void ieee80211_mesh_init_sdata(struct 
ieee80211_sub_if_data *sdata)
 
        sdata->vif.bss_conf.bssid = zero_addr;
 }
+
+void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata)
+{
+       mesh_rmc_free(sdata);
+       mesh_pathtbl_unregister(sdata);
+}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index f298987228c9..26b9ccbe1fce 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -219,6 +219,7 @@ void ieee80211s_init(void);
 void ieee80211s_update_metric(struct ieee80211_local *local,
                              struct sta_info *sta, struct sk_buff *skb);
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata);
 int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
 void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
-- 
2.6.1


-- 
Bob Copeland %% http://bobcopeland.com/
_______________________________________________
Devel mailing list
[email protected]
http://lists.open80211s.org/mailman/listinfo/devel

Reply via email to