From patchwork Wed Feb 6 18:17:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Pedersen X-Patchwork-Id: 2106031 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id A6DC4DF2A1 for ; Wed, 6 Feb 2013 18:18:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754734Ab3BFSSl (ORCPT ); Wed, 6 Feb 2013 13:18:41 -0500 Received: from mail-da0-f42.google.com ([209.85.210.42]:34526 "EHLO mail-da0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752107Ab3BFSSl (ORCPT ); Wed, 6 Feb 2013 13:18:41 -0500 Received: by mail-da0-f42.google.com with SMTP id z17so796637dal.15 for ; Wed, 06 Feb 2013 10:18:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=fPJIW//R6gEEi0ZZ120yb9+83zZN28QZuBbbhr+lL7Q=; b=JZHuRh1hn4AxZC2CP/mzcAEdAG5kig7DTAGhivrKejHGqN9cOaws3GtUPHyYz5SWwf JptBy0Opmt7vhSSrU4wx0S/nC9KEqkxxFugfg7+0d2DyKhdJhgHC35pKXw5zcbbljnj4 waVbPhR3KMZf4iwFkJ4FoO7TEMB8p0cFtzvLY9g0ZbqhVgS0xoAr/5E5w3l/kGuakG7H hFSbz3zPYRE1FWFUrXMqzjNYKxXq6mL/4KM8yG8gGMfo5Wvar6wOlvmJMchEh0Y7p469 wKxkSwHSvWQebrmvl8bUN+XosIqWelknPwZGFMXeOdfTQQFIc/a4S87gB0/ML3ng9Nz9 SzYA== X-Received: by 10.66.79.97 with SMTP id i1mr78174288pax.47.1360174720555; Wed, 06 Feb 2013 10:18:40 -0800 (PST) Received: from cable.lan (70-35-43-50.static.wiline.com. [70.35.43.50]) by mx.google.com with ESMTPS id bi8sm39504257pab.15.2013.02.06.10.18.38 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 06 Feb 2013 10:18:39 -0800 (PST) From: Thomas Pedersen To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, devel@lists.open80211s.org, Thomas Pedersen Subject: [PATCH v2] mac80211: fix mesh sta teardown Date: Wed, 6 Feb 2013 10:17:21 -0800 Message-Id: <1360174641-18347-1-git-send-email-thomas@cozybit.com> X-Mailer: git-send-email 1.7.10.4 X-Gm-Message-State: ALoCoQnhoYNtbTfjJaEliPGIJrpCnuD/A/YGwkdLu4BXoNyZB+gi6nIbxRSW1Ludjl8G5qCBokhV Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The patch "mac80211: clean up mesh sta allocation warning" moved some mesh initialization into a path which is only called when the kernel handles peering. This causes a hang when mac80211 tries to clean up a userspace-allocated station entry and delete a timer which has never been initialized. To avoid this, only do any mesh sta peering teardown if the kernel is actually handling it. The same is true when quiescing before suspend. Signed-off-by: Thomas Pedersen --- v2: add another check to mesh_plink_quiesce() net/mac80211/mesh.c | 25 +++++++++++++++++++++++++ net/mac80211/mesh.h | 4 +++- net/mac80211/mesh_plink.c | 8 ++++++-- net/mac80211/sta_info.c | 9 ++------- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 35ac388..0c51b78 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -149,6 +149,31 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) return changed; } +/* + * mesh_sta_cleanup - clean up any mesh sta state + * + * @sta: mesh sta to clean up. + */ +void mesh_sta_cleanup(struct sta_info *sta) +{ + struct ieee80211_sub_if_data *sdata = sta->sdata; + u32 changed; + + /* + * maybe userspace handles peer allocation and peering, but in either + * case the beacon is still generated by the kernel and we might need + * an update. + */ + changed = mesh_accept_plinks_update(sdata); + if (sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { + changed |= mesh_plink_deactivate(sta); + del_timer_sync(&sta->plink_timer); + } + + if (changed) + ieee80211_bss_info_change_notify(sdata, changed); +} + int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) { int i; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index eb33625..e5f6095 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -288,12 +288,13 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); void mesh_plink_broken(struct sta_info *sta); -void mesh_plink_deactivate(struct sta_info *sta); +u32 mesh_plink_deactivate(struct sta_info *sta); int mesh_plink_open(struct sta_info *sta); void mesh_plink_block(struct sta_info *sta); void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status); +void mesh_sta_cleanup(struct sta_info *sta); /* Private interfaces */ /* Mesh tables */ @@ -380,6 +381,7 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) { return false; } static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) {} +static inline void mesh_sta_cleanup(struct sta_info *sta) {} #endif #endif /* IEEE80211S_H */ diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 67524e7..56c9b31 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -214,7 +214,7 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta) * * All mesh paths with this peer as next hop will be flushed */ -void mesh_plink_deactivate(struct sta_info *sta) +u32 mesh_plink_deactivate(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; u32 changed; @@ -227,7 +227,7 @@ void mesh_plink_deactivate(struct sta_info *sta) sta->reason); spin_unlock_bh(&sta->lock); - ieee80211_bss_info_change_notify(sdata, changed); + return changed; } static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, @@ -595,6 +595,10 @@ void mesh_plink_quiesce(struct sta_info *sta) if (!ieee80211_vif_is_mesh(&sta->sdata->vif)) return; + /* no kernel mesh sta timers have been initialized */ + if (sta->sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE) + return; + if (del_timer_sync(&sta->plink_timer)) sta->plink_timer_was_running = true; } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 47a0f06..19db20a 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -137,13 +137,8 @@ static void cleanup_single_sta(struct sta_info *sta) ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); } -#ifdef CONFIG_MAC80211_MESH - if (ieee80211_vif_is_mesh(&sdata->vif)) { - mesh_accept_plinks_update(sdata); - mesh_plink_deactivate(sta); - del_timer_sync(&sta->plink_timer); - } -#endif + if (ieee80211_vif_is_mesh(&sdata->vif)) + mesh_sta_cleanup(sta); cancel_work_sync(&sta->drv_unblock_wk);