diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 53 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 19 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 1 |
5 files changed, 77 insertions, 13 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 5fbdb22c1899..0a337dab211c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -893,11 +893,14 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
893 | 893 | ||
894 | if (!rc) { | 894 | if (!rc) { |
895 | /* Mark the FCF discovery process done */ | 895 | /* Mark the FCF discovery process done */ |
896 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS, | 896 | if (phba->hba_flag & HBA_FIP_SUPPORT) |
897 | "2769 FLOGI successful on FCF record: " | 897 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | |
898 | "current_fcf_index:x%x, terminate FCF " | 898 | LOG_ELS, |
899 | "round robin failover process\n", | 899 | "2769 FLOGI successful on FCF " |
900 | phba->fcf.current_rec.fcf_indx); | 900 | "record: current_fcf_index:" |
901 | "x%x, terminate FCF round " | ||
902 | "robin failover process\n", | ||
903 | phba->fcf.current_rec.fcf_indx); | ||
901 | spin_lock_irq(&phba->hbalock); | 904 | spin_lock_irq(&phba->hbalock); |
902 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | 905 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; |
903 | spin_unlock_irq(&phba->hbalock); | 906 | spin_unlock_irq(&phba->hbalock); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e1466eec56b7..362730b6dd85 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1531,7 +1531,37 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
1531 | } | 1531 | } |
1532 | 1532 | ||
1533 | /** | 1533 | /** |
1534 | * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command | 1534 | * lpfc_sli4_new_fcf_random_select - Randomly select an eligible new fcf record |
1535 | * @phba: pointer to lpfc hba data structure. | ||
1536 | * @fcf_cnt: number of eligible fcf record seen so far. | ||
1537 | * | ||
1538 | * This function makes an running random selection decision on FCF record to | ||
1539 | * use through a sequence of @fcf_cnt eligible FCF records with equal | ||
1540 | * probability. To perform integer manunipulation of random numbers with | ||
1541 | * size unit32_t, the lower 16 bits of the 32-bit random number returned | ||
1542 | * from random32() are taken as the random random number generated. | ||
1543 | * | ||
1544 | * Returns true when outcome is for the newly read FCF record should be | ||
1545 | * chosen; otherwise, return false when outcome is for keeping the previously | ||
1546 | * chosen FCF record. | ||
1547 | **/ | ||
1548 | static bool | ||
1549 | lpfc_sli4_new_fcf_random_select(struct lpfc_hba *phba, uint32_t fcf_cnt) | ||
1550 | { | ||
1551 | uint32_t rand_num; | ||
1552 | |||
1553 | /* Get 16-bit uniform random number */ | ||
1554 | rand_num = (0xFFFF & random32()); | ||
1555 | |||
1556 | /* Decision with probability 1/fcf_cnt */ | ||
1557 | if ((fcf_cnt * rand_num) < 0xFFFF) | ||
1558 | return true; | ||
1559 | else | ||
1560 | return false; | ||
1561 | } | ||
1562 | |||
1563 | /** | ||
1564 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | ||
1535 | * @phba: pointer to lpfc hba data structure. | 1565 | * @phba: pointer to lpfc hba data structure. |
1536 | * @mboxq: pointer to mailbox object. | 1566 | * @mboxq: pointer to mailbox object. |
1537 | * @next_fcf_index: pointer to holder of next fcf index. | 1567 | * @next_fcf_index: pointer to holder of next fcf index. |
@@ -1679,6 +1709,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1679 | uint16_t fcf_index, next_fcf_index; | 1709 | uint16_t fcf_index, next_fcf_index; |
1680 | struct lpfc_fcf_rec *fcf_rec = NULL; | 1710 | struct lpfc_fcf_rec *fcf_rec = NULL; |
1681 | uint16_t vlan_id; | 1711 | uint16_t vlan_id; |
1712 | uint32_t seed; | ||
1713 | bool select_new_fcf; | ||
1682 | int rc; | 1714 | int rc; |
1683 | 1715 | ||
1684 | /* If there is pending FCoE event restart FCF table scan */ | 1716 | /* If there is pending FCoE event restart FCF table scan */ |
@@ -1809,9 +1841,21 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1809 | * than the driver FCF record, use the new record. | 1841 | * than the driver FCF record, use the new record. |
1810 | */ | 1842 | */ |
1811 | if (new_fcf_record->fip_priority < fcf_rec->priority) { | 1843 | if (new_fcf_record->fip_priority < fcf_rec->priority) { |
1812 | /* Choose this FCF record */ | 1844 | /* Choose the new FCF record with lower priority */ |
1813 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, | 1845 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1814 | addr_mode, vlan_id, 0); | 1846 | addr_mode, vlan_id, 0); |
1847 | /* Reset running random FCF selection count */ | ||
1848 | phba->fcf.eligible_fcf_cnt = 1; | ||
1849 | } else if (new_fcf_record->fip_priority == fcf_rec->priority) { | ||
1850 | /* Update running random FCF selection count */ | ||
1851 | phba->fcf.eligible_fcf_cnt++; | ||
1852 | select_new_fcf = lpfc_sli4_new_fcf_random_select(phba, | ||
1853 | phba->fcf.eligible_fcf_cnt); | ||
1854 | if (select_new_fcf) | ||
1855 | /* Choose the new FCF by random selection */ | ||
1856 | __lpfc_update_fcf_record(phba, fcf_rec, | ||
1857 | new_fcf_record, | ||
1858 | addr_mode, vlan_id, 0); | ||
1815 | } | 1859 | } |
1816 | spin_unlock_irq(&phba->hbalock); | 1860 | spin_unlock_irq(&phba->hbalock); |
1817 | goto read_next_fcf; | 1861 | goto read_next_fcf; |
@@ -1825,6 +1869,11 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1825 | addr_mode, vlan_id, (boot_flag ? | 1869 | addr_mode, vlan_id, (boot_flag ? |
1826 | BOOT_ENABLE : 0)); | 1870 | BOOT_ENABLE : 0)); |
1827 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1871 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1872 | /* Setup initial running random FCF selection count */ | ||
1873 | phba->fcf.eligible_fcf_cnt = 1; | ||
1874 | /* Seeding the random number generator for random selection */ | ||
1875 | seed = (uint32_t)(0xFFFFFFFF & jiffies); | ||
1876 | srandom32(seed); | ||
1828 | } | 1877 | } |
1829 | spin_unlock_irq(&phba->hbalock); | 1878 | spin_unlock_irq(&phba->hbalock); |
1830 | goto read_next_fcf; | 1879 | goto read_next_fcf; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 774663e8e1fe..25ee8cc6ab7a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3304,11 +3304,20 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3304 | switch (event_type) { | 3304 | switch (event_type) { |
3305 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: | 3305 | case LPFC_FCOE_EVENT_TYPE_NEW_FCF: |
3306 | case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: | 3306 | case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: |
3307 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, | 3307 | if (event_type == LPFC_FCOE_EVENT_TYPE_NEW_FCF) |
3308 | "2546 New FCF found/FCF parameter modified event: " | 3308 | lpfc_printf_log(phba, KERN_ERR, LOG_FIP | |
3309 | "evt_tag:x%x, fcf_index:x%x\n", | 3309 | LOG_DISCOVERY, |
3310 | acqe_fcoe->event_tag, acqe_fcoe->index); | 3310 | "2546 New FCF found event: " |
3311 | 3311 | "evt_tag:x%x, fcf_index:x%x\n", | |
3312 | acqe_fcoe->event_tag, | ||
3313 | acqe_fcoe->index); | ||
3314 | else | ||
3315 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | | ||
3316 | LOG_DISCOVERY, | ||
3317 | "2788 FCF parameter modified event: " | ||
3318 | "evt_tag:x%x, fcf_index:x%x\n", | ||
3319 | acqe_fcoe->event_tag, | ||
3320 | acqe_fcoe->index); | ||
3312 | spin_lock_irq(&phba->hbalock); | 3321 | spin_lock_irq(&phba->hbalock); |
3313 | if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || | 3322 | if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || |
3314 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { | 3323 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 049fb9a17b3f..2eff81d366f9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -12040,9 +12040,11 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) | |||
12040 | phba->hba_flag |= FCF_DISC_INPROGRESS; | 12040 | phba->hba_flag |= FCF_DISC_INPROGRESS; |
12041 | spin_unlock_irq(&phba->hbalock); | 12041 | spin_unlock_irq(&phba->hbalock); |
12042 | /* Reset FCF round robin index bmask for new scan */ | 12042 | /* Reset FCF round robin index bmask for new scan */ |
12043 | if (fcf_index == LPFC_FCOE_FCF_GET_FIRST) | 12043 | if (fcf_index == LPFC_FCOE_FCF_GET_FIRST) { |
12044 | memset(phba->fcf.fcf_rr_bmask, 0, | 12044 | memset(phba->fcf.fcf_rr_bmask, 0, |
12045 | sizeof(*phba->fcf.fcf_rr_bmask)); | 12045 | sizeof(*phba->fcf.fcf_rr_bmask)); |
12046 | phba->fcf.eligible_fcf_cnt = 0; | ||
12047 | } | ||
12046 | error = 0; | 12048 | error = 0; |
12047 | } | 12049 | } |
12048 | fail_fcf_scan: | 12050 | fail_fcf_scan: |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 4a35e7b9bc5b..5b6cb9742c58 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -162,6 +162,7 @@ struct lpfc_fcf { | |||
162 | #define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */ | 162 | #define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */ |
163 | uint32_t addr_mode; | 163 | uint32_t addr_mode; |
164 | uint16_t fcf_rr_init_indx; | 164 | uint16_t fcf_rr_init_indx; |
165 | uint32_t eligible_fcf_cnt; | ||
165 | struct lpfc_fcf_rec current_rec; | 166 | struct lpfc_fcf_rec current_rec; |
166 | struct lpfc_fcf_rec failover_rec; | 167 | struct lpfc_fcf_rec failover_rec; |
167 | struct timer_list redisc_wait; | 168 | struct timer_list redisc_wait; |