mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
bnx2fc: Remove explicit logouts.
Explicit logouts from bnx2fc were causing race conditions in either returning stale SCSI commands or not allowing a target to log back in. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
This commit is contained in:
parent
adcf7dfbea
commit
50a8741469
@ -303,7 +303,6 @@ struct bnx2fc_rport {
|
|||||||
#define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5
|
#define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5
|
||||||
#define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6
|
#define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6
|
||||||
#define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7
|
#define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7
|
||||||
#define BNX2FC_FLAG_EXPL_LOGO 0x8
|
|
||||||
#define BNX2FC_FLAG_DISABLE_FAILED 0x9
|
#define BNX2FC_FLAG_DISABLE_FAILED 0x9
|
||||||
#define BNX2FC_FLAG_ENABLED 0xa
|
#define BNX2FC_FLAG_ENABLED 0xa
|
||||||
|
|
||||||
|
@ -689,8 +689,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
|
|||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto els_err;
|
goto els_err;
|
||||||
}
|
}
|
||||||
if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) ||
|
if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
|
||||||
(test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags))) {
|
|
||||||
printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
|
printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto els_err;
|
goto els_err;
|
||||||
|
@ -40,11 +40,8 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd,
|
struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd,
|
||||||
timeout_work.work);
|
timeout_work.work);
|
||||||
struct fc_lport *lport;
|
|
||||||
struct fc_rport_priv *rdata;
|
|
||||||
u8 cmd_type = io_req->cmd_type;
|
u8 cmd_type = io_req->cmd_type;
|
||||||
struct bnx2fc_rport *tgt = io_req->tgt;
|
struct bnx2fc_rport *tgt = io_req->tgt;
|
||||||
int logo_issued;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d,"
|
BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d,"
|
||||||
@ -80,25 +77,14 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
|
|||||||
io_req->refcount.refcount.counter);
|
io_req->refcount.refcount.counter);
|
||||||
if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
|
if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
|
||||||
&io_req->req_flags))) {
|
&io_req->req_flags))) {
|
||||||
|
/*
|
||||||
lport = io_req->port->lport;
|
* Cleanup and return original command to
|
||||||
rdata = io_req->tgt->rdata;
|
* mid-layer.
|
||||||
logo_issued = test_and_set_bit(
|
*/
|
||||||
BNX2FC_FLAG_EXPL_LOGO,
|
bnx2fc_initiate_cleanup(io_req);
|
||||||
&tgt->flags);
|
|
||||||
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
||||||
spin_unlock_bh(&tgt->tgt_lock);
|
spin_unlock_bh(&tgt->tgt_lock);
|
||||||
|
|
||||||
/* Explicitly logo the target */
|
|
||||||
if (!logo_issued) {
|
|
||||||
BNX2FC_IO_DBG(io_req, "Explicit "
|
|
||||||
"logo - tgt flags = 0x%lx\n",
|
|
||||||
tgt->flags);
|
|
||||||
|
|
||||||
mutex_lock(&lport->disc.disc_mutex);
|
|
||||||
lport->tt.rport_logoff(rdata);
|
|
||||||
mutex_unlock(&lport->disc.disc_mutex);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -116,28 +102,10 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
|
|||||||
rc = bnx2fc_initiate_abts(io_req);
|
rc = bnx2fc_initiate_abts(io_req);
|
||||||
if (rc == SUCCESS)
|
if (rc == SUCCESS)
|
||||||
goto done;
|
goto done;
|
||||||
/*
|
|
||||||
* Explicitly logo the target if
|
|
||||||
* abts initiation fails
|
|
||||||
*/
|
|
||||||
lport = io_req->port->lport;
|
|
||||||
rdata = io_req->tgt->rdata;
|
|
||||||
logo_issued = test_and_set_bit(
|
|
||||||
BNX2FC_FLAG_EXPL_LOGO,
|
|
||||||
&tgt->flags);
|
|
||||||
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
||||||
spin_unlock_bh(&tgt->tgt_lock);
|
spin_unlock_bh(&tgt->tgt_lock);
|
||||||
|
|
||||||
if (!logo_issued) {
|
|
||||||
BNX2FC_IO_DBG(io_req, "Explicit "
|
|
||||||
"logo - tgt flags = 0x%lx\n",
|
|
||||||
tgt->flags);
|
|
||||||
|
|
||||||
|
|
||||||
mutex_lock(&lport->disc.disc_mutex);
|
|
||||||
lport->tt.rport_logoff(rdata);
|
|
||||||
mutex_unlock(&lport->disc.disc_mutex);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
BNX2FC_IO_DBG(io_req, "IO already in "
|
BNX2FC_IO_DBG(io_req, "IO already in "
|
||||||
@ -152,22 +120,9 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
|
|||||||
|
|
||||||
if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
|
if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
|
||||||
&io_req->req_flags)) {
|
&io_req->req_flags)) {
|
||||||
lport = io_req->port->lport;
|
|
||||||
rdata = io_req->tgt->rdata;
|
|
||||||
logo_issued = test_and_set_bit(
|
|
||||||
BNX2FC_FLAG_EXPL_LOGO,
|
|
||||||
&tgt->flags);
|
|
||||||
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
||||||
spin_unlock_bh(&tgt->tgt_lock);
|
spin_unlock_bh(&tgt->tgt_lock);
|
||||||
|
|
||||||
/* Explicitly logo the target */
|
|
||||||
if (!logo_issued) {
|
|
||||||
BNX2FC_IO_DBG(io_req, "Explicitly logo"
|
|
||||||
"(els)\n");
|
|
||||||
mutex_lock(&lport->disc.disc_mutex);
|
|
||||||
lport->tt.rport_logoff(rdata);
|
|
||||||
mutex_unlock(&lport->disc.disc_mutex);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1112,18 +1067,11 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
|
|||||||
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
|
return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
|
int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
|
||||||
{
|
{
|
||||||
struct bnx2fc_rport *tgt = io_req->tgt;
|
struct bnx2fc_rport *tgt = io_req->tgt;
|
||||||
struct fc_rport_priv *rdata = tgt->rdata;
|
|
||||||
int logo_issued;
|
|
||||||
int rc = SUCCESS;
|
int rc = SUCCESS;
|
||||||
int wait_cnt = 0;
|
|
||||||
|
|
||||||
BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
|
|
||||||
tgt->flags);
|
|
||||||
logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
|
|
||||||
&tgt->flags);
|
|
||||||
io_req->wait_for_comp = 1;
|
io_req->wait_for_comp = 1;
|
||||||
bnx2fc_initiate_cleanup(io_req);
|
bnx2fc_initiate_cleanup(io_req);
|
||||||
|
|
||||||
@ -1136,21 +1084,8 @@ int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req)
|
|||||||
* release the reference taken in eh_abort to allow the
|
* release the reference taken in eh_abort to allow the
|
||||||
* target to re-login after flushing IOs
|
* target to re-login after flushing IOs
|
||||||
*/
|
*/
|
||||||
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
kref_put(&io_req->refcount, bnx2fc_cmd_release);
|
||||||
|
|
||||||
if (!logo_issued) {
|
|
||||||
clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags);
|
|
||||||
mutex_lock(&lport->disc.disc_mutex);
|
|
||||||
lport->tt.rport_logoff(rdata);
|
|
||||||
mutex_unlock(&lport->disc.disc_mutex);
|
|
||||||
do {
|
|
||||||
msleep(BNX2FC_RELOGIN_WAIT_TIME);
|
|
||||||
if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) {
|
|
||||||
rc = FAILED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags));
|
|
||||||
}
|
|
||||||
spin_lock_bh(&tgt->tgt_lock);
|
spin_lock_bh(&tgt->tgt_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -1252,7 +1187,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
|
|||||||
if (cancel_delayed_work(&io_req->timeout_work))
|
if (cancel_delayed_work(&io_req->timeout_work))
|
||||||
kref_put(&io_req->refcount,
|
kref_put(&io_req->refcount,
|
||||||
bnx2fc_cmd_release); /* drop timer hold */
|
bnx2fc_cmd_release); /* drop timer hold */
|
||||||
rc = bnx2fc_expl_logo(lport, io_req);
|
rc = bnx2fc_abts_cleanup(io_req);
|
||||||
/* This only occurs when an task abort was requested while ABTS
|
/* This only occurs when an task abort was requested while ABTS
|
||||||
is in progress. Setting the IO_CLEANUP flag will skip the
|
is in progress. Setting the IO_CLEANUP flag will skip the
|
||||||
RRQ process in the case when the fw generated SCSI_CMD cmpl
|
RRQ process in the case when the fw generated SCSI_CMD cmpl
|
||||||
@ -1291,7 +1226,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
|
|||||||
/* Let the scsi-ml try to recover this command */
|
/* Let the scsi-ml try to recover this command */
|
||||||
printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
|
printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
|
||||||
io_req->xid);
|
io_req->xid);
|
||||||
rc = bnx2fc_expl_logo(lport, io_req);
|
rc = bnx2fc_abts_cleanup(io_req);
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -560,12 +560,6 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport,
|
|||||||
(hba->num_ofld_sess == 0)) {
|
(hba->num_ofld_sess == 0)) {
|
||||||
wake_up_interruptible(&hba->shutdown_wait);
|
wake_up_interruptible(&hba->shutdown_wait);
|
||||||
}
|
}
|
||||||
if (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags)) {
|
|
||||||
printk(KERN_ERR PFX "Relogin to the tgt\n");
|
|
||||||
mutex_lock(&lport->disc.disc_mutex);
|
|
||||||
lport->tt.rport_login(rdata);
|
|
||||||
mutex_unlock(&lport->disc.disc_mutex);
|
|
||||||
}
|
|
||||||
mutex_unlock(&hba->hba_mutex);
|
mutex_unlock(&hba->hba_mutex);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user