diff options
author | James Smart <james.smart@emulex.com> | 2013-09-06 12:20:36 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-09-10 20:26:17 -0400 |
commit | ec2087a725f42bfbe239120768933e881aab73cd (patch) | |
tree | 5c0760368247768f2bb829c37781aec32229baa7 /drivers/scsi | |
parent | 14660f4fc84c4cbb3e90de50793f7eef119c2a02 (diff) |
[SCSI] lpfc 8.3.42: Fix crash on driver load due to cpu affinity logic
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 28 |
2 files changed, 27 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 18b3a1d7f3f0..ad80f9ca2dbb 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -4013,8 +4013,11 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support"); | |||
4013 | # For [0], FCP commands are issued to Work Queues ina round robin fashion. | 4013 | # For [0], FCP commands are issued to Work Queues ina round robin fashion. |
4014 | # For [1], FCP commands are issued to a Work Queue associated with the | 4014 | # For [1], FCP commands are issued to a Work Queue associated with the |
4015 | # current CPU. | 4015 | # current CPU. |
4016 | # It would be set to 1 by the driver if it's able to set up cpu affinity | ||
4017 | # for FCP I/Os through Work Queue associated with the current CPU. Otherwise, | ||
4018 | # roundrobin scheduling of FCP I/Os through WQs will be used. | ||
4016 | */ | 4019 | */ |
4017 | LPFC_ATTR_RW(fcp_io_sched, 0, 0, 1, "Determine scheduling algrithmn for " | 4020 | LPFC_ATTR_RW(fcp_io_sched, 0, 0, 1, "Determine scheduling algorithm for " |
4018 | "issuing commands [0] - Round Robin, [1] - Current CPU"); | 4021 | "issuing commands [0] - Round Robin, [1] - Current CPU"); |
4019 | 4022 | ||
4020 | /* | 4023 | /* |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b94420b3817a..b0a500be8b1f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -8399,7 +8399,8 @@ static int | |||
8399 | lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) | 8399 | lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) |
8400 | { | 8400 | { |
8401 | int i, idx, saved_chann, used_chann, cpu, phys_id; | 8401 | int i, idx, saved_chann, used_chann, cpu, phys_id; |
8402 | int max_phys_id, num_io_channel, first_cpu; | 8402 | int max_phys_id, min_phys_id; |
8403 | int num_io_channel, first_cpu, chan; | ||
8403 | struct lpfc_vector_map_info *cpup; | 8404 | struct lpfc_vector_map_info *cpup; |
8404 | #ifdef CONFIG_X86 | 8405 | #ifdef CONFIG_X86 |
8405 | struct cpuinfo_x86 *cpuinfo; | 8406 | struct cpuinfo_x86 *cpuinfo; |
@@ -8417,6 +8418,7 @@ lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) | |||
8417 | phba->sli4_hba.num_present_cpu)); | 8418 | phba->sli4_hba.num_present_cpu)); |
8418 | 8419 | ||
8419 | max_phys_id = 0; | 8420 | max_phys_id = 0; |
8421 | min_phys_id = 0xff; | ||
8420 | phys_id = 0; | 8422 | phys_id = 0; |
8421 | num_io_channel = 0; | 8423 | num_io_channel = 0; |
8422 | first_cpu = LPFC_VECTOR_MAP_EMPTY; | 8424 | first_cpu = LPFC_VECTOR_MAP_EMPTY; |
@@ -8440,9 +8442,12 @@ lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) | |||
8440 | 8442 | ||
8441 | if (cpup->phys_id > max_phys_id) | 8443 | if (cpup->phys_id > max_phys_id) |
8442 | max_phys_id = cpup->phys_id; | 8444 | max_phys_id = cpup->phys_id; |
8445 | if (cpup->phys_id < min_phys_id) | ||
8446 | min_phys_id = cpup->phys_id; | ||
8443 | cpup++; | 8447 | cpup++; |
8444 | } | 8448 | } |
8445 | 8449 | ||
8450 | phys_id = min_phys_id; | ||
8446 | /* Now associate the HBA vectors with specific CPUs */ | 8451 | /* Now associate the HBA vectors with specific CPUs */ |
8447 | for (idx = 0; idx < vectors; idx++) { | 8452 | for (idx = 0; idx < vectors; idx++) { |
8448 | cpup = phba->sli4_hba.cpu_map; | 8453 | cpup = phba->sli4_hba.cpu_map; |
@@ -8453,13 +8458,25 @@ lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) | |||
8453 | for (i = 1; i < max_phys_id; i++) { | 8458 | for (i = 1; i < max_phys_id; i++) { |
8454 | phys_id++; | 8459 | phys_id++; |
8455 | if (phys_id > max_phys_id) | 8460 | if (phys_id > max_phys_id) |
8456 | phys_id = 0; | 8461 | phys_id = min_phys_id; |
8457 | cpu = lpfc_find_next_cpu(phba, phys_id); | 8462 | cpu = lpfc_find_next_cpu(phba, phys_id); |
8458 | if (cpu == LPFC_VECTOR_MAP_EMPTY) | 8463 | if (cpu == LPFC_VECTOR_MAP_EMPTY) |
8459 | continue; | 8464 | continue; |
8460 | goto found; | 8465 | goto found; |
8461 | } | 8466 | } |
8462 | 8467 | ||
8468 | /* Use round robin for scheduling */ | ||
8469 | phba->cfg_fcp_io_sched = LPFC_FCP_SCHED_ROUND_ROBIN; | ||
8470 | chan = 0; | ||
8471 | cpup = phba->sli4_hba.cpu_map; | ||
8472 | for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { | ||
8473 | cpup->channel_id = chan; | ||
8474 | cpup++; | ||
8475 | chan++; | ||
8476 | if (chan >= phba->cfg_fcp_io_channel) | ||
8477 | chan = 0; | ||
8478 | } | ||
8479 | |||
8463 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8480 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8464 | "3329 Cannot set affinity:" | 8481 | "3329 Cannot set affinity:" |
8465 | "Error mapping vector %d (%d)\n", | 8482 | "Error mapping vector %d (%d)\n", |
@@ -8497,7 +8514,7 @@ found: | |||
8497 | /* Spread vector mapping across multple physical CPU nodes */ | 8514 | /* Spread vector mapping across multple physical CPU nodes */ |
8498 | phys_id++; | 8515 | phys_id++; |
8499 | if (phys_id > max_phys_id) | 8516 | if (phys_id > max_phys_id) |
8500 | phys_id = 0; | 8517 | phys_id = min_phys_id; |
8501 | } | 8518 | } |
8502 | 8519 | ||
8503 | /* | 8520 | /* |
@@ -8507,7 +8524,7 @@ found: | |||
8507 | * Base the remaining IO channel assigned, to IO channels already | 8524 | * Base the remaining IO channel assigned, to IO channels already |
8508 | * assigned to other CPUs on the same phys_id. | 8525 | * assigned to other CPUs on the same phys_id. |
8509 | */ | 8526 | */ |
8510 | for (i = 0; i <= max_phys_id; i++) { | 8527 | for (i = min_phys_id; i <= max_phys_id; i++) { |
8511 | /* | 8528 | /* |
8512 | * If there are no io channels already mapped to | 8529 | * If there are no io channels already mapped to |
8513 | * this phys_id, just round robin thru the io_channels. | 8530 | * this phys_id, just round robin thru the io_channels. |
@@ -8589,10 +8606,11 @@ out: | |||
8589 | if (num_io_channel != phba->sli4_hba.num_present_cpu) | 8606 | if (num_io_channel != phba->sli4_hba.num_present_cpu) |
8590 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8607 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8591 | "3333 Set affinity mismatch:" | 8608 | "3333 Set affinity mismatch:" |
8592 | "%d chann != %d cpus: %d vactors\n", | 8609 | "%d chann != %d cpus: %d vectors\n", |
8593 | num_io_channel, phba->sli4_hba.num_present_cpu, | 8610 | num_io_channel, phba->sli4_hba.num_present_cpu, |
8594 | vectors); | 8611 | vectors); |
8595 | 8612 | ||
8613 | /* Enable using cpu affinity for scheduling */ | ||
8596 | phba->cfg_fcp_io_sched = LPFC_FCP_SCHED_BY_CPU; | 8614 | phba->cfg_fcp_io_sched = LPFC_FCP_SCHED_BY_CPU; |
8597 | return 1; | 8615 | return 1; |
8598 | } | 8616 | } |