diff options
author | Dick Kennedy | 2017-09-30 02:34:34 +0200 |
---|---|---|
committer | Martin K. Petersen | 2017-10-03 04:46:36 +0200 |
commit | f485c18db27734b37003bf2fafd364234e763633 (patch) | |
tree | 35fb4cd9c0f5a7049c2892dc80aeae5cc555ef4a /drivers/scsi/lpfc/lpfc_init.c | |
parent | scsi: lpfc: Make ktime sampling more accurate (diff) | |
download | kernel-qcow2-linux-f485c18db27734b37003bf2fafd364234e763633.tar.gz kernel-qcow2-linux-f485c18db27734b37003bf2fafd364234e763633.tar.xz kernel-qcow2-linux-f485c18db27734b37003bf2fafd364234e763633.zip |
scsi: lpfc: Move CQ processing to a soft IRQ
Under heavy target nvme load duration, the lpfc irq handler is
encountering cpu lockup warnings.
Convert the driver to a shortened ISR handler which identifies the
interrupting condition then schedules a workq thread to process the
completion queue the interrupt was for. This moves all the real work
into the workq element.
As nvmet_fc upcalls are no longer in ISR context, don't set the feature
flags
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b50c3b559a7a..4ffdde5808ee 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3216,6 +3216,9 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_destroy_vport_work_array(phba, vports); lpfc_sli_mbox_sys_shutdown(phba, mbx_action); + + if (phba->wq) + flush_workqueue(phba->wq); } /** @@ -4176,6 +4179,9 @@ void lpfc_stop_port(struct lpfc_hba *phba) { phba->lpfc_stop_port(phba); + + if (phba->wq) + flush_workqueue(phba->wq); } /** @@ -6369,6 +6375,9 @@ lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba) return error; } + /* workqueue for deferred irq use */ + phba->wq = alloc_workqueue("lpfc_wq", WQ_MEM_RECLAIM, 0); + return 0; } @@ -6383,6 +6392,12 @@ lpfc_setup_driver_resource_phase2(struct lpfc_hba *phba) static void lpfc_unset_driver_resource_phase2(struct lpfc_hba *phba) { + if (phba->wq) { + flush_workqueue(phba->wq); + destroy_workqueue(phba->wq); + phba->wq = NULL; + } + /* Stop kernel worker thread */ kthread_stop(phba->worker_thread); } |