0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) "powernv: " fmt
0007
0008 #include <linux/kernel.h>
0009 #include <linux/cpu.h>
0010 #include <linux/cpumask.h>
0011 #include <linux/device.h>
0012 #include <linux/gfp.h>
0013 #include <linux/smp.h>
0014 #include <linux/stop_machine.h>
0015
0016 #include <asm/cputhreads.h>
0017 #include <asm/cpuidle.h>
0018 #include <asm/kvm_ppc.h>
0019 #include <asm/machdep.h>
0020 #include <asm/opal.h>
0021 #include <asm/smp.h>
0022
0023 #include "subcore.h"
0024 #include "powernv.h"
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 static int subcores_per_core;
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 static int new_split_mode;
0138
0139 static cpumask_var_t cpu_offline_mask;
0140
0141 struct split_state {
0142 u8 step;
0143 u8 master;
0144 };
0145
0146 static DEFINE_PER_CPU(struct split_state, split_state);
0147
0148 static void wait_for_sync_step(int step)
0149 {
0150 int i, cpu = smp_processor_id();
0151
0152 for (i = cpu + 1; i < cpu + threads_per_core; i++)
0153 while(per_cpu(split_state, i).step < step)
0154 barrier();
0155
0156
0157 mb();
0158 }
0159
0160 static void update_hid_in_slw(u64 hid0)
0161 {
0162 u64 idle_states = pnv_get_supported_cpuidle_states();
0163
0164 if (idle_states & OPAL_PM_WINKLE_ENABLED) {
0165
0166 u64 cpu_pir = hard_smp_processor_id();
0167
0168 opal_slw_set_reg(cpu_pir, SPRN_HID0, hid0);
0169 }
0170 }
0171
0172 static inline void update_power8_hid0(unsigned long hid0)
0173 {
0174
0175
0176
0177
0178
0179 asm volatile("sync; mtspr %0,%1; isync":: "i"(SPRN_HID0), "r"(hid0));
0180 }
0181
0182 static void unsplit_core(void)
0183 {
0184 u64 hid0, mask;
0185 int i, cpu;
0186
0187 mask = HID0_POWER8_2LPARMODE | HID0_POWER8_4LPARMODE;
0188
0189 cpu = smp_processor_id();
0190 if (cpu_thread_in_core(cpu) != 0) {
0191 while (mfspr(SPRN_HID0) & mask)
0192 power7_idle_type(PNV_THREAD_NAP);
0193
0194 per_cpu(split_state, cpu).step = SYNC_STEP_UNSPLIT;
0195 return;
0196 }
0197
0198 hid0 = mfspr(SPRN_HID0);
0199 hid0 &= ~HID0_POWER8_DYNLPARDIS;
0200 update_power8_hid0(hid0);
0201 update_hid_in_slw(hid0);
0202
0203 while (mfspr(SPRN_HID0) & mask)
0204 cpu_relax();
0205
0206
0207 for (i = cpu + 1; i < cpu + threads_per_core; i++)
0208 smp_send_reschedule(i);
0209
0210 wait_for_sync_step(SYNC_STEP_UNSPLIT);
0211 }
0212
0213 static void split_core(int new_mode)
0214 {
0215 struct { u64 value; u64 mask; } split_parms[2] = {
0216 { HID0_POWER8_1TO2LPAR, HID0_POWER8_2LPARMODE },
0217 { HID0_POWER8_1TO4LPAR, HID0_POWER8_4LPARMODE }
0218 };
0219 int i, cpu;
0220 u64 hid0;
0221
0222
0223 i = (new_mode >> 1) - 1;
0224 BUG_ON(i < 0 || i > 1);
0225
0226 cpu = smp_processor_id();
0227 if (cpu_thread_in_core(cpu) != 0) {
0228 split_core_secondary_loop(&per_cpu(split_state, cpu).step);
0229 return;
0230 }
0231
0232 wait_for_sync_step(SYNC_STEP_REAL_MODE);
0233
0234
0235 hid0 = mfspr(SPRN_HID0);
0236 hid0 |= HID0_POWER8_DYNLPARDIS | split_parms[i].value;
0237 update_power8_hid0(hid0);
0238 update_hid_in_slw(hid0);
0239
0240
0241 while (!(mfspr(SPRN_HID0) & split_parms[i].mask))
0242 cpu_relax();
0243 }
0244
0245 static void cpu_do_split(int new_mode)
0246 {
0247
0248
0249
0250
0251
0252
0253 if (subcores_per_core != 1)
0254 unsplit_core();
0255
0256 if (new_mode != 1)
0257 split_core(new_mode);
0258
0259 mb();
0260 per_cpu(split_state, smp_processor_id()).step = SYNC_STEP_FINISHED;
0261 }
0262
0263 bool cpu_core_split_required(void)
0264 {
0265 smp_rmb();
0266
0267 if (!new_split_mode)
0268 return false;
0269
0270 cpu_do_split(new_split_mode);
0271
0272 return true;
0273 }
0274
0275 void update_subcore_sibling_mask(void)
0276 {
0277 int cpu;
0278
0279
0280
0281
0282 int sibling_mask_first_cpu = (1 << threads_per_subcore) - 1;
0283
0284 for_each_possible_cpu(cpu) {
0285 int tid = cpu_thread_in_core(cpu);
0286 int offset = (tid / threads_per_subcore) * threads_per_subcore;
0287 int mask = sibling_mask_first_cpu << offset;
0288
0289 paca_ptrs[cpu]->subcore_sibling_mask = mask;
0290
0291 }
0292 }
0293
0294 static int cpu_update_split_mode(void *data)
0295 {
0296 int cpu, new_mode = *(int *)data;
0297
0298 if (this_cpu_ptr(&split_state)->master) {
0299 new_split_mode = new_mode;
0300 smp_wmb();
0301
0302 cpumask_andnot(cpu_offline_mask, cpu_present_mask,
0303 cpu_online_mask);
0304
0305
0306 for_each_cpu(cpu, cpu_offline_mask)
0307 smp_send_reschedule(cpu);
0308 }
0309
0310 cpu_do_split(new_mode);
0311
0312 if (this_cpu_ptr(&split_state)->master) {
0313
0314 for_each_present_cpu(cpu) {
0315 if (cpu >= setup_max_cpus)
0316 break;
0317
0318 while(per_cpu(split_state, cpu).step < SYNC_STEP_FINISHED)
0319 barrier();
0320 }
0321
0322 new_split_mode = 0;
0323
0324
0325 subcores_per_core = new_mode;
0326 threads_per_subcore = threads_per_core / subcores_per_core;
0327 update_subcore_sibling_mask();
0328
0329
0330 mb();
0331 }
0332
0333 return 0;
0334 }
0335
0336 static int set_subcores_per_core(int new_mode)
0337 {
0338 struct split_state *state;
0339 int cpu;
0340
0341 if (kvm_hv_mode_active()) {
0342 pr_err("Unable to change split core mode while KVM active.\n");
0343 return -EBUSY;
0344 }
0345
0346
0347
0348
0349
0350 BUG_ON(new_mode < 1 || new_mode > 4 || new_mode == 3);
0351
0352 for_each_present_cpu(cpu) {
0353 state = &per_cpu(split_state, cpu);
0354 state->step = SYNC_STEP_INITIAL;
0355 state->master = 0;
0356 }
0357
0358 cpus_read_lock();
0359
0360
0361 this_cpu_ptr(&split_state)->master = 1;
0362
0363
0364 mb();
0365
0366 stop_machine_cpuslocked(cpu_update_split_mode, &new_mode,
0367 cpu_online_mask);
0368
0369 cpus_read_unlock();
0370
0371 return 0;
0372 }
0373
0374 static ssize_t __used store_subcores_per_core(struct device *dev,
0375 struct device_attribute *attr, const char *buf,
0376 size_t count)
0377 {
0378 unsigned long val;
0379 int rc;
0380
0381
0382
0383 rc = sscanf(buf, "%lx", &val);
0384 if (rc != 1)
0385 return -EINVAL;
0386
0387 switch (val) {
0388 case 1:
0389 case 2:
0390 case 4:
0391 if (subcores_per_core == val)
0392
0393 goto out;
0394 break;
0395 default:
0396 return -EINVAL;
0397 }
0398
0399 rc = set_subcores_per_core(val);
0400 if (rc)
0401 return rc;
0402
0403 out:
0404 return count;
0405 }
0406
0407 static ssize_t show_subcores_per_core(struct device *dev,
0408 struct device_attribute *attr, char *buf)
0409 {
0410 return sprintf(buf, "%x\n", subcores_per_core);
0411 }
0412
0413 static DEVICE_ATTR(subcores_per_core, 0644,
0414 show_subcores_per_core, store_subcores_per_core);
0415
0416 static int subcore_init(void)
0417 {
0418 unsigned pvr_ver;
0419
0420 pvr_ver = PVR_VER(mfspr(SPRN_PVR));
0421
0422 if (pvr_ver != PVR_POWER8 &&
0423 pvr_ver != PVR_POWER8E &&
0424 pvr_ver != PVR_POWER8NVL)
0425 return 0;
0426
0427
0428
0429
0430
0431 if (setup_max_cpus % threads_per_core)
0432 return 0;
0433
0434 BUG_ON(!alloc_cpumask_var(&cpu_offline_mask, GFP_KERNEL));
0435
0436 set_subcores_per_core(1);
0437
0438 return device_create_file(cpu_subsys.dev_root,
0439 &dev_attr_subcores_per_core);
0440 }
0441 machine_device_initcall(powernv, subcore_init);