aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJing Huang <huangj@brocade.com>2010-07-08 22:58:45 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:04:20 -0400
commit56d218fc93ede28a2a5b71c5db334f193b39988f (patch)
treecc0868699c656cdb93380ba20467c8ae5bf7e516
parentdb954c04cbebd7d719927118c7f58eddd8dd9913 (diff)
[SCSI] bfa: fix possible IO double completion
While processing the ioim in callback functions, the ioim is still in io_q. During this time, if the itnim goes offline, the ioim is requeued from itnim->io_q into itnim->delay_comp_q although the request is already completed. This results in requeing the ioim into the callback queue if the ioim is not freed by the time the ioim is requeued. This results in double completion of the ioim. To fix this, whenever a response is received from firmware for an ioim, deque it from io_q and enque to fcpim->comp_q. This will eliminate any possibility of itnim picking any ioim for which the response is already received. Signed-off-by: Jing Huang <huangj@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
index 680b87d8f0d9..4148ae09f998 100644
--- a/drivers/scsi/bfa/bfa_ioim.c
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -133,6 +133,8 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
133 133
134 case BFA_IOIM_SM_IOTOV: 134 case BFA_IOIM_SM_IOTOV:
135 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 135 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
136 list_del(&ioim->qe);
137 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
136 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 138 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
137 __bfa_cb_ioim_pathtov, ioim); 139 __bfa_cb_ioim_pathtov, ioim);
138 break; 140 break;
@@ -182,6 +184,8 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
182 case BFA_IOIM_SM_ABORT: 184 case BFA_IOIM_SM_ABORT:
183 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 185 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
184 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); 186 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
187 list_del(&ioim->qe);
188 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
185 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 189 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
186 ioim); 190 ioim);
187 break; 191 break;
@@ -189,6 +193,8 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
189 case BFA_IOIM_SM_HWFAIL: 193 case BFA_IOIM_SM_HWFAIL:
190 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 194 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
191 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); 195 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
196 list_del(&ioim->qe);
197 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
192 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 198 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
193 ioim); 199 ioim);
194 break; 200 break;
@@ -210,18 +216,24 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
210 switch (event) { 216 switch (event) {
211 case BFA_IOIM_SM_COMP_GOOD: 217 case BFA_IOIM_SM_COMP_GOOD:
212 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 218 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
219 list_del(&ioim->qe);
220 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
213 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 221 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
214 __bfa_cb_ioim_good_comp, ioim); 222 __bfa_cb_ioim_good_comp, ioim);
215 break; 223 break;
216 224
217 case BFA_IOIM_SM_COMP: 225 case BFA_IOIM_SM_COMP:
218 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 226 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
227 list_del(&ioim->qe);
228 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
219 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp, 229 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
220 ioim); 230 ioim);
221 break; 231 break;
222 232
223 case BFA_IOIM_SM_DONE: 233 case BFA_IOIM_SM_DONE:
224 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 234 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
235 list_del(&ioim->qe);
236 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
225 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp, 237 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
226 ioim); 238 ioim);
227 break; 239 break;
@@ -254,6 +266,8 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
254 266
255 case BFA_IOIM_SM_HWFAIL: 267 case BFA_IOIM_SM_HWFAIL:
256 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 268 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
269 list_del(&ioim->qe);
270 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
257 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 271 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
258 ioim); 272 ioim);
259 break; 273 break;
@@ -287,12 +301,16 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
287 301
288 case BFA_IOIM_SM_ABORT_COMP: 302 case BFA_IOIM_SM_ABORT_COMP:
289 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 303 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
304 list_del(&ioim->qe);
305 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
290 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 306 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
291 ioim); 307 ioim);
292 break; 308 break;
293 309
294 case BFA_IOIM_SM_COMP_UTAG: 310 case BFA_IOIM_SM_COMP_UTAG:
295 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 311 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
312 list_del(&ioim->qe);
313 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
296 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 314 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
297 ioim); 315 ioim);
298 break; 316 break;
@@ -312,6 +330,8 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
312 330
313 case BFA_IOIM_SM_HWFAIL: 331 case BFA_IOIM_SM_HWFAIL:
314 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 332 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
333 list_del(&ioim->qe);
334 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
315 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 335 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
316 ioim); 336 ioim);
317 break; 337 break;
@@ -365,6 +385,8 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
365 385
366 case BFA_IOIM_SM_HWFAIL: 386 case BFA_IOIM_SM_HWFAIL:
367 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 387 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
388 list_del(&ioim->qe);
389 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
368 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 390 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
369 ioim); 391 ioim);
370 break; 392 break;
@@ -399,6 +421,8 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
399 case BFA_IOIM_SM_ABORT: 421 case BFA_IOIM_SM_ABORT:
400 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 422 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
401 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 423 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
424 list_del(&ioim->qe);
425 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
402 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 426 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
403 ioim); 427 ioim);
404 break; 428 break;
@@ -414,6 +438,8 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
414 case BFA_IOIM_SM_HWFAIL: 438 case BFA_IOIM_SM_HWFAIL:
415 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 439 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
416 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 440 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
441 list_del(&ioim->qe);
442 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
417 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 443 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
418 ioim); 444 ioim);
419 break; 445 break;
@@ -448,6 +474,8 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
448 case BFA_IOIM_SM_COMP: 474 case BFA_IOIM_SM_COMP:
449 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 475 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
450 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 476 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
477 list_del(&ioim->qe);
478 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
451 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 479 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
452 ioim); 480 ioim);
453 break; 481 break;
@@ -455,6 +483,8 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
455 case BFA_IOIM_SM_DONE: 483 case BFA_IOIM_SM_DONE:
456 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 484 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
457 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 485 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
486 list_del(&ioim->qe);
487 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
458 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 488 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
459 ioim); 489 ioim);
460 break; 490 break;
@@ -462,6 +492,8 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
462 case BFA_IOIM_SM_HWFAIL: 492 case BFA_IOIM_SM_HWFAIL:
463 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 493 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
464 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 494 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
495 list_del(&ioim->qe);
496 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
465 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 497 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
466 ioim); 498 ioim);
467 break; 499 break;
@@ -511,6 +543,8 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
511 case BFA_IOIM_SM_HWFAIL: 543 case BFA_IOIM_SM_HWFAIL:
512 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 544 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
513 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 545 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
546 list_del(&ioim->qe);
547 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
514 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 548 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
515 ioim); 549 ioim);
516 break; 550 break;