aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2013-09-06 12:20:36 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-09-10 20:26:17 -0400
commitec2087a725f42bfbe239120768933e881aab73cd (patch)
tree5c0760368247768f2bb829c37781aec32229baa7 /drivers/scsi
parent14660f4fc84c4cbb3e90de50793f7eef119c2a02 (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.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c28
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*/
4017LPFC_ATTR_RW(fcp_io_sched, 0, 0, 1, "Determine scheduling algrithmn for " 4020LPFC_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
8399lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) 8399lpfc_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}