From patchwork Thu Jun 13 11:21:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Matyukevich X-Patchwork-Id: 10992301 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6EA0215E6 for ; Thu, 13 Jun 2019 15:29:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5B9A0212DB for ; Thu, 13 Jun 2019 15:29:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4FB2521C9A; Thu, 13 Jun 2019 15:29:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 249BC219AC for ; Thu, 13 Jun 2019 15:29:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731132AbfFMP3f (ORCPT ); Thu, 13 Jun 2019 11:29:35 -0400 Received: from mail-eopbgr740050.outbound.protection.outlook.com ([40.107.74.50]:48048 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728861AbfFMLYE (ORCPT ); Thu, 13 Jun 2019 07:24:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quantenna.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3lk/vuAZF7oO7f2eJE+rZB4+fsRJ4dIavidYbN7D8lc=; b=PLcGC/W9flXvkCaXAMDU5AFvoJFtDuv8l7Zf7h9cr63NgCWJUr1gyUyWae6lhEp2osSB2+y2mALYZeSzly4HYPjBdE/ac9GPjOaLKSSHoDl2wan1mLt3imR7VDEzqf5fEMY+GtKZ6trdu6CrIdtXi/o+vZpTX7lFQadUCglrqQI= Received: from BN6PR05MB2946.namprd05.prod.outlook.com (10.173.19.143) by BN6PR05MB3140.namprd05.prod.outlook.com (10.172.147.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1987.10; Thu, 13 Jun 2019 11:22:03 +0000 Received: from BN6PR05MB2946.namprd05.prod.outlook.com ([fe80::c5c4:3ecc:8bd5:4d58]) by BN6PR05MB2946.namprd05.prod.outlook.com ([fe80::c5c4:3ecc:8bd5:4d58%3]) with mapi id 15.20.2008.002; Thu, 13 Jun 2019 11:22:03 +0000 Received: from SN6PR05MB4928.namprd05.prod.outlook.com (52.135.117.74) by SN6PR05MB4256.namprd05.prod.outlook.com (52.135.73.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1987.10; Thu, 13 Jun 2019 11:21:40 +0000 Received: from SN6PR05MB4928.namprd05.prod.outlook.com ([fe80::a902:576c:72d6:b358]) by SN6PR05MB4928.namprd05.prod.outlook.com ([fe80::a902:576c:72d6:b358%5]) with mapi id 15.20.2008.002; Thu, 13 Jun 2019 11:21:40 +0000 From: Sergey Matyukevich To: "linux-wireless@vger.kernel.org" CC: Johannes Berg , Igor Mitsyanko , Mikhail Karpenko , Sergey Matyukevich Subject: [RFC PATCH] cfg80211: fix duplicated scan entries after channel switch Thread-Topic: [RFC PATCH] cfg80211: fix duplicated scan entries after channel switch Thread-Index: AQHVIdor2pKU2TPLDEKkmFBmH5mjfg== Date: Thu, 13 Jun 2019 11:21:40 +0000 Message-ID: <20190613112128.834-1-sergey.matyukevich.os@quantenna.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR02CA0041.namprd02.prod.outlook.com (2603:10b6:a03:54::18) To SN6PR05MB4928.namprd05.prod.outlook.com (2603:10b6:805:9d::10) authentication-results: spf=none (sender IP is ) smtp.mailfrom=sergey.matyukevich.os@quantenna.com; x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.11.0 x-originating-ip: [195.182.157.78] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: c89e9ace-dde8-4329-b38c-08d6eff14ddc x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600148)(711020)(4605104)(1401327)(2017052603328)(7193020);SRVR:SN6PR05MB4256; x-ms-traffictypediagnostic: SN6PR05MB4256:|BN6PR05MB3140: x-moderation-data: 6/13/2019 11:22:01 AM x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:4502; x-forefront-prvs: 0067A8BA2A x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(39850400004)(346002)(136003)(396003)(376002)(366004)(189003)(199004)(81166006)(7736002)(8936002)(6512007)(73956011)(66446008)(64756008)(66556008)(99286004)(54906003)(2906002)(66946007)(52116002)(316002)(103116003)(5640700003)(50226002)(6486002)(68736007)(305945005)(6436002)(107886003)(66476007)(6916009)(81156014)(8676002)(53936002)(14454004)(71200400001)(6506007)(386003)(25786009)(71190400001)(86362001)(4326008)(186003)(2616005)(2501003)(26005)(256004)(3846002)(14444005)(66066001)(486006)(102836004)(436003)(478600001)(476003)(6116002)(36756003)(5660300002)(1076003)(2351001);DIR:OUT;SFP:1101;SCL:1;SRVR:BN6PR05MB3140;H:BN6PR05MB2946.namprd05.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: quantenna.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 3+yavuC01qrqEaNlsQUbQ1+ncmw6l+lgU5iUKvS1b44ZrNfplZnkAVIHEqJA4dsozN1FkG2rK16rLsB9NssFy5vCWYaPNA3wtoFOyP3c2BJ8hwb9T5G4vzbvC+D2sJDHpZkqBTRCzywC9GfFAfAbOiM7n6P9B8QElASluQ/n57C3YtgpuaMOMKUyMjF1dEqyMx7fU9b4hYUhIFhPl7gkiotOyj0wc3a8svznJ38mskdF05VYkY0BcKLkmJDcuh21n2cnd+XXGEEOHSTMHKyf3ko1m/i8HN2Ihaa5mIZ/niC2wP+aRxCFvhQp1okdYQ38KMz9KpAhE+AtKZR6b7jsxKqJ2dCP4am+yf+jwQ8+kbJJhmnDzBYuvjQgtrbG5KolSEDJuuY47NOHRuTQJsiK6Qw2+8WWieSPOi0xH61uDHI= MIME-Version: 1.0 X-OriginatorOrg: quantenna.com X-MS-Exchange-CrossTenant-Network-Message-Id: c89e9ace-dde8-4329-b38c-08d6eff14ddc X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a355dbce-62b4-4789-9446-c1d5582180ff X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: SPO_Arbitration_b0b286b7-f867-4773-abab-9aa7f1e88f6f@quantenna.onmicrosoft.com X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Jun 2019 11:22:03.5752 (UTC) X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR05MB3140 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When associated BSS completes channel switch procedure, its channel record needs to be updated. The existing mac80211 solution was extended to cfg80211 in commit 5dc8cdce1d72 ("mac80211/cfg80211: update bss channel on channel switch") However this solution appears to be incomplete as it may lead to duplicated scan entries for associated BSS after channel switch. The root cause of the problem is as follows. Each BSS entry is included into the following data structures: - bss list rdev->bss_list - bss search tree rdev->bss_tree Updating BSS channel record without rebuilding bss_tree may break tree search since cmp_bss considers all of the following: channel, bssid, ssid. When BSS channel is updated, but its location in bss_tree is not updated, then subsequent search operations may fail to locate this BSS since they will be traversing bss_tree in wrong direction. As a result, for scan performed after associated BSS channel switch, cfg80211_bss_update may add the second entry for the same BSS to both bss_list and bss_tree, rather then update the existing one. To summarize, if BSS channel needs to be updated, then bss_tree should be rebuilt in order to put updated BSS entry into a proper location. This commit suggests the following straightforward solution: - if new entry has been already created for BSS after channel switch, then remove it completely - use rb_erase/rb_insert_bss reinstall updated BSS in bss_tree Finally, next scan operation will find BSS entry in expected location in rb_tree. So all the IEs, including HT/VHT operation IEs, will be properly updated. Signed-off-by: Sergey Matyukevich --- Misc notes. 1. Tested using iwlwifi and qtnfmac drivers, looks good 2. Alternative approach: remove old BSS entry and keep new a one This approach may have certain benefits for mac80211 drivers. For instance, in this case HT/VHT operation IEs are going to be valid from the start, no need to wait for the next scan. However the following procedure for replacing current_bss, protected by wdev->mtx and rdev->bss_lock locks, seems to be insufficient: bss_ref_get(rdev, new); cfg80211_hold_bss(new); wdev->current_bss = new; cfg80211_unhold_bss(old); bss_ref_put(rdev, old); __cfg80211_unlink_bss(rdev, old); When testing this alternative approach using iwlwifi driver, occasional general protection fault crashes have been observed on ieee80211_rx_mgmt_beacon/ieee80211_bss_info_update code paths. So far I haven't yet root caused them. --- net/wireless/core.h | 2 ++ net/wireless/nl80211.c | 5 +++-- net/wireless/scan.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/net/wireless/core.h b/net/wireless/core.h index 84d36ca7a7ab..763edce6b34f 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -306,6 +306,8 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy); void cfg80211_bss_expire(struct cfg80211_registered_device *rdev); void cfg80211_bss_age(struct cfg80211_registered_device *rdev, unsigned long age_secs); +void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, + struct ieee80211_channel *channel); /* IBSS */ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c391b560d986..b3b13131e42e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -15971,8 +15971,9 @@ void cfg80211_ch_switch_notify(struct net_device *dev, wdev->preset_chandef = *chandef; if (wdev->iftype == NL80211_IFTYPE_STATION && - !WARN_ON(!wdev->current_bss)) - wdev->current_bss->pub.channel = chandef->chan; + !WARN_ON(!wdev->current_bss)) { + cfg80211_update_assoc_bss_entry(wdev, chandef->chan); + } nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL, NL80211_CMD_CH_SWITCH_NOTIFY, 0); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index c04f5451f89b..9a16c42296d0 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1972,6 +1972,51 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) } EXPORT_SYMBOL(cfg80211_unlink_bss); +void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, + struct ieee80211_channel *chan) +{ + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + struct cfg80211_internal_bss *cbss = wdev->current_bss; + struct cfg80211_internal_bss *new = NULL; + struct cfg80211_internal_bss *bss; + + spin_lock_bh(&rdev->bss_lock); + + if (WARN_ON(cbss->pub.channel == chan)) + goto done; + + cbss->pub.channel = chan; + cbss->ts = jiffies; + + list_for_each_entry(bss, &rdev->bss_list, list) { + if (!cfg80211_bss_type_match(bss->pub.capability, + bss->pub.channel->band, + wdev->conn_bss_type)) + continue; + + if (bss == cbss) + continue; + + if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) { + new = bss; + break; + } + } + + if (new) { + WARN_ON(atomic_read(&new->hold)); + WARN_ON(!__cfg80211_unlink_bss(rdev, new)); + } + + rb_erase(&cbss->rbn, &rdev->bss_tree); + rb_insert_bss(rdev, cbss); + rdev->bss_generation++; + +done: + spin_unlock_bh(&rdev->bss_lock); +} + #ifdef CONFIG_CFG80211_WEXT static struct cfg80211_registered_device * cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)