From patchwork Sun Mar 9 20:06:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Goode X-Patchwork-Id: 328394 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 8DC622C0091 for ; Mon, 10 Mar 2014 07:08:46 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752349AbaCIUHL (ORCPT ); Sun, 9 Mar 2014 16:07:11 -0400 Received: from mail-la0-f45.google.com ([209.85.215.45]:57309 "EHLO mail-la0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750962AbaCIUHI (ORCPT ); Sun, 9 Mar 2014 16:07:08 -0400 Received: by mail-la0-f45.google.com with SMTP id hr17so4165172lab.32 for ; Sun, 09 Mar 2014 13:07:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=oKQMMqWfZCrNaDiO3mg0XoXYwi4A6aXtyYgFfjHV8Ds=; b=pqSY9GnxS51sdMH20LyO/+X8+eLDVLT/ebbAzAzcBHsuKa7q6klqb4r7ZJuL6vEffQ naynCyo7tlx9sqDAh4p53c19+H5tZ0IDlcpDKtChNiLb/R1SfBlrazpe+KfjgIqt6viK UN1EUni4asBX0YKwAb7KFEqtgUjg9fFGUfBq1BrF05HCgRmehZcxQgT1jHOzcDkUzvuW 0g2ai944vE0ySj/8iyy97FhfAGQsh0/qLeQZtGG0SvCbXtAH5qzO/6okFjUeV528x/NZ r/dcPmH11cdsbIlF4u5qhUBO4+BjXsv6UdEcX9OX0oI7dzGGv8Ee2Kym3iWZCfUqT7JD wRVA== X-Received: by 10.152.6.199 with SMTP id d7mr21052193laa.22.1394395625512; Sun, 09 Mar 2014 13:07:05 -0700 (PDT) Received: from lianli.example.org (c193-14-149-135.cust.tele2.se. [193.14.149.135]) by mx.google.com with ESMTPSA id wv4sm10164678lbb.10.2014.03.09.13.07.03 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 09 Mar 2014 13:07:04 -0700 (PDT) From: Emil Goode To: Brett Rudley , Arend van Spriel , "Franky (Zhenhui) Lin" , Hante Meuleman , "John W. Linville" , Hauke Mehrtens , Johannes Berg , "Luis R. Rodriguez" Cc: linux-wireless@vger.kernel.org, brcm80211-dev-list@broadcom.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Emil Goode Subject: [PATCH 1/2] brcmsmac: fix deadlock on missing firmware Date: Sun, 9 Mar 2014 21:06:51 +0100 Message-Id: <1394395612-3510-1-git-send-email-emilgoode@gmail.com> X-Mailer: git-send-email 1.7.10.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When brcm80211 firmware is not installed networking hangs. A deadlock happens because we call ieee80211_unregister_hw() from the .start callback of struct ieee80211_ops. When .start is called we are under rtnl lock and ieee80211_unregister_hw() tries to take it again. Function call stack: dev_change_flags() __dev_change_flags() __dev_open() ASSERT_RTNL() <-- Assert rtnl lock ops->ndo_open() .ndo_open = ieee80211_open, ieee80211_open() ieee80211_do_open() drv_start() local->ops->start() .start = brcms_ops_start, brcms_ops_start() brcms_remove() ieee80211_unregister_hw() rtnl_lock() <-- Here we deadlock Introduced by: commit 25b5632fb35ca61b8ae3eee235edcdc2883f7a5e ("brcmsmac: request firmware in .start() callback") This patch fixes the bug by removing the call to brcms_remove() and moves the brcms_request_fw() call to the top of the .start callback to not initiate anything unless firmware is installed. Signed-off-by: Emil Goode --- drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 925034b..93598cd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -426,6 +426,12 @@ static int brcms_ops_start(struct ieee80211_hw *hw) bool blocked; int err; + if (!wl->ucode.bcm43xx_bomminor) { + err = brcms_request_fw(wl, wl->wlc->hw->d11core); + if (err) + return -ENOENT; + } + ieee80211_wake_queues(hw); spin_lock_bh(&wl->lock); blocked = brcms_rfkill_set_hw_state(wl); @@ -433,14 +439,6 @@ static int brcms_ops_start(struct ieee80211_hw *hw) if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - if (!wl->ucode.bcm43xx_bomminor) { - err = brcms_request_fw(wl, wl->wlc->hw->d11core); - if (err) { - brcms_remove(wl->wlc->hw->d11core); - return -ENOENT; - } - } - spin_lock_bh(&wl->lock); /* avoid acknowledging frames before a non-monitor device is added */ wl->mute_tx = true;