aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-18 14:48:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-18 14:48:48 -0400
commita0a6a39ecb11cefe0d7e6e07997306fb5ab2b07e (patch)
tree35dfe4099b54dbc6971ef115c2e4d39cefd24413
parentbab58350e565756df9e45daafe8301a309b35e7e (diff)
parent83dac59409387789b88bed40b1be86a8abc572be (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc fixes from Benjamin Herrenschmidt: "Here are a handful of powerpc related fixes." * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: cpuidle/powerpc: Fix snooze state problem in the cpuidle design on pseries. cpuidle/powerpc: Fix smt_snooze_delay functionality. cpuidle/powerpc: Fix target residency initialisation in pseries cpuidle powerpc: Build fix for powerpc KVM Revert "powerpc/perf: Use pmc_overflow() to detect rolled back events"
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_32.h1
-rw-r--r--arch/powerpc/include/asm/processor.h4
-rw-r--r--arch/powerpc/kernel/sysfs.c2
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu_host.c4
-rw-r--r--arch/powerpc/perf/core-book3s.c2
-rw-r--r--arch/powerpc/platforms/pseries/processor_idle.c62
6 files changed, 36 insertions, 39 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s_32.h b/arch/powerpc/include/asm/kvm_book3s_32.h
index 38040ff82063..ce0ef6ce8f86 100644
--- a/arch/powerpc/include/asm/kvm_book3s_32.h
+++ b/arch/powerpc/include/asm/kvm_book3s_32.h
@@ -42,5 +42,6 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)
42#define SID_SHIFT 28 42#define SID_SHIFT 28
43#define ESID_MASK 0xf0000000 43#define ESID_MASK 0xf0000000
44#define VSID_MASK 0x00fffffff0000000ULL 44#define VSID_MASK 0x00fffffff0000000ULL
45#define VPN_SHIFT 12
45 46
46#endif /* __ASM_KVM_BOOK3S_32_H__ */ 47#endif /* __ASM_KVM_BOOK3S_32_H__ */
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 8734b3855272..87502046c0dc 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -388,9 +388,9 @@ extern int powersave_nap; /* set if nap mode can be used in idle loop */
388extern void power7_nap(void); 388extern void power7_nap(void);
389 389
390#ifdef CONFIG_PSERIES_IDLE 390#ifdef CONFIG_PSERIES_IDLE
391extern void update_smt_snooze_delay(int snooze); 391extern void update_smt_snooze_delay(int cpu, int residency);
392#else 392#else
393static inline void update_smt_snooze_delay(int snooze) {} 393static inline void update_smt_snooze_delay(int cpu, int residency) {}
394#endif 394#endif
395 395
396extern void flush_instruction_cache(void); 396extern void flush_instruction_cache(void);
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 8302af649219..cf357a059ddb 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -50,7 +50,7 @@ static ssize_t store_smt_snooze_delay(struct device *dev,
50 return -EINVAL; 50 return -EINVAL;
51 51
52 per_cpu(smt_snooze_delay, cpu->dev.id) = snooze; 52 per_cpu(smt_snooze_delay, cpu->dev.id) = snooze;
53 update_smt_snooze_delay(snooze); 53 update_smt_snooze_delay(cpu->dev.id, snooze);
54 54
55 return count; 55 return count;
56} 56}
diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c
index 00aa61268e0d..b0f625a33345 100644
--- a/arch/powerpc/kvm/book3s_32_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_32_mmu_host.c
@@ -173,8 +173,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
173 BUG_ON(!map); 173 BUG_ON(!map);
174 174
175 vsid = map->host_vsid; 175 vsid = map->host_vsid;
176 vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) | ((eaddr & ~ESID_MASK) >> VPN_SHIFT) 176 vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) |
177 177 ((eaddr & ~ESID_MASK) >> VPN_SHIFT);
178next_pteg: 178next_pteg:
179 if (rr == 16) { 179 if (rr == 16) {
180 primary = !primary; 180 primary = !primary;
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 0db88f501f91..aa2465e21f1a 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -1463,7 +1463,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
1463 if (!event->hw.idx || is_limited_pmc(event->hw.idx)) 1463 if (!event->hw.idx || is_limited_pmc(event->hw.idx))
1464 continue; 1464 continue;
1465 val = read_pmc(event->hw.idx); 1465 val = read_pmc(event->hw.idx);
1466 if (pmc_overflow(val)) { 1466 if ((int)val < 0) {
1467 /* event has overflowed */ 1467 /* event has overflowed */
1468 found = 1; 1468 found = 1;
1469 record_and_restart(event, val, regs); 1469 record_and_restart(event, val, regs);
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 455760b1fe6e..45d00e5fe14d 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -33,13 +33,6 @@ static int max_idle_state = MAX_IDLE_STATE_COUNT - 1;
33static struct cpuidle_device __percpu *pseries_cpuidle_devices; 33static struct cpuidle_device __percpu *pseries_cpuidle_devices;
34static struct cpuidle_state *cpuidle_state_table; 34static struct cpuidle_state *cpuidle_state_table;
35 35
36void update_smt_snooze_delay(int snooze)
37{
38 struct cpuidle_driver *drv = cpuidle_get_driver();
39 if (drv)
40 drv->states[0].target_residency = snooze;
41}
42
43static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) 36static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
44{ 37{
45 38
@@ -66,32 +59,22 @@ static int snooze_loop(struct cpuidle_device *dev,
66{ 59{
67 unsigned long in_purr; 60 unsigned long in_purr;
68 ktime_t kt_before; 61 ktime_t kt_before;
69 unsigned long start_snooze; 62 int cpu = dev->cpu;
70 long snooze = drv->states[0].target_residency;
71 63
72 idle_loop_prolog(&in_purr, &kt_before); 64 idle_loop_prolog(&in_purr, &kt_before);
65 local_irq_enable();
66 set_thread_flag(TIF_POLLING_NRFLAG);
73 67
74 if (snooze) { 68 while ((!need_resched()) && cpu_online(cpu)) {
75 start_snooze = get_tb() + snooze * tb_ticks_per_usec; 69 ppc64_runlatch_off();
76 local_irq_enable(); 70 HMT_low();
77 set_thread_flag(TIF_POLLING_NRFLAG); 71 HMT_very_low();
78
79 while ((snooze < 0) || (get_tb() < start_snooze)) {
80 if (need_resched() || cpu_is_offline(dev->cpu))
81 goto out;
82 ppc64_runlatch_off();
83 HMT_low();
84 HMT_very_low();
85 }
86
87 HMT_medium();
88 clear_thread_flag(TIF_POLLING_NRFLAG);
89 smp_mb();
90 local_irq_disable();
91 } 72 }
92 73
93out:
94 HMT_medium(); 74 HMT_medium();
75 clear_thread_flag(TIF_POLLING_NRFLAG);
76 smp_mb();
77
95 dev->last_residency = 78 dev->last_residency =
96 (int)idle_loop_epilog(in_purr, kt_before); 79 (int)idle_loop_epilog(in_purr, kt_before);
97 return index; 80 return index;
@@ -172,8 +155,8 @@ static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = {
172 .name = "CEDE", 155 .name = "CEDE",
173 .desc = "CEDE", 156 .desc = "CEDE",
174 .flags = CPUIDLE_FLAG_TIME_VALID, 157 .flags = CPUIDLE_FLAG_TIME_VALID,
175 .exit_latency = 1, 158 .exit_latency = 10,
176 .target_residency = 10, 159 .target_residency = 100,
177 .enter = &dedicated_cede_loop }, 160 .enter = &dedicated_cede_loop },
178}; 161};
179 162
@@ -190,6 +173,23 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
190 .enter = &shared_cede_loop }, 173 .enter = &shared_cede_loop },
191}; 174};
192 175
176void update_smt_snooze_delay(int cpu, int residency)
177{
178 struct cpuidle_driver *drv = cpuidle_get_driver();
179 struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
180
181 if (cpuidle_state_table != dedicated_states)
182 return;
183
184 if (residency < 0) {
185 /* Disable the Nap state on that cpu */
186 if (dev)
187 dev->states_usage[1].disable = 1;
188 } else
189 if (drv)
190 drv->states[1].target_residency = residency;
191}
192
193static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, 193static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
194 unsigned long action, void *hcpu) 194 unsigned long action, void *hcpu)
195{ 195{
@@ -246,10 +246,6 @@ static int pseries_cpuidle_driver_init(void)
246 drv->states[drv->state_count] = /* structure copy */ 246 drv->states[drv->state_count] = /* structure copy */
247 cpuidle_state_table[idle_state]; 247 cpuidle_state_table[idle_state];
248 248
249 if (cpuidle_state_table == dedicated_states)
250 drv->states[drv->state_count].target_residency =
251 __get_cpu_var(smt_snooze_delay);
252
253 drv->state_count += 1; 249 drv->state_count += 1;
254 } 250 }
255 251