lpfc 8.3.39: Fixed driver vector mapping to CPU affinity
Subsystems (2)
PATCH 18/22 lpfc 8.3.39: Fixed driver vector mapping to CPU affinity
Fixed driver vector mapping to CPU affinity
Signed-off-by James Smart <[email protected]>
---
lpfc.h | 1 lpfc_attr.c | 137 +++++++++++++++++++++++++ lpfc_hw4.h | 5 lpfc_init.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- lpfc_sli.c | 22 ++-- lpfc_sli4.h | 16 ++ 6 files changed, 488 insertions(+), 15 deletions(-)
drivers/scsi/lpfc/lpfc_attr.c +137 -0
@@ -3799,6 +3799,141 @@ lpfc_fcp_imax_init(struct lpfc_hba *phba static DEVICE_ATTR(lpfc_fcp_imax, S_IRUGO | S_IWUSR, lpfc_fcp_imax_show, lpfc_fcp_imax_store); +/** +* lpfc_state_show - Display current driver CPU affinity +* @dev: class converted to a Scsi_host structure. +* @attr: device attribute, not used. +* @buf: on return contains text describing the state of the link. +* +* Returns: size of formatted string. +**/ +static ssize_t +lpfc_fcp_cpu_map_show (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct Scsi_Host *shost =class_to_shost (dev); +struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; +struct lpfc_hba *phba = vport->phba; +struct lpfc_vector_map_info *cpup; +int idx, len =0 ; + +if ((phba->sli_rev !=LPFC_SLI_REV4 ) || + (phba->intr_type !=MSIX )) +return len; + +switch (phba->cfg_fcp_cpu_map) { +case 0 : + len +=snprintf (buf + len,PAGE_SIZE -len, +"fcp_cpu_map: No mapping (%d)\n" , + phba->cfg_fcp_cpu_map); +return len; +case 1 : + len +=snprintf (buf + len,PAGE_SIZE -len, +"fcp_cpu_map: HBA centric mapping (%d): " +"%d online CPUs\n" , + phba->cfg_fcp_cpu_map, + phba->sli4_hba.num_online_cpu); +break ; +case 2 : + len +=snprintf (buf + len,PAGE_SIZE -len, +"fcp_cpu_map: Driver centric mapping (%d): " +"%d online CPUs\n" , + phba->cfg_fcp_cpu_map, + phba->sli4_hba.num_online_cpu); +break ; + } + + cpup = phba->sli4_hba.cpu_map; +for (idx =0 ; idx < phba->sli4_hba.num_present_cpu; idx++) { +if (cpup->irq ==LPFC_VECTOR_MAP_EMPTY ) + len +=snprintf (buf + len,PAGE_SIZE -len, +"CPU %02d io_chan %02d " +"physid %d coreid %d\n" , + idx, cpup->channel_id, cpup->phys_id, + cpup->core_id); +else + len +=snprintf (buf + len,PAGE_SIZE -len, +"CPU %02d io_chan %02d " +"physid %d coreid %d IRQ %d\n" , + idx, cpup->channel_id, cpup->phys_id, + cpup->core_id, cpup->irq); + + cpup++; + } +return len; +} + +/** +* lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors +* @dev: class device that is converted into a Scsi_host. +* @attr: device attribute, not used. +* @buf: one or more lpfc_polling_flags values. +* @count: not used. +* +* Returns: +* -EINVAL - Not implemented yet. +**/ +static ssize_t +lpfc_fcp_cpu_map_store (struct device *dev,struct device_attribute *attr, +const char *buf,size_t count) +{ +int status = -EINVAL ; +return status; +} + +/* +# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors +# for the HBA. +# +# Value range is [0 to 2]. Default value is LPFC_DRIVER_CPU_MAP (2). +# 0 - Do not affinitze IRQ vectors +# 1 - Affintize HBA vectors with respect to each HBA +# (start with CPU0 for each HBA) +# 2 - Affintize HBA vectors with respect to the entire driver +# (round robin thru all CPUs across all HBAs) +*/ +static int lpfc_fcp_cpu_map =LPFC_DRIVER_CPU_MAP ; +module_param (lpfc_fcp_cpu_map, int,S_IRUGO |S_IWUSR ); +MODULE_PARM_DESC (lpfc_fcp_cpu_map, +"Defines how to map CPUs to IRQ vectors per HBA" ); + +/** +* lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable +* @phba: lpfc_hba pointer. +* @val: link speed value. +* +* Description: +* If val is in a valid range [0-2], then affinitze the adapter's +* MSIX vectors. +* +* Returns: +* zero if val saved. +* -EINVAL val out of range +**/ +static int +lpfc_fcp_cpu_map_init (struct lpfc_hba *phba,int val) +{ +if (phba->sli_rev !=LPFC_SLI_REV4 ) { + phba->cfg_fcp_cpu_map =0 ; +return 0 ; + } + +if (val >=LPFC_MIN_CPU_MAP && val <=LPFC_MAX_CPU_MAP ) { + phba->cfg_fcp_cpu_map = val; +return 0 ; + } + +lpfc_printf_log (phba,KERN_ERR ,LOG_INIT , +"3326 fcp_cpu_map: %d out of range, using default\n" , + val); + phba->cfg_fcp_cpu_map =LPFC_DRIVER_CPU_MAP ; + +return 0 ; +} + +static DEVICE_ATTR(lpfc_fcp_cpu_map, S_IRUGO | S_IWUSR, + lpfc_fcp_cpu_map_show, lpfc_fcp_cpu_map_store); +/* # lpfc_fcp_class: Determines FC class to use for the FCP protocol. # Value range is [2,3]. Default value is 3.
@@ -4154,6 +4289,7 @@ struct device_attribute *lpfc_hba_attrs[ &dev_attr_lpfc_poll_tmo, &dev_attr_lpfc_use_msi, &dev_attr_lpfc_fcp_imax, + &dev_attr_lpfc_fcp_cpu_map, &dev_attr_lpfc_fcp_wq_count, &dev_attr_lpfc_fcp_eq_count, &dev_attr_lpfc_fcp_io_channel,
@@ -5136,6 +5272,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)lpfc_enable_rrq_init (phba, lpfc_enable_rrq);lpfc_use_msi_init (phba, lpfc_use_msi);lpfc_fcp_imax_init (phba, lpfc_fcp_imax); +lpfc_fcp_cpu_map_init (phba, lpfc_fcp_cpu_map);lpfc_fcp_wq_count_init (phba, lpfc_fcp_wq_count);lpfc_fcp_eq_count_init (phba, lpfc_fcp_eq_count);lpfc_fcp_io_channel_init (phba, lpfc_fcp_io_channel);
drivers/scsi/lpfc/lpfc.h +1 -0
@@ -709,6 +709,7 @@ struct lpfc_hba {uint32_t cfg_poll_tmo;uint32_t cfg_use_msi;uint32_t cfg_fcp_imax; +uint32_t cfg_fcp_cpu_map;uint32_t cfg_fcp_wq_count;uint32_t cfg_fcp_eq_count;uint32_t cfg_fcp_io_channel;
drivers/scsi/lpfc/lpfc_hw4.h +5 -0
@@ -200,6 +200,11 @@ struct lpfc_sli_intf {#define LPFC_MAX_IMAX 5000000#define LPFC_DEF_IMAX 50000 +#define LPFC_MIN_CPU_MAP 0 +#define LPFC_MAX_CPU_MAP 2 +#define LPFC_HBA_CPU_MAP 1 +#define LPFC_DRIVER_CPU_MAP 2/* Default */ +/* PORT_CAPABILITIES constants. */ #define LPFC_MAX_SUPPORTED_PAGES 8
drivers/scsi/lpfc/lpfc_init.c +315 -7
405 lines not on this page · raw message
drivers/scsi/lpfc/lpfc_sli4.h +16 -0
@@ -435,6 +435,17 @@ struct lpfc_sli4_lnk_info {#define LPFC_SLI4_HANDLER_NAME_SZ 16 +/* Used for IRQ vector to CPU mapping */ +struct lpfc_vector_map_info { +uint16_t phys_id; +uint16_t core_id; +uint16_t irq; +uint16_t channel_id; +struct cpumask maskbits; +}; +#define LPFC_VECTOR_MAP_EMPTY 0xffff +#define LPFC_MAX_CPU 256 +/* SLI4 HBA data structure entries */ struct lpfc_sli4_hba {void __iomem *conf_regs_memmap_p;/* Kernel memory mapped address for
@@ -568,6 +579,11 @@ struct lpfc_sli4_hba {struct lpfc_iov iov;spinlock_t abts_scsi_buf_list_lock;/* list of aborted SCSI IOs */ spinlock_t abts_sgl_list_lock;/* list of aborted els IOs */ + +/* CPU to vector mapping information */ +struct lpfc_vector_map_info *cpu_map; +uint16_t num_online_cpu; +uint16_t num_present_cpu; };enum lpfc_sge_type {
drivers/scsi/lpfc/lpfc_sli.c +14 -8
@@ -7922,15 +7922,21 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba,static inline uint32_t lpfc_sli4_scmd_to_wqidx_distr (struct lpfc_hba *phba) { -int i; +struct lpfc_vector_map_info *cpup; +int chann, cpu; -if (phba->cfg_fcp_io_sched ==LPFC_FCP_SCHED_BY_CPU ) - i =smp_processor_id (); -else - i =atomic_add_return (1 , &phba->fcp_qidx); - - i = (i % phba->cfg_fcp_io_channel); -return i; +if (phba->cfg_fcp_io_sched ==LPFC_FCP_SCHED_BY_CPU ) { + cpu =smp_processor_id (); +if (cpu < phba->sli4_hba.num_present_cpu) { + cpup = phba->sli4_hba.cpu_map; + cpup += cpu; +return cpup->channel_id; + } + chann = cpu; + } + chann =atomic_add_return (1 , &phba->fcp_qidx); + chann = (chann % phba->cfg_fcp_io_channel); +return chann; }/**