[SCSI] zfcp: Fix deadlock between zfcp ERP and SCSI
The SCSI stack requires low level drivers to register and unregister devices. For zfcp this leads to the situation where zfcp calls the SCSI stack, the SCSI tries to scan the new device and the scan SCSI command fails. This would require the zfcp erp, but the erp thread is already blocked in the register call. The fix is to make sure that the calls from the ERP thread to the SCSI stack do not block the ERP thread. In detail: 1) Use a workqueue to avoid blocking of the scsi_scan_target calls. 2) When removing a unit make sure that no scsi_scan_target call is pending. 3) Replace scsi_flush_work with scsi_target_unblock. This avoids blocking and has the same result. Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:

committed by
James Bottomley

parent
801e0ced18
commit
5f852be9e1
@@ -22,6 +22,7 @@
|
||||
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI
|
||||
|
||||
#include "zfcp_ext.h"
|
||||
#include <asm/atomic.h>
|
||||
|
||||
static void zfcp_scsi_slave_destroy(struct scsi_device *sdp);
|
||||
static int zfcp_scsi_slave_alloc(struct scsi_device *sdp);
|
||||
@@ -179,6 +180,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
|
||||
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
|
||||
|
||||
if (unit) {
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
wait_event(unit->scsi_scan_wq,
|
||||
atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING,
|
||||
&unit->status) == 0);
|
||||
atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
|
||||
sdpnt->hostdata = NULL;
|
||||
unit->device = NULL;
|
||||
|
Reference in New Issue
Block a user