From patchwork Wed Mar 12 14:37:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 3818281 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id AE4D6BF540 for ; Wed, 12 Mar 2014 14:37:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CC883202B4 for ; Wed, 12 Mar 2014 14:37:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 924B52027D for ; Wed, 12 Mar 2014 14:37:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754522AbaCLOho (ORCPT ); Wed, 12 Mar 2014 10:37:44 -0400 Received: from [143.182.124.21] ([143.182.124.21]:21409 "EHLO mga03.intel.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1754083AbaCLOhh (ORCPT ); Wed, 12 Mar 2014 10:37:37 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by azsmga101.ch.intel.com with ESMTP; 12 Mar 2014 07:37:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,638,1389772800"; d="scan'208";a="490533633" Received: from dubbel.iil.intel.com ([10.185.114.141]) by fmsmga001.fm.intel.com with ESMTP; 12 Mar 2014 07:37:25 -0700 From: Luciano Coelho To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, michal.kazior@tieto.com, sw@simonwunderlich.de, andrei.otcheretianski@intel.com Subject: [PATCH v8 1/4] mac80211: split ieee80211_vif_change_channel in two Date: Wed, 12 Mar 2014 16:37:18 +0200 Message-Id: <1394635041-2561-2-git-send-email-luciano.coelho@intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1394635041-2561-1-git-send-email-luciano.coelho@intel.com> References: <1394635041-2561-1-git-send-email-luciano.coelho@intel.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP ieee80211_vif_change_channel() locks chanctx_mtx. When implementing channel reservation for CS, we will need to call the function to change channel when the lock is already held, so split the part that requires the lock out and leave the locking in the original function. Signed-off-by: Luciano Coelho --- net/mac80211/chan.c | 58 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index fdbb932..ef77703 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -547,39 +547,20 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, return ret; } -int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, - u32 *changed) +static int __ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, + struct ieee80211_chanctx *ctx, + u32 *changed) { struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx_conf *conf; - struct ieee80211_chanctx *ctx; const struct cfg80211_chan_def *chandef = &sdata->csa_chandef; - int ret; u32 chanctx_changed = 0; - lockdep_assert_held(&local->mtx); - - /* should never be called if not performing a channel switch. */ - if (WARN_ON(!sdata->vif.csa_active)) - return -EINVAL; - if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, IEEE80211_CHAN_DISABLED)) return -EINVAL; - mutex_lock(&local->chanctx_mtx); - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); - if (!conf) { - ret = -EINVAL; - goto out; - } - - ctx = container_of(conf, struct ieee80211_chanctx, conf); - if (ctx->refcount != 1) { - ret = -EINVAL; - goto out; - } + if (ctx->refcount != 1) + return -EINVAL; if (sdata->vif.bss_conf.chandef.width != chandef->width) { chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH; @@ -597,7 +578,34 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, ieee80211_recalc_radar_chanctx(local, ctx); ieee80211_recalc_chanctx_min_def(local, ctx); - ret = 0; + return 0; +} + +int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, + u32 *changed) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *conf; + struct ieee80211_chanctx *ctx; + int ret; + + lockdep_assert_held(&local->mtx); + + /* should never be called if not performing a channel switch. */ + if (WARN_ON(!sdata->vif.csa_active)) + return -EINVAL; + + mutex_lock(&local->chanctx_mtx); + conf = rcu_dereference_protected(sdata->vif.chanctx_conf, + lockdep_is_held(&local->chanctx_mtx)); + if (!conf) { + ret = -EINVAL; + goto out; + } + + ctx = container_of(conf, struct ieee80211_chanctx, conf); + + ret = __ieee80211_vif_change_channel(sdata, ctx, changed); out: mutex_unlock(&local->chanctx_mtx); return ret;