From patchwork Mon Sep 18 19:59:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 9957571 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.web.codeaurora.org (Postfix) with ESMTP id DB615601E9 for ; Mon, 18 Sep 2017 20:00:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA9EA28C7D for ; Mon, 18 Sep 2017 20:00:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BFB8128CEE; Mon, 18 Sep 2017 20:00:00 +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=-6.9 required=2.0 tests=BAYES_00,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 9D39628D61 for ; Mon, 18 Sep 2017 19:59:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751343AbdIRT7Y (ORCPT ); Mon, 18 Sep 2017 15:59:24 -0400 Received: from mga05.intel.com ([192.55.52.43]:7741 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750864AbdIRT7X (ORCPT ); Mon, 18 Sep 2017 15:59:23 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga105.fm.intel.com with ESMTP; 18 Sep 2017 12:59:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,414,1500966000"; d="scan'208";a="1173414493" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga001.jf.intel.com with SMTP; 18 Sep 2017 12:59:20 -0700 Received: by stinkbox (sSMTP sendmail emulation); Mon, 18 Sep 2017 22:59:19 +0300 From: Ville Syrjala To: linux-wireless@vger.kernel.org Cc: Johannes Berg , "David S. Miller" , netdev@vger.kernel.org, =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Subject: [PATCH 1/2] mac80211: Add rcu read side critical sections Date: Mon, 18 Sep 2017 22:59:18 +0300 Message-Id: <20170918195919.15860-1-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.13.5 MIME-Version: 1.0 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 From: Ville Syrjälä I got the following lockdep warning about the rcu_dereference()s in ieee80211_tx_h_select_key(). After tracing all callers of ieee80211_tx_h_select_key() I discovered that ieee80211_get_buffered_bc() and ieee80211_build_data_template() had the rcu_read_lock/unlock() but three other places did not. So I just blindly added them and made the read side critical section extend as far as the lifetime of 'tx' which is where we seem to be stuffing the rcu protected pointers. No real clue whether this is correct or not. [ 854.573700] ../net/mac80211/tx.c:594 suspicious rcu_dereference_check() usage! [ 854.573704] other info that might help us debug this: [ 854.573707] rcu_scheduler_active = 2, debug_locks = 1 [ 854.573712] 6 locks held by kworker/u2:0/2877: [ 854.573715] #0: ("%s"wiphy_name(local->hw.wiphy)){++++.+}, at: [] process_one_work+0x127/0x580 [ 854.573742] #1: ((&sdata->work)){+.+.+.}, at: [] process_one_work+0x127/0x580 [ 854.573758] #2: (&wdev->mtx){+.+.+.}, at: [] ieee80211_sta_work+0x23/0x1c70 [mac80211] [ 854.573902] #3: (&local->sta_mtx){+.+.+.}, at: [] __sta_info_flush+0x60/0x160 [mac80211] [ 854.573947] #4: (&(&txq->axq_lock)->rlock){+.-...}, at: [] ath_tx_node_cleanup+0x5c/0x180 [ath9k] [ 854.573973] #5: (&(&fq->lock)->rlock){+.-...}, at: [] ieee80211_tx_dequeue+0x24/0xa80 [mac80211] [ 854.574023] stack backtrace: [ 854.574028] CPU: 0 PID: 2877 Comm: kworker/u2:0 Not tainted 4.13.0-mgm-ovl+ #52 [ 854.574032] Hardware name: FUJITSU SIEMENS LIFEBOOK S6120/FJNB16C, BIOS Version 1.26 05/10/2004 [ 854.574070] Workqueue: phy0 ieee80211_iface_work [mac80211] [ 854.574076] Call Trace: [ 854.574086] dump_stack+0x16/0x19 [ 854.574092] lockdep_rcu_suspicious+0xcb/0xf0 [ 854.574131] ieee80211_tx_h_select_key+0x1b5/0x500 [mac80211] [ 854.574171] ieee80211_tx_dequeue+0x283/0xa80 [mac80211] [ 854.574181] ath_tid_dequeue+0x84/0xf0 [ath9k] [ 854.574189] ath_tx_node_cleanup+0xb8/0x180 [ath9k] [ 854.574199] ath9k_sta_state+0x48/0xf0 [ath9k] [ 854.574207] ? ath9k_del_ps_key.isra.19+0x60/0x60 [ath9k] [ 854.574240] drv_sta_state+0xaf/0x8c0 [mac80211] [ 854.574275] __sta_info_destroy_part2+0x10b/0x140 [mac80211] [ 854.574309] __sta_info_flush+0xd5/0x160 [mac80211] [ 854.574349] ieee80211_set_disassoc+0xd3/0x570 [mac80211] [ 854.574390] ieee80211_sta_connection_lost+0x30/0x60 [mac80211] [ 854.574431] ieee80211_sta_work+0x1ff/0x1c70 [mac80211] [ 854.574436] ? mark_held_locks+0x62/0x90 [ 854.574443] ? _raw_spin_unlock_irqrestore+0x55/0x70 [ 854.574447] ? trace_hardirqs_on_caller+0x11c/0x1a0 [ 854.574452] ? trace_hardirqs_on+0xb/0x10 [ 854.574459] ? dev_mc_net_exit+0xe/0x20 [ 854.574467] ? skb_dequeue+0x48/0x70 [ 854.574504] ieee80211_iface_work+0x2d8/0x320 [mac80211] [ 854.574509] process_one_work+0x1d1/0x580 [ 854.574513] ? process_one_work+0x127/0x580 [ 854.574519] worker_thread+0x31/0x380 [ 854.574525] kthread+0xd9/0x110 [ 854.574529] ? process_one_work+0x580/0x580 [ 854.574534] ? kthread_create_on_node+0x30/0x30 [ 854.574540] ret_from_fork+0x19/0x24 [ 854.574548] ============================= [ 854.574551] WARNING: suspicious RCU usage [ 854.574555] 4.13.0-mgm-ovl+ #52 Not tainted [ 854.574558] ----------------------------- [ 854.574561] ../net/mac80211/tx.c:608 suspicious rcu_dereference_check() usage! [ 854.574564] other info that might help us debug this: [ 854.574568] rcu_scheduler_active = 2, debug_locks = 1 [ 854.574572] 6 locks held by kworker/u2:0/2877: [ 854.574574] #0: ("%s"wiphy_name(local->hw.wiphy)){++++.+}, at: [] process_one_work+0x127/0x580 [ 854.574590] #1: ((&sdata->work)){+.+.+.}, at: [] process_one_work+0x127/0x580 [ 854.574606] #2: (&wdev->mtx){+.+.+.}, at: [] ieee80211_sta_work+0x23/0x1c70 [mac80211] [ 854.574657] #3: (&local->sta_mtx){+.+.+.}, at: [] __sta_info_flush+0x60/0x160 [mac80211] [ 854.574702] #4: (&(&txq->axq_lock)->rlock){+.-...}, at: [] ath_tx_node_cleanup+0x5c/0x180 [ath9k] [ 854.574721] #5: (&(&fq->lock)->rlock){+.-...}, at: [] ieee80211_tx_dequeue+0x24/0xa80 [mac80211] [ 854.574771] stack backtrace: [ 854.574775] CPU: 0 PID: 2877 Comm: kworker/u2:0 Not tainted 4.13.0-mgm-ovl+ #52 [ 854.574779] Hardware name: FUJITSU SIEMENS LIFEBOOK S6120/FJNB16C, BIOS Version 1.26 05/10/2004 [ 854.574814] Workqueue: phy0 ieee80211_iface_work [mac80211] [ 854.574821] Call Trace: [ 854.574825] dump_stack+0x16/0x19 [ 854.574830] lockdep_rcu_suspicious+0xcb/0xf0 [ 854.574869] ieee80211_tx_h_select_key+0x44e/0x500 [mac80211] [ 854.574908] ieee80211_tx_dequeue+0x283/0xa80 [mac80211] [ 854.574919] ath_tid_dequeue+0x84/0xf0 [ath9k] [ 854.574927] ath_tx_node_cleanup+0xb8/0x180 [ath9k] [ 854.574936] ath9k_sta_state+0x48/0xf0 [ath9k] [ 854.574945] ? ath9k_del_ps_key.isra.19+0x60/0x60 [ath9k] [ 854.574978] drv_sta_state+0xaf/0x8c0 [mac80211] [ 854.575012] __sta_info_destroy_part2+0x10b/0x140 [mac80211] [ 854.575046] __sta_info_flush+0xd5/0x160 [mac80211] [ 854.575087] ieee80211_set_disassoc+0xd3/0x570 [mac80211] [ 854.575127] ieee80211_sta_connection_lost+0x30/0x60 [mac80211] [ 854.575168] ieee80211_sta_work+0x1ff/0x1c70 [mac80211] [ 854.575173] ? mark_held_locks+0x62/0x90 [ 854.575178] ? _raw_spin_unlock_irqrestore+0x55/0x70 [ 854.575182] ? trace_hardirqs_on_caller+0x11c/0x1a0 [ 854.575187] ? trace_hardirqs_on+0xb/0x10 [ 854.575192] ? dev_mc_net_exit+0xe/0x20 [ 854.575197] ? skb_dequeue+0x48/0x70 [ 854.575233] ieee80211_iface_work+0x2d8/0x320 [mac80211] [ 854.575238] process_one_work+0x1d1/0x580 [ 854.575243] ? process_one_work+0x127/0x580 [ 854.575248] worker_thread+0x31/0x380 [ 854.575253] kthread+0xd9/0x110 [ 854.575257] ? process_one_work+0x580/0x580 [ 854.575262] ? kthread_create_on_node+0x30/0x30 [ 854.575267] ret_from_fork+0x19/0x24 Cc: Johannes Berg Cc: "David S. Miller" Cc: netdev@vger.kernel.org Signed-off-by: Ville Syrjälä --- net/mac80211/tx.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 94826680cf2b..073022ee2462 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1770,15 +1770,21 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, struct ieee80211_tx_data tx; struct sk_buff *skb2; - if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) + rcu_read_lock(); + + if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) { + rcu_read_unlock(); return false; + } info->band = band; info->control.vif = vif; info->hw_queue = vif->hw_queue[skb_get_queue_mapping(skb)]; - if (invoke_tx_handlers(&tx)) + if (invoke_tx_handlers(&tx)) { + rcu_read_unlock(); return false; + } if (sta) { if (tx.sta) @@ -1792,9 +1798,12 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, if (WARN_ON(skb2 != skb || !skb_queue_empty(&tx.skbs))) { ieee80211_free_txskb(hw, skb2); ieee80211_purge_tx_queue(hw, &tx.skbs); + rcu_read_unlock(); return false; } + rcu_read_unlock(); + return true; } EXPORT_SYMBOL(ieee80211_tx_prepare_skb); @@ -1818,14 +1827,18 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, return true; } + rcu_read_lock(); + /* initialises tx */ led_len = skb->len; res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb); if (unlikely(res_prepare == TX_DROP)) { ieee80211_free_txskb(&local->hw, skb); + rcu_read_unlock(); return true; } else if (unlikely(res_prepare == TX_QUEUED)) { + rcu_read_unlock(); return true; } @@ -1835,16 +1848,22 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; - if (invoke_tx_handlers_early(&tx)) + if (invoke_tx_handlers_early(&tx)) { + rcu_read_unlock(); return false; + } - if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb)) + if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb)) { + rcu_read_unlock(); return true; + } if (!invoke_tx_handlers_late(&tx)) result = __ieee80211_tx(local, &tx.skbs, led_len, tx.sta, txpending); + rcu_read_unlock(); + return result; } @@ -3411,6 +3430,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, ieee80211_tx_result r; struct ieee80211_vif *vif; + rcu_read_lock(); + spin_lock_bh(&fq->lock); if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags)) @@ -3513,6 +3534,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, out: spin_unlock_bh(&fq->lock); + rcu_read_unlock(); + return skb; } EXPORT_SYMBOL(ieee80211_tx_dequeue);