lkml.org 
[lkml]   [2016]   [Oct]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.7 13/45] mei: amthif: fix deadlock in initialization during a reset
    Date
    4.7-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alexander Usyskin <alexander.usyskin@intel.com>

    commit e728ae271f4cf71218ec06a6daf61b79466cb466 upstream.

    The device lock was unnecessary obtained in bus rescan work before the
    amthif client search. That causes incorrect lock ordering and task
    hang:
    ...
    [88004.613213] INFO: task kworker/1:14:21832 blocked for more than 120 seconds.
    ...
    [88004.645934] Workqueue: events mei_cl_bus_rescan_work
    ...

    The correct lock order is
    cl_bus_lock
    device_lock
    me_clients_rwsem

    Move device_lock into amthif init function that called
    after me_clients_rwsem is released.

    This fixes regression introduced by commit:
    commit 025fb792bac3 ("mei: split amthif client init from end of clients enumeration")

    Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
    Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/misc/mei/amthif.c | 12 +++++++++---
    drivers/misc/mei/bus.c | 2 --
    2 files changed, 9 insertions(+), 5 deletions(-)

    --- a/drivers/misc/mei/amthif.c
    +++ b/drivers/misc/mei/amthif.c
    @@ -67,8 +67,12 @@ int mei_amthif_host_init(struct mei_devi
    struct mei_cl *cl = &dev->iamthif_cl;
    int ret;

    - if (mei_cl_is_connected(cl))
    - return 0;
    + mutex_lock(&dev->device_lock);
    +
    + if (mei_cl_is_connected(cl)) {
    + ret = 0;
    + goto out;
    + }

    dev->iamthif_state = MEI_IAMTHIF_IDLE;

    @@ -77,11 +81,13 @@ int mei_amthif_host_init(struct mei_devi
    ret = mei_cl_link(cl);
    if (ret < 0) {
    dev_err(dev->dev, "amthif: failed cl_link %d\n", ret);
    - return ret;
    + goto out;
    }

    ret = mei_cl_connect(cl, me_cl, NULL);

    +out:
    + mutex_unlock(&dev->device_lock);
    return ret;
    }

    --- a/drivers/misc/mei/bus.c
    +++ b/drivers/misc/mei/bus.c
    @@ -983,12 +983,10 @@ void mei_cl_bus_rescan_work(struct work_
    container_of(work, struct mei_device, bus_rescan_work);
    struct mei_me_client *me_cl;

    - mutex_lock(&bus->device_lock);
    me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid);
    if (me_cl)
    mei_amthif_host_init(bus, me_cl);
    mei_me_cl_put(me_cl);
    - mutex_unlock(&bus->device_lock);

    mei_cl_bus_rescan(bus);
    }

    \
     
     \ /
      Last update: 2016-10-21 11:19    [W:4.247 / U:0.240 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site