diff options
| author | Alexandra Winter <wintera@linux.ibm.com> | 2021-09-21 16:52:17 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-10-07 07:53:03 +0200 |
| commit | 0bfe741741327822d1482c7edef0184636d08b40 (patch) | |
| tree | 0cf3c08d9f1cc8bbb8da2909f8a3671c60c71fc5 /arch | |
| parent | 0184084365c4d0a99ddd2ab1e1d8dbf9fd3c4714 (diff) | |
| download | linux-0bfe741741327822d1482c7edef0184636d08b40.tar.gz linux-0bfe741741327822d1482c7edef0184636d08b40.tar.bz2 linux-0bfe741741327822d1482c7edef0184636d08b40.zip | |
s390/qeth: fix deadlock during failing recovery
[ Upstream commit d2b59bd4b06d84a4eadb520b0f71c62fe8ec0a62 ]
Commit 0b9902c1fcc5 ("s390/qeth: fix deadlock during recovery") removed
taking discipline_mutex inside qeth_do_reset(), fixing potential
deadlocks. An error path was missed though, that still takes
discipline_mutex and thus has the original deadlock potential.
Intermittent deadlocks were seen when a qeth channel path is configured
offline, causing a race between qeth_do_reset and ccwgroup_remove.
Call qeth_set_offline() directly in the qeth_do_reset() error case and
then a new variant of ccwgroup_set_offline(), without taking
discipline_mutex.
Fixes: b41b554c1ee7 ("s390/qeth: fix locking for discipline setup / removal")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/s390/include/asm/ccwgroup.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index 20f169b6db4e..d97301d9d0b8 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -57,7 +57,7 @@ struct ccwgroup_device *get_ccwgroupdev_by_busid(struct ccwgroup_driver *gdrv, char *bus_id); extern int ccwgroup_set_online(struct ccwgroup_device *gdev); -extern int ccwgroup_set_offline(struct ccwgroup_device *gdev); +int ccwgroup_set_offline(struct ccwgroup_device *gdev, bool call_gdrv); extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); |
