scsi: fix race between simultaneous decrements of ->host_failed
authorWei Fang <fangwei1@huawei.com>
Tue, 7 Jun 2016 06:53:56 +0000 (14:53 +0800)
committerSasha Levin <sasha.levin@oracle.com>
Mon, 11 Jul 2016 00:19:54 +0000 (20:19 -0400)
commitbcef1c817adc16f798ff75e7910ab8b3361b85c8
treec8a2ea0b8d01d07e7b514b5440e4ecb72c33bcac
parente342d574a6ce550e14ae1def0eaf2c7cbdc3d991
scsi: fix race between simultaneous decrements of ->host_failed

[ Upstream commit 72d8c36ec364c82bf1bf0c64dfa1041cfaf139f7 ]

sas_ata_strategy_handler() adds the works of the ata error handler to
system_unbound_wq. This workqueue asynchronously runs work items, so the
ata error handler will be performed concurrently on different CPUs. In
this case, ->host_failed will be decreased simultaneously in
scsi_eh_finish_cmd() on different CPUs, and become abnormal.

It will lead to permanently inequality between ->host_failed and
->host_busy, and scsi error handler thread won't start running. IO
errors after that won't be handled.

Since all scmds must have been handled in the strategy handler, just
remove the decrement in scsi_eh_finish_cmd() and zero ->host_busy after
the strategy handler to fix this race.

Fixes: 50824d6c5657 ("[SCSI] libsas: async ata-eh")
Cc: stable@vger.kernel.org
Signed-off-by: Wei Fang <fangwei1@huawei.com>
Reviewed-by: James Bottomley <jejb@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Documentation/scsi/scsi_eh.txt
drivers/ata/libata-eh.c
drivers/scsi/scsi_error.c