From patchwork Wed Apr 2 20:32:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seth Forshee X-Patchwork-Id: 336467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 380DD14012D for ; Thu, 3 Apr 2014 07:32:42 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WVRps-0007Tf-FR; Wed, 02 Apr 2014 20:32:36 +0000 Received: from mail-oa0-f51.google.com ([209.85.219.51]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WVRpm-0007SC-EL for kernel-team@lists.ubuntu.com; Wed, 02 Apr 2014 20:32:30 +0000 Received: by mail-oa0-f51.google.com with SMTP id i4so923341oah.38 for ; Wed, 02 Apr 2014 13:32:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=VadMzM3pVsDT4rnXzReVvHc2TdcIIU+MbG+Im9lTBRM=; b=VOqiyEWpaznoiOd05iwI4VrCyq7TiShCK5Wujv4KzMkMTxVGDidDYF5pmeEmBjxsXG CGSO4MPuTvtCPbTb67I8Uv3UAkuI2hCutOFLx0W+xoKDOwffc82iTb9ip3OKgVKwIha0 ddkMeSuEHCrvMfyv+/4oCngwwb2UAnqCbHFhogLbE5frP4cTbO+xPOCzWg2tNfmTsiCN kLz8CbH9lGSRQMxrak5CnIXKjVVQKw5q0mcEcCU/t6nR8BuvrUTW+GRHnaC9l5RYV5uQ vrI85UR5e1MGNwfOIttXIFPUS3eLx5g+WnbRndbEiVrEZ9tPVuRQDLBOsghw3rUo53wp DhrQ== X-Gm-Message-State: ALoCoQnQ2p9lYU0CzE1Vy5atLyeqY4hU5/aU8vpyL+4L4y0vIVL2d1QZQlekn7AeonRhTgZyQajP X-Received: by 10.60.155.72 with SMTP id vu8mr1829325oeb.60.1396470749709; Wed, 02 Apr 2014 13:32:29 -0700 (PDT) Received: from localhost ([64.126.112.59]) by mx.google.com with ESMTPSA id f9sm5177786obm.2.2014.04.02.13.32.28 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 02 Apr 2014 13:32:29 -0700 (PDT) From: Seth Forshee To: kernel-team@lists.ubuntu.com Subject: [PATCH][trusty] UBUNTU: SAUCE: brcmsmac: fix deadlock on missing firmware Date: Wed, 2 Apr 2014 15:32:27 -0500 Message-Id: <1396470747-22892-1-git-send-email-seth.forshee@canonical.com> X-Mailer: git-send-email 1.9.1 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Emil Goode 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 Signed-off-by: John W. Linville (cherry picked from commit 8fc1e8c240aab968db658b2d8d079b4391207a36 git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git) BugLink: http://bugs.launchpad.net/bugs/1300416 Signed-off-by: Seth Forshee Acked-by: Andy Whitcroft --- 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 edc5d10..03a56df 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;