summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/cxlflash/superpipe.h
diff options
context:
space:
mode:
authorMatthew R. Ochs2015-10-21 22:15:52 +0200
committerJames Bottomley2015-10-30 09:22:11 +0100
commitaacb4ff69eea4ac47a7389f90ea7a896abbe92f5 (patch)
tree8318e4ff5a29e309f91786c7beb386cb97524d5d /drivers/scsi/cxlflash/superpipe.h
parentcxlflash: Correct trace string (diff)
downloadkernel-qcow2-linux-aacb4ff69eea4ac47a7389f90ea7a896abbe92f5.tar.gz
kernel-qcow2-linux-aacb4ff69eea4ac47a7389f90ea7a896abbe92f5.tar.xz
kernel-qcow2-linux-aacb4ff69eea4ac47a7389f90ea7a896abbe92f5.zip
cxlflash: Fix to avoid potential deadlock on EEH
Ioctl threads that use scsi_execute() can run for an excessive amount of time due to the fact that they have lengthy timeouts and retry logic built in. Under normal operation this is not an issue. However, once EEH enters the picture, a long execution time coupled with the possibility that a timeout can trigger entry to the driver via registered reset callbacks becomes a liability. In particular, a deadlock can occur when an EEH event is encountered while in running in scsi_execute(). As part of the recovery, the EEH handler drains all currently running ioctls, waiting until they have completed before proceeding with a reset. As the scsi_execute()'s are situated on the ioctl path, the EEH handler will wait until they (and the remainder of the ioctl handler they're associated with) have completed. Normally this would not be much of an issue aside from the longer recovery period. Unfortunately, the scsi_execute() triggers a reset when it times out. The reset handler will see that the device is already being reset and wait until that reset completed. This creates a condition where the EEH handler becomes stuck, infinitely waiting for the ioctl thread to complete. To avoid this behavior, temporarily unmark the scsi_execute() threads as an ioctl thread by releasing the ioctl read semaphore. This allows the EEH handler to proceed with a recovery while the thread is still running. Once the scsi_execute() returns, the ioctl read semaphore is reacquired and the adapter state is rechecked in case it changed while inside of scsi_execute(). The state check will wait if the adapter is still being recovered or returns a failure if the recovery failed. In the event that the adapter reset failed, the failure is simply returned as the ioctl would be unable to continue. Reported-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Signed-off-by: Manoj N. Kumar <manoj@linux.vnet.ibm.com> Reviewed-by: Brian King <brking@linux.vnet.ibm.com> Reviewed-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/cxlflash/superpipe.h')
-rw-r--r--drivers/scsi/cxlflash/superpipe.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/scsi/cxlflash/superpipe.h b/drivers/scsi/cxlflash/superpipe.h
index 7df88eeea9c0..06a805ab1439 100644
--- a/drivers/scsi/cxlflash/superpipe.h
+++ b/drivers/scsi/cxlflash/superpipe.h
@@ -147,4 +147,6 @@ void cxlflash_ba_terminate(struct ba_lun *);
int cxlflash_manage_lun(struct scsi_device *, struct dk_cxlflash_manage_lun *);
+int check_state(struct cxlflash_cfg *);
+
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */