diff options
author | Chad Dupuis <chad.dupuis@qlogic.com> | 2015-10-19 15:40:39 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-11-09 20:31:34 -0500 |
commit | 50a87414695fc5009ba776a61f48d3d67ffdd6ed (patch) | |
tree | 12f77344ea450ff7613149b78cb5e7159723b011 | |
parent | adcf7dfbea80382457a552b4eb7aa2b7d9f76dac (diff) |
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>
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_els.c | 3 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 87 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_tgt.c | 6 |
4 files changed, 12 insertions, 85 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index 0e2aa653b892..d46267da4307 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h | |||
@@ -303,7 +303,6 @@ struct bnx2fc_rport { | |||
303 | #define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5 | 303 | #define BNX2FC_FLAG_OFLD_REQ_CMPL 0x5 |
304 | #define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6 | 304 | #define BNX2FC_FLAG_CTX_ALLOC_FAILURE 0x6 |
305 | #define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7 | 305 | #define BNX2FC_FLAG_UPLD_REQ_COMPL 0x7 |
306 | #define BNX2FC_FLAG_EXPL_LOGO 0x8 | ||
307 | #define BNX2FC_FLAG_DISABLE_FAILED 0x9 | 306 | #define BNX2FC_FLAG_DISABLE_FAILED 0x9 |
308 | #define BNX2FC_FLAG_ENABLED 0xa | 307 | #define BNX2FC_FLAG_ENABLED 0xa |
309 | 308 | ||
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index 0d0ab2e272cb..5beea776b9f5 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c | |||
@@ -689,8 +689,7 @@ static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, | |||
689 | rc = -EINVAL; | 689 | rc = -EINVAL; |
690 | goto els_err; | 690 | goto els_err; |
691 | } | 691 | } |
692 | if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) || | 692 | if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) { |
693 | (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags))) { | ||
694 | printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op); | 693 | printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op); |
695 | rc = -EINVAL; | 694 | rc = -EINVAL; |
696 | goto els_err; | 695 | goto els_err; |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 8ae0621dbe28..0002caf687dd 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -40,11 +40,8 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) | |||
40 | { | 40 | { |
41 | struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd, | 41 | struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd, |
42 | timeout_work.work); | 42 | timeout_work.work); |
43 | struct fc_lport *lport; | ||
44 | struct fc_rport_priv *rdata; | ||
45 | u8 cmd_type = io_req->cmd_type; | 43 | u8 cmd_type = io_req->cmd_type; |
46 | struct bnx2fc_rport *tgt = io_req->tgt; | 44 | struct bnx2fc_rport *tgt = io_req->tgt; |
47 | int logo_issued; | ||
48 | int rc; | 45 | int rc; |
49 | 46 | ||
50 | BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d," | 47 | BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d," |
@@ -80,25 +77,14 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) | |||
80 | io_req->refcount.refcount.counter); | 77 | io_req->refcount.refcount.counter); |
81 | if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, | 78 | if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, |
82 | &io_req->req_flags))) { | 79 | &io_req->req_flags))) { |
83 | 80 | /* | |
84 | lport = io_req->port->lport; | 81 | * Cleanup and return original command to |
85 | rdata = io_req->tgt->rdata; | 82 | * mid-layer. |
86 | logo_issued = test_and_set_bit( | 83 | */ |
87 | BNX2FC_FLAG_EXPL_LOGO, | 84 | bnx2fc_initiate_cleanup(io_req); |
88 | &tgt->flags); | ||
89 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | 85 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
90 | spin_unlock_bh(&tgt->tgt_lock); | 86 | spin_unlock_bh(&tgt->tgt_lock); |
91 | 87 | ||
92 | /* Explicitly logo the target */ | ||
93 | if (!logo_issued) { | ||
94 | BNX2FC_IO_DBG(io_req, "Explicit " | ||
95 | "logo - tgt flags = 0x%lx\n", | ||
96 | tgt->flags); | ||
97 | |||
98 | mutex_lock(&lport->disc.disc_mutex); | ||
99 | lport->tt.rport_logoff(rdata); | ||
100 | mutex_unlock(&lport->disc.disc_mutex); | ||
101 | } | ||
102 | return; | 88 | return; |
103 | } | 89 | } |
104 | } else { | 90 | } else { |
@@ -116,28 +102,10 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) | |||
116 | rc = bnx2fc_initiate_abts(io_req); | 102 | rc = bnx2fc_initiate_abts(io_req); |
117 | if (rc == SUCCESS) | 103 | if (rc == SUCCESS) |
118 | goto done; | 104 | goto done; |
119 | /* | 105 | |
120 | * Explicitly logo the target if | ||
121 | * abts initiation fails | ||
122 | */ | ||
123 | lport = io_req->port->lport; | ||
124 | rdata = io_req->tgt->rdata; | ||
125 | logo_issued = test_and_set_bit( | ||
126 | BNX2FC_FLAG_EXPL_LOGO, | ||
127 | &tgt->flags); | ||
128 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | 106 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
129 | spin_unlock_bh(&tgt->tgt_lock); | 107 | spin_unlock_bh(&tgt->tgt_lock); |
130 | 108 | ||
131 | if (!logo_issued) { | ||
132 | BNX2FC_IO_DBG(io_req, "Explicit " | ||
133 | "logo - tgt flags = 0x%lx\n", | ||
134 | tgt->flags); | ||
135 | |||
136 | |||
137 | mutex_lock(&lport->disc.disc_mutex); | ||
138 | lport->tt.rport_logoff(rdata); | ||
139 | mutex_unlock(&lport->disc.disc_mutex); | ||
140 | } | ||
141 | return; | 109 | return; |
142 | } else { | 110 | } else { |
143 | BNX2FC_IO_DBG(io_req, "IO already in " | 111 | BNX2FC_IO_DBG(io_req, "IO already in " |
@@ -152,22 +120,9 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) | |||
152 | 120 | ||
153 | if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, | 121 | if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, |
154 | &io_req->req_flags)) { | 122 | &io_req->req_flags)) { |
155 | lport = io_req->port->lport; | ||
156 | rdata = io_req->tgt->rdata; | ||
157 | logo_issued = test_and_set_bit( | ||
158 | BNX2FC_FLAG_EXPL_LOGO, | ||
159 | &tgt->flags); | ||
160 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | 123 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
161 | spin_unlock_bh(&tgt->tgt_lock); | 124 | spin_unlock_bh(&tgt->tgt_lock); |
162 | 125 | ||
163 | /* Explicitly logo the target */ | ||
164 | if (!logo_issued) { | ||
165 | BNX2FC_IO_DBG(io_req, "Explicitly logo" | ||
166 | "(els)\n"); | ||
167 | mutex_lock(&lport->disc.disc_mutex); | ||
168 | lport->tt.rport_logoff(rdata); | ||
169 | mutex_unlock(&lport->disc.disc_mutex); | ||
170 | } | ||
171 | return; | 126 | return; |
172 | } | 127 | } |
173 | } else { | 128 | } else { |
@@ -1112,18 +1067,11 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd) | |||
1112 | return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); | 1067 | return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); |
1113 | } | 1068 | } |
1114 | 1069 | ||
1115 | int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req) | 1070 | int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) |
1116 | { | 1071 | { |
1117 | struct bnx2fc_rport *tgt = io_req->tgt; | 1072 | struct bnx2fc_rport *tgt = io_req->tgt; |
1118 | struct fc_rport_priv *rdata = tgt->rdata; | ||
1119 | int logo_issued; | ||
1120 | int rc = SUCCESS; | 1073 | int rc = SUCCESS; |
1121 | int wait_cnt = 0; | ||
1122 | 1074 | ||
1123 | BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n", | ||
1124 | tgt->flags); | ||
1125 | logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO, | ||
1126 | &tgt->flags); | ||
1127 | io_req->wait_for_comp = 1; | 1075 | io_req->wait_for_comp = 1; |
1128 | bnx2fc_initiate_cleanup(io_req); | 1076 | bnx2fc_initiate_cleanup(io_req); |
1129 | 1077 | ||
@@ -1136,21 +1084,8 @@ int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req) | |||
1136 | * release the reference taken in eh_abort to allow the | 1084 | * release the reference taken in eh_abort to allow the |
1137 | * target to re-login after flushing IOs | 1085 | * target to re-login after flushing IOs |
1138 | */ | 1086 | */ |
1139 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | 1087 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
1140 | 1088 | ||
1141 | if (!logo_issued) { | ||
1142 | clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags); | ||
1143 | mutex_lock(&lport->disc.disc_mutex); | ||
1144 | lport->tt.rport_logoff(rdata); | ||
1145 | mutex_unlock(&lport->disc.disc_mutex); | ||
1146 | do { | ||
1147 | msleep(BNX2FC_RELOGIN_WAIT_TIME); | ||
1148 | if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) { | ||
1149 | rc = FAILED; | ||
1150 | break; | ||
1151 | } | ||
1152 | } while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)); | ||
1153 | } | ||
1154 | spin_lock_bh(&tgt->tgt_lock); | 1089 | spin_lock_bh(&tgt->tgt_lock); |
1155 | return rc; | 1090 | return rc; |
1156 | } | 1091 | } |
@@ -1252,7 +1187,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) | |||
1252 | if (cancel_delayed_work(&io_req->timeout_work)) | 1187 | if (cancel_delayed_work(&io_req->timeout_work)) |
1253 | kref_put(&io_req->refcount, | 1188 | kref_put(&io_req->refcount, |
1254 | bnx2fc_cmd_release); /* drop timer hold */ | 1189 | bnx2fc_cmd_release); /* drop timer hold */ |
1255 | rc = bnx2fc_expl_logo(lport, io_req); | 1190 | rc = bnx2fc_abts_cleanup(io_req); |
1256 | /* This only occurs when an task abort was requested while ABTS | 1191 | /* This only occurs when an task abort was requested while ABTS |
1257 | is in progress. Setting the IO_CLEANUP flag will skip the | 1192 | is in progress. Setting the IO_CLEANUP flag will skip the |
1258 | RRQ process in the case when the fw generated SCSI_CMD cmpl | 1193 | 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) | |||
1291 | /* Let the scsi-ml try to recover this command */ | 1226 | /* Let the scsi-ml try to recover this command */ |
1292 | printk(KERN_ERR PFX "abort failed, xid = 0x%x\n", | 1227 | printk(KERN_ERR PFX "abort failed, xid = 0x%x\n", |
1293 | io_req->xid); | 1228 | io_req->xid); |
1294 | rc = bnx2fc_expl_logo(lport, io_req); | 1229 | rc = bnx2fc_abts_cleanup(io_req); |
1295 | goto out; | 1230 | goto out; |
1296 | } else { | 1231 | } else { |
1297 | /* | 1232 | /* |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 30a8788657b7..08ec318afb99 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c | |||
@@ -560,12 +560,6 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport, | |||
560 | (hba->num_ofld_sess == 0)) { | 560 | (hba->num_ofld_sess == 0)) { |
561 | wake_up_interruptible(&hba->shutdown_wait); | 561 | wake_up_interruptible(&hba->shutdown_wait); |
562 | } | 562 | } |
563 | if (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags)) { | ||
564 | printk(KERN_ERR PFX "Relogin to the tgt\n"); | ||
565 | mutex_lock(&lport->disc.disc_mutex); | ||
566 | lport->tt.rport_login(rdata); | ||
567 | mutex_unlock(&lport->disc.disc_mutex); | ||
568 | } | ||
569 | mutex_unlock(&hba->hba_mutex); | 563 | mutex_unlock(&hba->hba_mutex); |
570 | 564 | ||
571 | break; | 565 | break; |