Commit ec2087a725f42bfbe239120768933e881aab73cd
Committed by
James Bottomley
1 parent
14660f4fc8
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
[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>
Showing 2 changed files with 27 additions and 6 deletions Side-by-side Diff
drivers/scsi/lpfc/lpfc_attr.c
... | ... | @@ -4013,8 +4013,11 @@ |
4013 | 4013 | # For [0], FCP commands are issued to Work Queues ina round robin fashion. |
4014 | 4014 | # For [1], FCP commands are issued to a Work Queue associated with the |
4015 | 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 | 4021 | "issuing commands [0] - Round Robin, [1] - Current CPU"); |
4019 | 4022 | |
4020 | 4023 | /* |
drivers/scsi/lpfc/lpfc_init.c
... | ... | @@ -8399,7 +8399,8 @@ |
8399 | 8399 | lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) |
8400 | 8400 | { |
8401 | 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 | 8404 | struct lpfc_vector_map_info *cpup; |
8404 | 8405 | #ifdef CONFIG_X86 |
8405 | 8406 | struct cpuinfo_x86 *cpuinfo; |
... | ... | @@ -8417,6 +8418,7 @@ |
8417 | 8418 | phba->sli4_hba.num_present_cpu)); |
8418 | 8419 | |
8419 | 8420 | max_phys_id = 0; |
8421 | + min_phys_id = 0xff; | |
8420 | 8422 | phys_id = 0; |
8421 | 8423 | num_io_channel = 0; |
8422 | 8424 | first_cpu = LPFC_VECTOR_MAP_EMPTY; |
8423 | 8425 | |
... | ... | @@ -8440,9 +8442,12 @@ |
8440 | 8442 | |
8441 | 8443 | if (cpup->phys_id > max_phys_id) |
8442 | 8444 | max_phys_id = cpup->phys_id; |
8445 | + if (cpup->phys_id < min_phys_id) | |
8446 | + min_phys_id = cpup->phys_id; | |
8443 | 8447 | cpup++; |
8444 | 8448 | } |
8445 | 8449 | |
8450 | + phys_id = min_phys_id; | |
8446 | 8451 | /* Now associate the HBA vectors with specific CPUs */ |
8447 | 8452 | for (idx = 0; idx < vectors; idx++) { |
8448 | 8453 | cpup = phba->sli4_hba.cpu_map; |
8449 | 8454 | |
... | ... | @@ -8453,13 +8458,25 @@ |
8453 | 8458 | for (i = 1; i < max_phys_id; i++) { |
8454 | 8459 | phys_id++; |
8455 | 8460 | if (phys_id > max_phys_id) |
8456 | - phys_id = 0; | |
8461 | + phys_id = min_phys_id; | |
8457 | 8462 | cpu = lpfc_find_next_cpu(phba, phys_id); |
8458 | 8463 | if (cpu == LPFC_VECTOR_MAP_EMPTY) |
8459 | 8464 | continue; |
8460 | 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 | 8480 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8464 | 8481 | "3329 Cannot set affinity:" |
8465 | 8482 | "Error mapping vector %d (%d)\n", |
... | ... | @@ -8497,7 +8514,7 @@ |
8497 | 8514 | /* Spread vector mapping across multple physical CPU nodes */ |
8498 | 8515 | phys_id++; |
8499 | 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 @@ |
8507 | 8524 | * Base the remaining IO channel assigned, to IO channels already |
8508 | 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 | 8529 | * If there are no io channels already mapped to |
8513 | 8530 | * this phys_id, just round robin thru the io_channels. |
8514 | 8531 | |
... | ... | @@ -8589,10 +8606,11 @@ |
8589 | 8606 | if (num_io_channel != phba->sli4_hba.num_present_cpu) |
8590 | 8607 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8591 | 8608 | "3333 Set affinity mismatch:" |
8592 | - "%d chann != %d cpus: %d vactors\n", | |
8609 | + "%d chann != %d cpus: %d vectors\n", | |
8593 | 8610 | num_io_channel, phba->sli4_hba.num_present_cpu, |
8594 | 8611 | vectors); |
8595 | 8612 | |
8613 | + /* Enable using cpu affinity for scheduling */ | |
8596 | 8614 | phba->cfg_fcp_io_sched = LPFC_FCP_SCHED_BY_CPU; |
8597 | 8615 | return 1; |
8598 | 8616 | } |