diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ba17a8f740a9..a56f01f659f8 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5373,8 +5373,10 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, */ if (!(phba->hba_flag & HBA_FCOE_MODE)) { rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) + if (rc == MBX_NOT_FINISHED) { + lpfc_mbuf_free(phba, mp->virt, mp->phys); goto out_free_dmabuf; + } return; } /* @@ -5925,7 +5927,7 @@ lpfc_cmf_timer(struct hrtimer *timer) uint32_t io_cnt; uint32_t head, tail; uint32_t busy, max_read; - uint64_t total, rcv, lat, mbpi, extra; + uint64_t total, rcv, lat, mbpi, extra, cnt; int timer_interval = LPFC_CMF_INTERVAL; uint32_t ms; struct lpfc_cgn_stat *cgs; @@ -5996,20 +5998,28 @@ lpfc_cmf_timer(struct hrtimer *timer) /* Calculate any extra bytes needed to account for the * timer accuracy. If we are less than LPFC_CMF_INTERVAL - * add an extra 3% slop factor, equal to LPFC_CMF_INTERVAL - * add an extra 2%. The goal is to equalize total with a - * time > LPFC_CMF_INTERVAL or <= LPFC_CMF_INTERVAL + 1 + * calculate the adjustment needed for total to reflect + * a full LPFC_CMF_INTERVAL. */ - if (ms == LPFC_CMF_INTERVAL) - extra = div_u64(total, 50); - else if (ms < LPFC_CMF_INTERVAL) - extra = div_u64(total, 33); + if (ms && ms < LPFC_CMF_INTERVAL) { + cnt = div_u64(total, ms); /* bytes per ms */ + cnt *= LPFC_CMF_INTERVAL; /* what total should be */ + + /* If the timeout is scheduled to be shorter, + * this value may skew the data, so cap it at mbpi. + */ + if ((phba->hba_flag & HBA_SHORT_CMF) && cnt > mbpi) + cnt = mbpi; + + extra = cnt - total; + } lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra); } else { /* For Monitor mode or link down we want mbpi * to be the full link speed */ mbpi = phba->cmf_link_byte_count; + extra = 0; } phba->cmf_timer_cnt++; @@ -6040,6 +6050,7 @@ lpfc_cmf_timer(struct hrtimer *timer) LPFC_RXMONITOR_TABLE_IN_USE); entry = &phba->rxtable[head]; entry->total_bytes = total; + entry->cmf_bytes = total + extra; entry->rcv_bytes = rcv; entry->cmf_busy = busy; entry->cmf_info = phba->cmf_active_info; @@ -6082,6 +6093,8 @@ lpfc_cmf_timer(struct hrtimer *timer) /* Each minute save Fabric and Driver congestion information */ lpfc_cgn_save_evt_cnt(phba); + phba->hba_flag &= ~HBA_SHORT_CMF; + /* Since we need to call lpfc_cgn_save_evt_cnt every minute, on the * minute, adjust our next timer interval, if needed, to ensure a * 1 minute granularity when we get the next timer interrupt. @@ -6092,6 +6105,8 @@ lpfc_cmf_timer(struct hrtimer *timer) jiffies); if (timer_interval <= 0) timer_interval = LPFC_CMF_INTERVAL; + else + phba->hba_flag |= HBA_SHORT_CMF; /* If we adjust timer_interval, max_bytes_per_interval * needs to be adjusted as well. @@ -6337,8 +6352,10 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) } rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) + if (rc == MBX_NOT_FINISHED) { + lpfc_mbuf_free(phba, mp->virt, mp->phys); goto out_free_dmabuf; + } return; out_free_dmabuf: @@ -12709,7 +12726,7 @@ lpfc_irq_set_aff(struct lpfc_hba_eq_hdl *eqhdl, unsigned int cpu) cpumask_clear(&eqhdl->aff_mask); cpumask_set_cpu(cpu, &eqhdl->aff_mask); irq_set_status_flags(eqhdl->irq, IRQ_NO_BALANCING); - irq_set_affinity_hint(eqhdl->irq, &eqhdl->aff_mask); + irq_set_affinity(eqhdl->irq, &eqhdl->aff_mask); } /** @@ -12998,7 +13015,6 @@ cfg_fail_out: for (--index; index >= 0; index--) { eqhdl = lpfc_get_eq_hdl(index); lpfc_irq_clear_aff(eqhdl); - irq_set_affinity_hint(eqhdl->irq, NULL); free_irq(eqhdl->irq, eqhdl); } @@ -13159,7 +13175,6 @@ lpfc_sli4_disable_intr(struct lpfc_hba *phba) for (index = 0; index < phba->cfg_irq_chann; index++) { eqhdl = lpfc_get_eq_hdl(index); lpfc_irq_clear_aff(eqhdl); - irq_set_affinity_hint(eqhdl->irq, NULL); free_irq(eqhdl->irq, eqhdl); } } else { @@ -13466,7 +13481,7 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba) phba->cgn_evt_minute = 0; phba->hba_flag &= ~HBA_CGN_DAY_WRAP; - memset(cp, 0xff, LPFC_CGN_DATA_SIZE); + memset(cp, 0xff, offsetof(struct lpfc_cgn_info, cgn_stat)); cp->cgn_info_size = cpu_to_le16(LPFC_CGN_INFO_SZ); cp->cgn_info_version = LPFC_CGN_INFO_V3; @@ -13525,7 +13540,7 @@ lpfc_init_congestion_stat(struct lpfc_hba *phba) return; cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; - memset(&cp->cgn_stat_npm, 0, LPFC_CGN_STAT_SIZE); + memset(&cp->cgn_stat, 0, sizeof(cp->cgn_stat)); ktime_get_real_ts64(&cmpl_time); time64_to_tm(cmpl_time.tv_sec, 0, &broken); |