From patchwork Sat Jan 24 08:30:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 5698761 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9C2DB9F305 for ; Sat, 24 Jan 2015 08:30:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BB31C2026F for ; Sat, 24 Jan 2015 08:30:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BCBD320268 for ; Sat, 24 Jan 2015 08:30:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751904AbbAXIaR (ORCPT ); Sat, 24 Jan 2015 03:30:17 -0500 Received: from dedo.coelho.fi ([88.198.205.34]:56350 "EHLO dedo.coelho.fi" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1750913AbbAXIaQ (ORCPT ); Sat, 24 Jan 2015 03:30:16 -0500 Received: from a88-113-225-236.elisa-laajakaista.fi ([88.113.225.236] helo=dubbel.amr.corp.intel.com) by dedo.coelho.fi with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA256:128) (Exim 4.80) (envelope-from ) id 1YEw6f-00052q-Vt; Sat, 24 Jan 2015 10:30:14 +0200 From: Luca Coelho To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org Date: Sat, 24 Jan 2015 10:30:02 +0200 Message-Id: <1422088202-31871-1-git-send-email-luca@coelho.fi> X-Mailer: git-send-email 2.1.4 X-SA-Exim-Connect-IP: 88.113.225.236 X-SA-Exim-Mail-From: luca@coelho.fi X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Subject: [PATCH] mac80211: handle potential race between suspend and scan completion X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on dedo.coelho.fi) 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: Luciano Coelho If suspend starts while ieee80211_scan_completed() is running, between the point where SCAN_COMPLETED is set and the work is queued, ieee80211_scan_cancel() will not catch the work and we may finish suspending before the work is actually executed, leaving the scan running while suspended. To fix this race, queue the scan work during resume if the SCAN_COMPLETED flag is set and flush it immediately. Signed-off-by: Luciano Coelho --- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/util.c | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index bdb3e3b..3afe368 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1752,7 +1752,8 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw) { struct ieee80211_local *local = hw_to_local(hw); - WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) && + !test_bit(SCAN_COMPLETED, &local->scanning), "%s: resume with hardware scan still in progress\n", wiphy_name(hw->wiphy)); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c65d03f..8428f4a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2060,6 +2060,18 @@ int ieee80211_reconfig(struct ieee80211_local *local) mb(); local->resuming = false; + /* It's possible that we don't handle the scan completion in + * time during suspend, so if it's still marked as completed + * here, queue the work and flush it to clean things up. + * Instead of calling the worker function directly here, we + * really queue it to avoid potential races with other flows + * scheduling the same work. + */ + if (test_bit(SCAN_COMPLETED, &local->scanning)) { + ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); + flush_delayed_work(&local->scan_work); + } + if (local->open_count && !reconfig_due_to_wowlan) drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);