Skip to content

Commit

Permalink
mei: amthif: fix deadlock in initialization during a reset
Browse files Browse the repository at this point in the history
BugLink: http://bugs.launchpad.net/bugs/1637517

commit e728ae2 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 025fb79 ("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>

Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
  • Loading branch information
ausyskin authored and Luis Henriques committed Nov 8, 2016
1 parent d262252 commit 09d6f24
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 5 deletions.
12 changes: 9 additions & 3 deletions drivers/misc/mei/amthif.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
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;

Expand All @@ -77,11 +81,13 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
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;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/misc/mei/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,12 +983,10 @@ void mei_cl_bus_rescan_work(struct 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);
}
Expand Down

0 comments on commit 09d6f24

Please sign in to comment.