|
@@ -122,9 +122,12 @@ static void pnv_alloc_idle_core_states(void)
|
|
for (i = 0; i < nr_cores; i++) {
|
|
for (i = 0; i < nr_cores; i++) {
|
|
int first_cpu = i * threads_per_core;
|
|
int first_cpu = i * threads_per_core;
|
|
int node = cpu_to_node(first_cpu);
|
|
int node = cpu_to_node(first_cpu);
|
|
|
|
+ size_t paca_ptr_array_size;
|
|
|
|
|
|
core_idle_state = kmalloc_node(sizeof(u32), GFP_KERNEL, node);
|
|
core_idle_state = kmalloc_node(sizeof(u32), GFP_KERNEL, node);
|
|
*core_idle_state = PNV_CORE_IDLE_THREAD_BITS;
|
|
*core_idle_state = PNV_CORE_IDLE_THREAD_BITS;
|
|
|
|
+ paca_ptr_array_size = (threads_per_core *
|
|
|
|
+ sizeof(struct paca_struct *));
|
|
|
|
|
|
for (j = 0; j < threads_per_core; j++) {
|
|
for (j = 0; j < threads_per_core; j++) {
|
|
int cpu = first_cpu + j;
|
|
int cpu = first_cpu + j;
|
|
@@ -132,6 +135,11 @@ static void pnv_alloc_idle_core_states(void)
|
|
paca[cpu].core_idle_state_ptr = core_idle_state;
|
|
paca[cpu].core_idle_state_ptr = core_idle_state;
|
|
paca[cpu].thread_idle_state = PNV_THREAD_RUNNING;
|
|
paca[cpu].thread_idle_state = PNV_THREAD_RUNNING;
|
|
paca[cpu].thread_mask = 1 << j;
|
|
paca[cpu].thread_mask = 1 << j;
|
|
|
|
+ if (!cpu_has_feature(CPU_FTR_POWER9_DD1))
|
|
|
|
+ continue;
|
|
|
|
+ paca[cpu].thread_sibling_pacas =
|
|
|
|
+ kmalloc_node(paca_ptr_array_size,
|
|
|
|
+ GFP_KERNEL, node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -560,6 +568,28 @@ static int __init pnv_init_idle_states(void)
|
|
|
|
|
|
pnv_alloc_idle_core_states();
|
|
pnv_alloc_idle_core_states();
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * For each CPU, record its PACA address in each of it's
|
|
|
|
+ * sibling thread's PACA at the slot corresponding to this
|
|
|
|
+ * CPU's index in the core.
|
|
|
|
+ */
|
|
|
|
+ if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
|
|
|
|
+ int cpu;
|
|
|
|
+
|
|
|
|
+ pr_info("powernv: idle: Saving PACA pointers of all CPUs in their thread sibling PACA\n");
|
|
|
|
+ for_each_possible_cpu(cpu) {
|
|
|
|
+ int base_cpu = cpu_first_thread_sibling(cpu);
|
|
|
|
+ int idx = cpu_thread_in_core(cpu);
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < threads_per_core; i++) {
|
|
|
|
+ int j = base_cpu + i;
|
|
|
|
+
|
|
|
|
+ paca[j].thread_sibling_pacas[idx] = &paca[cpu];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (supported_cpuidle_states & OPAL_PM_NAP_ENABLED)
|
|
if (supported_cpuidle_states & OPAL_PM_NAP_ENABLED)
|
|
ppc_md.power_save = power7_idle;
|
|
ppc_md.power_save = power7_idle;
|
|
|
|
|