lkml.org 
[lkml]   [2021]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 023/151] net: wwan: mhi_wwan_ctrl: Fix possible deadlock
    Date
    From: Loic Poulain <loic.poulain@linaro.org>

    commit 34737e1320db6d51f0d140d5c684b9eb32f0da76 upstream.

    Lockdep detected possible interrupt unsafe locking scenario:

    CPU0 CPU1
    ---- ----
    lock(&mhiwwan->rx_lock);
    local_irq_disable();
    lock(&mhi_cntrl->pm_lock);
    lock(&mhiwwan->rx_lock);
    <Interrupt>
    lock(&mhi_cntrl->pm_lock);

    *** DEADLOCK ***

    To prevent this we need to disable the soft-interrupts when taking
    the rx_lock.

    Cc: stable@vger.kernel.org
    Fixes: fa588eba632d ("net: Add Qcom WWAN control driver")
    Reported-by: Thomas Perrot <thomas.perrot@bootlin.com>
    Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
    Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/wwan/mhi_wwan_ctrl.c | 12 ++++++------
    1 file changed, 6 insertions(+), 6 deletions(-)

    --- a/drivers/net/wwan/mhi_wwan_ctrl.c
    +++ b/drivers/net/wwan/mhi_wwan_ctrl.c
    @@ -41,14 +41,14 @@ struct mhi_wwan_dev {
    /* Increment RX budget and schedule RX refill if necessary */
    static void mhi_wwan_rx_budget_inc(struct mhi_wwan_dev *mhiwwan)
    {
    - spin_lock(&mhiwwan->rx_lock);
    + spin_lock_bh(&mhiwwan->rx_lock);

    mhiwwan->rx_budget++;

    if (test_bit(MHI_WWAN_RX_REFILL, &mhiwwan->flags))
    schedule_work(&mhiwwan->rx_refill);

    - spin_unlock(&mhiwwan->rx_lock);
    + spin_unlock_bh(&mhiwwan->rx_lock);
    }

    /* Decrement RX budget if non-zero and return true on success */
    @@ -56,7 +56,7 @@ static bool mhi_wwan_rx_budget_dec(struc
    {
    bool ret = false;

    - spin_lock(&mhiwwan->rx_lock);
    + spin_lock_bh(&mhiwwan->rx_lock);

    if (mhiwwan->rx_budget) {
    mhiwwan->rx_budget--;
    @@ -64,7 +64,7 @@ static bool mhi_wwan_rx_budget_dec(struc
    ret = true;
    }

    - spin_unlock(&mhiwwan->rx_lock);
    + spin_unlock_bh(&mhiwwan->rx_lock);

    return ret;
    }
    @@ -130,9 +130,9 @@ static void mhi_wwan_ctrl_stop(struct ww
    {
    struct mhi_wwan_dev *mhiwwan = wwan_port_get_drvdata(port);

    - spin_lock(&mhiwwan->rx_lock);
    + spin_lock_bh(&mhiwwan->rx_lock);
    clear_bit(MHI_WWAN_RX_REFILL, &mhiwwan->flags);
    - spin_unlock(&mhiwwan->rx_lock);
    + spin_unlock_bh(&mhiwwan->rx_lock);

    cancel_work_sync(&mhiwwan->rx_refill);


    \
     
     \ /
      Last update: 2021-08-16 15:24    [W:3.221 / U:0.620 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site