@@ -12485,15 +12485,54 @@ lpfc_sli_hba_iocb_abort(struct lpfc_hba *phba)
12485
12485
}
12486
12486
12487
12487
/**
12488
- * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN
12488
+ * lpfc_sli_validate_fcp_iocb_for_abort - filter iocbs appropriate for FCP aborts
12489
+ * @iocbq: Pointer to iocb object.
12490
+ * @vport: Pointer to driver virtual port object.
12491
+ *
12492
+ * This function acts as an iocb filter for functions which abort FCP iocbs.
12493
+ *
12494
+ * Return values
12495
+ * -ENODEV, if a null iocb or vport ptr is encountered
12496
+ * -EINVAL, if the iocb is not an FCP I/O, not on the TX cmpl queue, premarked as
12497
+ * driver already started the abort process, or is an abort iocb itself
12498
+ * 0, passes criteria for aborting the FCP I/O iocb
12499
+ **/
12500
+ static int
12501
+ lpfc_sli_validate_fcp_iocb_for_abort(struct lpfc_iocbq *iocbq,
12502
+ struct lpfc_vport *vport)
12503
+ {
12504
+ IOCB_t *icmd = NULL;
12505
+
12506
+ /* No null ptr vports */
12507
+ if (!iocbq || iocbq->vport != vport)
12508
+ return -ENODEV;
12509
+
12510
+ /* iocb must be for FCP IO, already exists on the TX cmpl queue,
12511
+ * can't be premarked as driver aborted, nor be an ABORT iocb itself
12512
+ */
12513
+ icmd = &iocbq->iocb;
12514
+ if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
12515
+ !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) ||
12516
+ (iocbq->iocb_flag & LPFC_DRIVER_ABORTED) ||
12517
+ (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
12518
+ icmd->ulpCommand == CMD_CLOSE_XRI_CN))
12519
+ return -EINVAL;
12520
+
12521
+ return 0;
12522
+ }
12523
+
12524
+ /**
12525
+ * lpfc_sli_validate_fcp_iocb - validate commands associated with a SCSI target
12489
12526
* @iocbq: Pointer to driver iocb object.
12490
12527
* @vport: Pointer to driver virtual port object.
12491
12528
* @tgt_id: SCSI ID of the target.
12492
12529
* @lun_id: LUN ID of the scsi device.
12493
12530
* @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST
12494
12531
*
12495
- * This function acts as an iocb filter for functions which abort or count
12496
- * all FCP iocbs pending on a lun/SCSI target/SCSI host. It will return
12532
+ * This function acts as an iocb filter for validating a lun/SCSI target/SCSI
12533
+ * host.
12534
+ *
12535
+ * It will return
12497
12536
* 0 if the filtering criteria is met for the given iocb and will return
12498
12537
* 1 if the filtering criteria is not met.
12499
12538
* If ctx_cmd == LPFC_CTX_LUN, the function returns 0 only if the
@@ -12512,22 +12551,8 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
12512
12551
lpfc_ctx_cmd ctx_cmd)
12513
12552
{
12514
12553
struct lpfc_io_buf *lpfc_cmd;
12515
- IOCB_t *icmd = NULL;
12516
12554
int rc = 1;
12517
12555
12518
- if (!iocbq || iocbq->vport != vport)
12519
- return rc;
12520
-
12521
- if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
12522
- !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) ||
12523
- iocbq->iocb_flag & LPFC_DRIVER_ABORTED)
12524
- return rc;
12525
-
12526
- icmd = &iocbq->iocb;
12527
- if (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
12528
- icmd->ulpCommand == CMD_CLOSE_XRI_CN)
12529
- return rc;
12530
-
12531
12556
lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
12532
12557
12533
12558
if (lpfc_cmd->pCmd == NULL)
@@ -12582,17 +12607,33 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id,
12582
12607
{
12583
12608
struct lpfc_hba *phba = vport->phba;
12584
12609
struct lpfc_iocbq *iocbq;
12610
+ IOCB_t *icmd = NULL;
12585
12611
int sum, i;
12612
+ unsigned long iflags;
12586
12613
12587
- spin_lock_irq (&phba->hbalock);
12614
+ spin_lock_irqsave (&phba->hbalock, iflags );
12588
12615
for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) {
12589
12616
iocbq = phba->sli.iocbq_lookup[i];
12590
12617
12591
- if (lpfc_sli_validate_fcp_iocb (iocbq, vport, tgt_id, lun_id,
12592
- ctx_cmd) == 0)
12618
+ if (!iocbq || iocbq->vport != vport)
12619
+ continue;
12620
+ if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
12621
+ !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ))
12622
+ continue;
12623
+
12624
+ /* Include counting outstanding aborts */
12625
+ icmd = &iocbq->iocb;
12626
+ if (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
12627
+ icmd->ulpCommand == CMD_CLOSE_XRI_CN) {
12628
+ sum++;
12629
+ continue;
12630
+ }
12631
+
12632
+ if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id,
12633
+ ctx_cmd) == 0)
12593
12634
sum++;
12594
12635
}
12595
- spin_unlock_irq (&phba->hbalock);
12636
+ spin_unlock_irqrestore (&phba->hbalock, iflags );
12596
12637
12597
12638
return sum;
12598
12639
}
@@ -12659,7 +12700,11 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
12659
12700
*
12660
12701
* This function sends an abort command for every SCSI command
12661
12702
* associated with the given virtual port pending on the ring
12662
- * filtered by lpfc_sli_validate_fcp_iocb function.
12703
+ * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then
12704
+ * lpfc_sli_validate_fcp_iocb function. The ordering for validation before
12705
+ * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort
12706
+ * followed by lpfc_sli_validate_fcp_iocb.
12707
+ *
12663
12708
* When abort_cmd == LPFC_CTX_LUN, the function sends abort only to the
12664
12709
* FCP iocbs associated with lun specified by tgt_id and lun_id
12665
12710
* parameters
@@ -12691,6 +12736,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id,
12691
12736
for (i = 1; i <= phba->sli.last_iotag; i++) {
12692
12737
iocbq = phba->sli.iocbq_lookup[i];
12693
12738
12739
+ if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport))
12740
+ continue;
12741
+
12694
12742
if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id,
12695
12743
abort_cmd) != 0)
12696
12744
continue;
@@ -12723,7 +12771,11 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id,
12723
12771
*
12724
12772
* This function sends an abort command for every SCSI command
12725
12773
* associated with the given virtual port pending on the ring
12726
- * filtered by lpfc_sli_validate_fcp_iocb function.
12774
+ * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then
12775
+ * lpfc_sli_validate_fcp_iocb function. The ordering for validation before
12776
+ * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort
12777
+ * followed by lpfc_sli_validate_fcp_iocb.
12778
+ *
12727
12779
* When taskmgmt_cmd == LPFC_CTX_LUN, the function sends abort only to the
12728
12780
* FCP iocbs associated with lun specified by tgt_id and lun_id
12729
12781
* parameters
@@ -12761,6 +12813,9 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
12761
12813
for (i = 1; i <= phba->sli.last_iotag; i++) {
12762
12814
iocbq = phba->sli.iocbq_lookup[i];
12763
12815
12816
+ if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport))
12817
+ continue;
12818
+
12764
12819
if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id,
12765
12820
cmd) != 0)
12766
12821
continue;
0 commit comments