diff options
author | Steve Ma <steve.ma@intel.com> | 2009-02-27 13:55:13 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-03-06 16:40:45 -0500 |
commit | f7db2c150cf5082cf74555f30a1305938041de80 (patch) | |
tree | 51d92a06ddb32fb0fd7757e67f3e3f8c81b39b0b /drivers/scsi | |
parent | 26d9cab558f901051d0b69b2c445c8588931ce8d (diff) |
[SCSI] libfc: exch mgr is freed while lport still retrying sequences
When a sequence cannot be delivered to the target, the local
port will schedule retries, While this process is in progress,
if we destroy the FCoE interface, the fcoe_sw_destroy routine is
entered, and the fc_exch_mgr_free(lp->emp) is called. Thus
if fc_exch_alloc() is called when retrying the sequence,
the mempool_alloc() will fail to allocate the exchange because
the mempool of the exchange manager has already been released.
This patch is to cancel any pending retry work of the local
port before we start to destroy the interface.
Also, when resetting the local port, we should also stop the
scheduled pending retries.
Signed-off-by: Steve Ma <steve.ma@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/libfc/fc_lport.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index a6ab692f5f51..e6ea4f119530 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -619,6 +619,7 @@ int fc_fabric_logoff(struct fc_lport *lport) | |||
619 | mutex_lock(&lport->lp_mutex); | 619 | mutex_lock(&lport->lp_mutex); |
620 | fc_lport_enter_logo(lport); | 620 | fc_lport_enter_logo(lport); |
621 | mutex_unlock(&lport->lp_mutex); | 621 | mutex_unlock(&lport->lp_mutex); |
622 | cancel_delayed_work_sync(&lport->retry_work); | ||
622 | return 0; | 623 | return 0; |
623 | } | 624 | } |
624 | EXPORT_SYMBOL(fc_fabric_logoff); | 625 | EXPORT_SYMBOL(fc_fabric_logoff); |
@@ -918,6 +919,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, | |||
918 | */ | 919 | */ |
919 | int fc_lport_reset(struct fc_lport *lport) | 920 | int fc_lport_reset(struct fc_lport *lport) |
920 | { | 921 | { |
922 | cancel_delayed_work_sync(&lport->retry_work); | ||
921 | mutex_lock(&lport->lp_mutex); | 923 | mutex_lock(&lport->lp_mutex); |
922 | fc_lport_enter_reset(lport); | 924 | fc_lport_enter_reset(lport); |
923 | mutex_unlock(&lport->lp_mutex); | 925 | mutex_unlock(&lport->lp_mutex); |