Commit fa61a54e48efc8e5c7a6d4680ad8ceb74a5fca84
Committed by
James Bottomley
1 parent
0ff10d46cf
Exists in
master
and in
7 other branches
[SCSI] lpfc 8.2.4 : Correct abort handler logic
Correct Abort handler logic. It was unconditionally waiting a minimum of 2 seconds rather than looking for abort completion. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Showing 2 changed files with 29 additions and 10 deletions Side-by-side Diff
drivers/scsi/lpfc/lpfc_scsi.c
... | ... | @@ -542,6 +542,7 @@ |
542 | 542 | int result; |
543 | 543 | struct scsi_device *sdev, *tmp_sdev; |
544 | 544 | int depth = 0; |
545 | + unsigned long flags; | |
545 | 546 | |
546 | 547 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; |
547 | 548 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; |
... | ... | @@ -608,6 +609,15 @@ |
608 | 609 | cmd->scsi_done(cmd); |
609 | 610 | |
610 | 611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
612 | + /* | |
613 | + * If there is a thread waiting for command completion | |
614 | + * wake up the thread. | |
615 | + */ | |
616 | + spin_lock_irqsave(sdev->host->host_lock, flags); | |
617 | + lpfc_cmd->pCmd = NULL; | |
618 | + if (lpfc_cmd->waitq) | |
619 | + wake_up(lpfc_cmd->waitq); | |
620 | + spin_unlock_irqrestore(sdev->host->host_lock, flags); | |
611 | 621 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
612 | 622 | return; |
613 | 623 | } |
... | ... | @@ -669,6 +679,16 @@ |
669 | 679 | } |
670 | 680 | } |
671 | 681 | |
682 | + /* | |
683 | + * If there is a thread waiting for command completion | |
684 | + * wake up the thread. | |
685 | + */ | |
686 | + spin_lock_irqsave(sdev->host->host_lock, flags); | |
687 | + lpfc_cmd->pCmd = NULL; | |
688 | + if (lpfc_cmd->waitq) | |
689 | + wake_up(lpfc_cmd->waitq); | |
690 | + spin_unlock_irqrestore(sdev->host->host_lock, flags); | |
691 | + | |
672 | 692 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
673 | 693 | } |
674 | 694 | |
675 | 695 | |
... | ... | @@ -1018,8 +1038,8 @@ |
1018 | 1038 | struct lpfc_iocbq *abtsiocb; |
1019 | 1039 | struct lpfc_scsi_buf *lpfc_cmd; |
1020 | 1040 | IOCB_t *cmd, *icmd; |
1021 | - unsigned int loop_count = 0; | |
1022 | 1041 | int ret = SUCCESS; |
1042 | + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | |
1023 | 1043 | |
1024 | 1044 | lpfc_block_error_handler(cmnd); |
1025 | 1045 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
1026 | 1046 | |
1027 | 1047 | |
... | ... | @@ -1074,17 +1094,15 @@ |
1074 | 1094 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) |
1075 | 1095 | lpfc_sli_poll_fcp_ring (phba); |
1076 | 1096 | |
1097 | + lpfc_cmd->waitq = &waitq; | |
1077 | 1098 | /* Wait for abort to complete */ |
1078 | - while (lpfc_cmd->pCmd == cmnd) | |
1079 | - { | |
1080 | - if (phba->cfg_poll & DISABLE_FCP_RING_INT) | |
1081 | - lpfc_sli_poll_fcp_ring (phba); | |
1099 | + wait_event_timeout(waitq, | |
1100 | + (lpfc_cmd->pCmd != cmnd), | |
1101 | + (2*vport->cfg_devloss_tmo*HZ)); | |
1082 | 1102 | |
1083 | - schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ); | |
1084 | - if (++loop_count | |
1085 | - > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT) | |
1086 | - break; | |
1087 | - } | |
1103 | + spin_lock_irq(shost->host_lock); | |
1104 | + lpfc_cmd->waitq = NULL; | |
1105 | + spin_unlock_irq(shost->host_lock); | |
1088 | 1106 | |
1089 | 1107 | if (lpfc_cmd->pCmd == cmnd) { |
1090 | 1108 | ret = FAILED; |