mei: amthif: fix deadlock in initialization during a reset
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 025fb792ba
("mei: split amthif client init from end of clients enumeration")
Cc: <stable@vger.kernel.org> # 4.6+
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>
This commit is contained in:
parent
80293c47a6
commit
e728ae271f
|
@ -66,8 +66,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;
|
||||
|
||||
|
@ -76,11 +80,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -984,12 +984,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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue