@@ -506,6 +506,7 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc)
506
506
psb -> status = IOSTAT_SUCCESS ;
507
507
/* Put it back into the SCSI buffer list */
508
508
psb -> cur_iocbq .context1 = psb ;
509
+ spin_lock_init (& psb -> buf_lock );
509
510
lpfc_release_scsi_buf_s3 (phba , psb );
510
511
511
512
}
@@ -712,7 +713,6 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
712
713
lpfc_cmd -> cur_iocbq .iocb_flag = LPFC_IO_FCP ;
713
714
lpfc_cmd -> prot_seg_cnt = 0 ;
714
715
lpfc_cmd -> seg_cnt = 0 ;
715
- lpfc_cmd -> waitq = NULL ;
716
716
lpfc_cmd -> timeout = 0 ;
717
717
lpfc_cmd -> flags = 0 ;
718
718
lpfc_cmd -> start_time = jiffies ;
@@ -3651,10 +3651,17 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
3651
3651
int cpu ;
3652
3652
#endif
3653
3653
3654
+ /* Guard against abort handler being called at same time */
3655
+ spin_lock (& lpfc_cmd -> buf_lock );
3656
+
3654
3657
/* Sanity check on return of outstanding command */
3655
3658
cmd = lpfc_cmd -> pCmd ;
3656
- if (!cmd )
3659
+ if (!cmd ) {
3660
+ lpfc_printf_vlog (vport , KERN_ERR , LOG_INIT ,
3661
+ "2621 IO completion: Not an active IO\n" );
3662
+ spin_unlock (& lpfc_cmd -> buf_lock );
3657
3663
return ;
3664
+ }
3658
3665
3659
3666
idx = lpfc_cmd -> cur_iocbq .hba_wqidx ;
3660
3667
if (phba -> sli4_hba .hdwq )
@@ -3860,29 +3867,24 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
3860
3867
}
3861
3868
lpfc_scsi_unprep_dma_buf (phba , lpfc_cmd );
3862
3869
3863
- /* If pCmd was set to NULL from abort path, do not call scsi_done */
3864
- if (xchg (& lpfc_cmd -> pCmd , NULL ) == NULL ) {
3865
- lpfc_printf_vlog (vport , KERN_INFO , LOG_FCP ,
3866
- "5688 FCP cmd already NULL, sid: 0x%06x, "
3867
- "did: 0x%06x, oxid: 0x%04x\n" ,
3868
- vport -> fc_myDID ,
3869
- (pnode ) ? pnode -> nlp_DID : 0 ,
3870
- phba -> sli_rev == LPFC_SLI_REV4 ?
3871
- lpfc_cmd -> cur_iocbq .sli4_xritag : 0xffff );
3872
- return ;
3873
- }
3870
+ lpfc_cmd -> pCmd = NULL ;
3871
+ spin_unlock (& lpfc_cmd -> buf_lock );
3874
3872
3875
3873
/* The sdev is not guaranteed to be valid post scsi_done upcall. */
3876
3874
cmd -> scsi_done (cmd );
3877
3875
3878
3876
/*
3879
- * If there is a thread waiting for command completion
3877
+ * If there is an abort thread waiting for command completion
3880
3878
* wake up the thread.
3881
3879
*/
3882
- spin_lock_irqsave (shost -> host_lock , flags );
3883
- if (lpfc_cmd -> waitq )
3884
- wake_up (lpfc_cmd -> waitq );
3885
- spin_unlock_irqrestore (shost -> host_lock , flags );
3880
+ spin_lock (& lpfc_cmd -> buf_lock );
3881
+ if (unlikely (lpfc_cmd -> cur_iocbq .iocb_flag & LPFC_DRIVER_ABORTED )) {
3882
+ lpfc_cmd -> cur_iocbq .iocb_flag &= ~LPFC_DRIVER_ABORTED ;
3883
+ if (lpfc_cmd -> waitq )
3884
+ wake_up (lpfc_cmd -> waitq );
3885
+ lpfc_cmd -> waitq = NULL ;
3886
+ }
3887
+ spin_unlock (& lpfc_cmd -> buf_lock );
3886
3888
3887
3889
lpfc_release_scsi_buf (phba , lpfc_cmd );
3888
3890
}
@@ -4563,44 +4565,47 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4563
4565
if (status != 0 && status != SUCCESS )
4564
4566
return status ;
4565
4567
4568
+ lpfc_cmd = (struct lpfc_io_buf * )cmnd -> host_scribble ;
4569
+ if (!lpfc_cmd )
4570
+ return ret ;
4571
+
4566
4572
spin_lock_irqsave (& phba -> hbalock , flags );
4567
4573
/* driver queued commands are in process of being flushed */
4568
4574
if (phba -> hba_flag & HBA_FCP_IOQ_FLUSH ) {
4569
- spin_unlock_irqrestore (& phba -> hbalock , flags );
4570
4575
lpfc_printf_vlog (vport , KERN_WARNING , LOG_FCP ,
4571
4576
"3168 SCSI Layer abort requested I/O has been "
4572
4577
"flushed by LLD.\n" );
4573
- return FAILED ;
4578
+ ret = FAILED ;
4579
+ goto out_unlock ;
4574
4580
}
4575
4581
4576
- lpfc_cmd = (struct lpfc_io_buf * )cmnd -> host_scribble ;
4577
- if (!lpfc_cmd || !lpfc_cmd -> pCmd ) {
4578
- spin_unlock_irqrestore (& phba -> hbalock , flags );
4582
+ /* Guard against IO completion being called at same time */
4583
+ spin_lock (& lpfc_cmd -> buf_lock );
4584
+
4585
+ if (!lpfc_cmd -> pCmd ) {
4579
4586
lpfc_printf_vlog (vport , KERN_WARNING , LOG_FCP ,
4580
4587
"2873 SCSI Layer I/O Abort Request IO CMPL Status "
4581
4588
"x%x ID %d LUN %llu\n" ,
4582
4589
SUCCESS , cmnd -> device -> id , cmnd -> device -> lun );
4583
- return SUCCESS ;
4590
+ goto out_unlock_buf ;
4584
4591
}
4585
4592
4586
4593
iocb = & lpfc_cmd -> cur_iocbq ;
4587
4594
if (phba -> sli_rev == LPFC_SLI_REV4 ) {
4588
4595
pring_s4 = phba -> sli4_hba .hdwq [iocb -> hba_wqidx ].fcp_wq -> pring ;
4589
4596
if (!pring_s4 ) {
4590
4597
ret = FAILED ;
4591
- goto out_unlock ;
4598
+ goto out_unlock_buf ;
4592
4599
}
4593
4600
spin_lock (& pring_s4 -> ring_lock );
4594
4601
}
4595
4602
/* the command is in process of being cancelled */
4596
4603
if (!(iocb -> iocb_flag & LPFC_IO_ON_TXCMPLQ )) {
4597
- if (phba -> sli_rev == LPFC_SLI_REV4 )
4598
- spin_unlock (& pring_s4 -> ring_lock );
4599
- spin_unlock_irqrestore (& phba -> hbalock , flags );
4600
4604
lpfc_printf_vlog (vport , KERN_WARNING , LOG_FCP ,
4601
4605
"3169 SCSI Layer abort requested I/O has been "
4602
4606
"cancelled by LLD.\n" );
4603
- return FAILED ;
4607
+ ret = FAILED ;
4608
+ goto out_unlock_ring ;
4604
4609
}
4605
4610
/*
4606
4611
* If pCmd field of the corresponding lpfc_io_buf structure
@@ -4609,12 +4614,10 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4609
4614
* see the completion before the eh fired. Just return SUCCESS.
4610
4615
*/
4611
4616
if (lpfc_cmd -> pCmd != cmnd ) {
4612
- if (phba -> sli_rev == LPFC_SLI_REV4 )
4613
- spin_unlock (& pring_s4 -> ring_lock );
4614
4617
lpfc_printf_vlog (vport , KERN_WARNING , LOG_FCP ,
4615
4618
"3170 SCSI Layer abort requested I/O has been "
4616
4619
"completed by LLD.\n" );
4617
- goto out_unlock ;
4620
+ goto out_unlock_ring ;
4618
4621
}
4619
4622
4620
4623
BUG_ON (iocb -> context1 != lpfc_cmd );
@@ -4625,16 +4628,15 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4625
4628
"3389 SCSI Layer I/O Abort Request is pending\n" );
4626
4629
if (phba -> sli_rev == LPFC_SLI_REV4 )
4627
4630
spin_unlock (& pring_s4 -> ring_lock );
4631
+ spin_unlock (& lpfc_cmd -> buf_lock );
4628
4632
spin_unlock_irqrestore (& phba -> hbalock , flags );
4629
4633
goto wait_for_cmpl ;
4630
4634
}
4631
4635
4632
4636
abtsiocb = __lpfc_sli_get_iocbq (phba );
4633
4637
if (abtsiocb == NULL ) {
4634
4638
ret = FAILED ;
4635
- if (phba -> sli_rev == LPFC_SLI_REV4 )
4636
- spin_unlock (& pring_s4 -> ring_lock );
4637
- goto out_unlock ;
4639
+ goto out_unlock_ring ;
4638
4640
}
4639
4641
4640
4642
/* Indicate the IO is being aborted by the driver. */
@@ -4684,24 +4686,18 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4684
4686
/* no longer need the lock after this point */
4685
4687
spin_unlock_irqrestore (& phba -> hbalock , flags );
4686
4688
4687
-
4688
4689
if (ret_val == IOCB_ERROR ) {
4689
- if (phba -> sli_rev == LPFC_SLI_REV4 )
4690
- spin_lock_irqsave (& pring_s4 -> ring_lock , flags );
4691
- else
4692
- spin_lock_irqsave (& phba -> hbalock , flags );
4693
4690
/* Indicate the IO is not being aborted by the driver. */
4694
4691
iocb -> iocb_flag &= ~LPFC_DRIVER_ABORTED ;
4695
4692
lpfc_cmd -> waitq = NULL ;
4696
- if (phba -> sli_rev == LPFC_SLI_REV4 )
4697
- spin_unlock_irqrestore (& pring_s4 -> ring_lock , flags );
4698
- else
4699
- spin_unlock_irqrestore (& phba -> hbalock , flags );
4693
+ spin_unlock (& lpfc_cmd -> buf_lock );
4700
4694
lpfc_sli_release_iocbq (phba , abtsiocb );
4701
4695
ret = FAILED ;
4702
4696
goto out ;
4703
4697
}
4704
4698
4699
+ spin_unlock (& lpfc_cmd -> buf_lock );
4700
+
4705
4701
if (phba -> cfg_poll & DISABLE_FCP_RING_INT )
4706
4702
lpfc_sli_handle_fast_ring_event (phba ,
4707
4703
& phba -> sli .sli3_ring [LPFC_FCP_RING ], HA_R0RE_REQ );
@@ -4712,9 +4708,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4712
4708
(lpfc_cmd -> pCmd != cmnd ),
4713
4709
msecs_to_jiffies (2 * vport -> cfg_devloss_tmo * 1000 ));
4714
4710
4715
- spin_lock_irqsave (shost -> host_lock , flags );
4716
- lpfc_cmd -> waitq = NULL ;
4717
- spin_unlock_irqrestore (shost -> host_lock , flags );
4711
+ spin_lock (& lpfc_cmd -> buf_lock );
4718
4712
4719
4713
if (lpfc_cmd -> pCmd == cmnd ) {
4720
4714
ret = FAILED ;
@@ -4725,8 +4719,14 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
4725
4719
iocb -> sli4_xritag , ret ,
4726
4720
cmnd -> device -> id , cmnd -> device -> lun );
4727
4721
}
4722
+ spin_unlock (& lpfc_cmd -> buf_lock );
4728
4723
goto out ;
4729
4724
4725
+ out_unlock_ring :
4726
+ if (phba -> sli_rev == LPFC_SLI_REV4 )
4727
+ spin_unlock (& pring_s4 -> ring_lock );
4728
+ out_unlock_buf :
4729
+ spin_unlock (& lpfc_cmd -> buf_lock );
4730
4730
out_unlock :
4731
4731
spin_unlock_irqrestore (& phba -> hbalock , flags );
4732
4732
out :
0 commit comments