Loading drivers/scsi/lpfc/lpfc.h +2 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,8 @@ struct lpfc_sli2_slim; #define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */ #define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */ #define LPFC_LOOK_AHEAD_OFF 0 /* Look ahead logic is turned off */ /* Error Attention event polling interval */ #define LPFC_ERATT_POLL_INTERVAL 5 /* EATT poll interval in seconds */ Loading drivers/scsi/lpfc/lpfc_attr.c +11 −0 Original line number Diff line number Diff line Loading @@ -3917,6 +3917,17 @@ LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat."); */ LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); /* # lpfc_fcp_look_ahead: Look ahead for completions in FCP start routine # 0 = disabled (default) # 1 = enabled # Value range is [0,1]. Default value is 0. */ unsigned int lpfc_fcp_look_ahead = LPFC_LOOK_AHEAD_OFF; module_param(lpfc_fcp_look_ahead, uint, S_IRUGO); MODULE_PARM_DESC(lpfc_fcp_look_ahead, "Look ahead for completions"); /* # lpfc_prot_mask: i # - Bit mask of host protection capabilities used to register with the Loading drivers/scsi/lpfc/lpfc_crtn.h +1 −0 Original line number Diff line number Diff line Loading @@ -390,6 +390,7 @@ extern spinlock_t pgcnt_lock; extern unsigned int pgcnt; extern unsigned int lpfc_prot_mask; extern unsigned char lpfc_prot_guard; extern unsigned int lpfc_fcp_look_ahead; /* Interface exported by fabric iocb scheduler */ void lpfc_fabric_abort_nport(struct lpfc_nodelist *); Loading drivers/scsi/lpfc/lpfc_init.c +3 −0 Original line number Diff line number Diff line Loading @@ -8111,6 +8111,7 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) phba->sli4_hba.fcp_eq_hdl[index].idx = index; phba->sli4_hba.fcp_eq_hdl[index].phba = phba; atomic_set(&phba->sli4_hba.fcp_eq_hdl[index].fcp_eq_in_use, 1); rc = request_irq(phba->sli4_hba.msix_entries[index].vector, &lpfc_sli4_hba_intr_handler, IRQF_SHARED, (char *)&phba->sli4_hba.handler_name[index], Loading Loading @@ -8283,6 +8284,8 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) index++) { phba->sli4_hba.fcp_eq_hdl[index].idx = index; phba->sli4_hba.fcp_eq_hdl[index].phba = phba; atomic_set(&phba->sli4_hba.fcp_eq_hdl[index]. fcp_eq_in_use, 1); } } } Loading drivers/scsi/lpfc/lpfc_sli.c +84 −4 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ static int lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *, struct lpfc_queue *, struct lpfc_cqe *); static int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *, struct list_head *, int); static void lpfc_sli4_hba_handle_eqe(struct lpfc_hba *, struct lpfc_eqe *, uint32_t); static IOCB_t * lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) Loading Loading @@ -257,6 +259,25 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) return eqe; } /** * lpfc_sli4_eq_clr_intr - Turn off interrupts from this EQ * @q: The Event Queue to disable interrupts * **/ static inline void lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) { struct lpfc_register doorbell; doorbell.word0 = 0; bf_set(lpfc_eqcq_doorbell_eqci, &doorbell, 1); bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT); bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); } /** * lpfc_sli4_eq_release - Indicates the host has finished processing an EQ * @q: The Event Queue that the host has completed processing for. Loading Loading @@ -8422,7 +8443,10 @@ int lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, struct lpfc_iocbq *piocb, uint32_t flag) { struct lpfc_fcp_eq_hdl *fcp_eq_hdl; struct lpfc_sli_ring *pring; struct lpfc_queue *fpeq; struct lpfc_eqe *eqe; unsigned long iflags; int rc, idx; Loading @@ -8433,11 +8457,48 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, idx = lpfc_sli4_scmd_to_wqidx_distr(phba); piocb->fcp_wqidx = idx; ring_number = MAX_SLI3_CONFIGURED_RINGS + idx; pring = &phba->sli.ring[ring_number]; spin_lock_irqsave(&pring->ring_lock, iflags); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); spin_unlock_irqrestore(&pring->ring_lock, iflags); if (lpfc_fcp_look_ahead) { fcp_eq_hdl = &phba->sli4_hba.fcp_eq_hdl[idx]; if (atomic_dec_and_test(&fcp_eq_hdl-> fcp_eq_in_use)) { /* Get associated EQ with this index */ fpeq = phba->sli4_hba.hba_eq[idx]; /* Turn off interrupts from this EQ */ lpfc_sli4_eq_clr_intr(fpeq); /* * Process all the events on FCP EQ */ while ((eqe = lpfc_sli4_eq_get(fpeq))) { lpfc_sli4_hba_handle_eqe(phba, eqe, idx); fpeq->EQ_processed++; } /* Always clear and re-arm the EQ */ lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM); } atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); } } else { pring = &phba->sli.ring[ring_number]; spin_lock_irqsave(&pring->ring_lock, iflags); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); spin_unlock_irqrestore(&pring->ring_lock, iflags); } } else { /* For now, SLI2/3 will still use hbalock */ spin_lock_irqsave(&phba->hbalock, iflags); Loading Loading @@ -11854,6 +11915,15 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) if (unlikely(!fpeq)) return IRQ_NONE; if (lpfc_fcp_look_ahead) { if (atomic_dec_and_test(&fcp_eq_hdl->fcp_eq_in_use)) lpfc_sli4_eq_clr_intr(fpeq); else { atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_NONE; } } /* Check device state for handling interrupt */ if (unlikely(lpfc_intr_state_check(phba))) { fpeq->EQ_badstate++; Loading @@ -11863,6 +11933,8 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) /* Flush, clear interrupt, and rearm the EQ */ lpfc_sli4_eq_flush(phba, fpeq); spin_unlock_irqrestore(&phba->hbalock, iflag); if (lpfc_fcp_look_ahead) atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_NONE; } Loading @@ -11885,6 +11957,12 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) if (unlikely(ecount == 0)) { fpeq->EQ_no_entry++; if (lpfc_fcp_look_ahead) { atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_NONE; } if (phba->intr_type == MSIX) /* MSI-X treated interrupt served as no EQ share INT */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, Loading @@ -11894,6 +11972,8 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) return IRQ_NONE; } if (lpfc_fcp_look_ahead) atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_HANDLED; } /* lpfc_sli4_fp_intr_handler */ Loading Loading
drivers/scsi/lpfc/lpfc.h +2 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,8 @@ struct lpfc_sli2_slim; #define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */ #define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */ #define LPFC_LOOK_AHEAD_OFF 0 /* Look ahead logic is turned off */ /* Error Attention event polling interval */ #define LPFC_ERATT_POLL_INTERVAL 5 /* EATT poll interval in seconds */ Loading
drivers/scsi/lpfc/lpfc_attr.c +11 −0 Original line number Diff line number Diff line Loading @@ -3917,6 +3917,17 @@ LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat."); */ LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); /* # lpfc_fcp_look_ahead: Look ahead for completions in FCP start routine # 0 = disabled (default) # 1 = enabled # Value range is [0,1]. Default value is 0. */ unsigned int lpfc_fcp_look_ahead = LPFC_LOOK_AHEAD_OFF; module_param(lpfc_fcp_look_ahead, uint, S_IRUGO); MODULE_PARM_DESC(lpfc_fcp_look_ahead, "Look ahead for completions"); /* # lpfc_prot_mask: i # - Bit mask of host protection capabilities used to register with the Loading
drivers/scsi/lpfc/lpfc_crtn.h +1 −0 Original line number Diff line number Diff line Loading @@ -390,6 +390,7 @@ extern spinlock_t pgcnt_lock; extern unsigned int pgcnt; extern unsigned int lpfc_prot_mask; extern unsigned char lpfc_prot_guard; extern unsigned int lpfc_fcp_look_ahead; /* Interface exported by fabric iocb scheduler */ void lpfc_fabric_abort_nport(struct lpfc_nodelist *); Loading
drivers/scsi/lpfc/lpfc_init.c +3 −0 Original line number Diff line number Diff line Loading @@ -8111,6 +8111,7 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) phba->sli4_hba.fcp_eq_hdl[index].idx = index; phba->sli4_hba.fcp_eq_hdl[index].phba = phba; atomic_set(&phba->sli4_hba.fcp_eq_hdl[index].fcp_eq_in_use, 1); rc = request_irq(phba->sli4_hba.msix_entries[index].vector, &lpfc_sli4_hba_intr_handler, IRQF_SHARED, (char *)&phba->sli4_hba.handler_name[index], Loading Loading @@ -8283,6 +8284,8 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) index++) { phba->sli4_hba.fcp_eq_hdl[index].idx = index; phba->sli4_hba.fcp_eq_hdl[index].phba = phba; atomic_set(&phba->sli4_hba.fcp_eq_hdl[index]. fcp_eq_in_use, 1); } } } Loading
drivers/scsi/lpfc/lpfc_sli.c +84 −4 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ static int lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *, struct lpfc_queue *, struct lpfc_cqe *); static int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *, struct list_head *, int); static void lpfc_sli4_hba_handle_eqe(struct lpfc_hba *, struct lpfc_eqe *, uint32_t); static IOCB_t * lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) Loading Loading @@ -257,6 +259,25 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) return eqe; } /** * lpfc_sli4_eq_clr_intr - Turn off interrupts from this EQ * @q: The Event Queue to disable interrupts * **/ static inline void lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) { struct lpfc_register doorbell; doorbell.word0 = 0; bf_set(lpfc_eqcq_doorbell_eqci, &doorbell, 1); bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT); bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); } /** * lpfc_sli4_eq_release - Indicates the host has finished processing an EQ * @q: The Event Queue that the host has completed processing for. Loading Loading @@ -8422,7 +8443,10 @@ int lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, struct lpfc_iocbq *piocb, uint32_t flag) { struct lpfc_fcp_eq_hdl *fcp_eq_hdl; struct lpfc_sli_ring *pring; struct lpfc_queue *fpeq; struct lpfc_eqe *eqe; unsigned long iflags; int rc, idx; Loading @@ -8433,11 +8457,48 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, idx = lpfc_sli4_scmd_to_wqidx_distr(phba); piocb->fcp_wqidx = idx; ring_number = MAX_SLI3_CONFIGURED_RINGS + idx; pring = &phba->sli.ring[ring_number]; spin_lock_irqsave(&pring->ring_lock, iflags); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); spin_unlock_irqrestore(&pring->ring_lock, iflags); if (lpfc_fcp_look_ahead) { fcp_eq_hdl = &phba->sli4_hba.fcp_eq_hdl[idx]; if (atomic_dec_and_test(&fcp_eq_hdl-> fcp_eq_in_use)) { /* Get associated EQ with this index */ fpeq = phba->sli4_hba.hba_eq[idx]; /* Turn off interrupts from this EQ */ lpfc_sli4_eq_clr_intr(fpeq); /* * Process all the events on FCP EQ */ while ((eqe = lpfc_sli4_eq_get(fpeq))) { lpfc_sli4_hba_handle_eqe(phba, eqe, idx); fpeq->EQ_processed++; } /* Always clear and re-arm the EQ */ lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM); } atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); } } else { pring = &phba->sli.ring[ring_number]; spin_lock_irqsave(&pring->ring_lock, iflags); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); spin_unlock_irqrestore(&pring->ring_lock, iflags); } } else { /* For now, SLI2/3 will still use hbalock */ spin_lock_irqsave(&phba->hbalock, iflags); Loading Loading @@ -11854,6 +11915,15 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) if (unlikely(!fpeq)) return IRQ_NONE; if (lpfc_fcp_look_ahead) { if (atomic_dec_and_test(&fcp_eq_hdl->fcp_eq_in_use)) lpfc_sli4_eq_clr_intr(fpeq); else { atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_NONE; } } /* Check device state for handling interrupt */ if (unlikely(lpfc_intr_state_check(phba))) { fpeq->EQ_badstate++; Loading @@ -11863,6 +11933,8 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) /* Flush, clear interrupt, and rearm the EQ */ lpfc_sli4_eq_flush(phba, fpeq); spin_unlock_irqrestore(&phba->hbalock, iflag); if (lpfc_fcp_look_ahead) atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_NONE; } Loading @@ -11885,6 +11957,12 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) if (unlikely(ecount == 0)) { fpeq->EQ_no_entry++; if (lpfc_fcp_look_ahead) { atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_NONE; } if (phba->intr_type == MSIX) /* MSI-X treated interrupt served as no EQ share INT */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, Loading @@ -11894,6 +11972,8 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) return IRQ_NONE; } if (lpfc_fcp_look_ahead) atomic_inc(&fcp_eq_hdl->fcp_eq_in_use); return IRQ_HANDLED; } /* lpfc_sli4_fp_intr_handler */ Loading