aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds2012-10-18 11:48:48 -0700
committerLinus Torvalds2012-10-18 11:48:48 -0700
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)
#define SID_SHIFT 28
#define ESID_MASK 0xf0000000
#define VSID_MASK 0x00fffffff0000000ULL
+#define VPN_SHIFT 12
#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 */
extern void power7_nap(void);
#ifdef CONFIG_PSERIES_IDLE
-extern void update_smt_snooze_delay(int snooze);
+extern void update_smt_snooze_delay(int cpu, int residency);
#else
-static inline void update_smt_snooze_delay(int snooze) {}
+static inline void update_smt_snooze_delay(int cpu, int residency) {}
#endif
extern 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,
return -EINVAL;
per_cpu(smt_snooze_delay, cpu->dev.id) = snooze;
- update_smt_snooze_delay(snooze);
+ update_smt_snooze_delay(cpu->dev.id, snooze);
return count;
}
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)
BUG_ON(!map);
vsid = map->host_vsid;
- vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) | ((eaddr & ~ESID_MASK) >> VPN_SHIFT)
-
+ vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) |
+ ((eaddr & ~ESID_MASK) >> VPN_SHIFT);
next_pteg:
if (rr == 16) {
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)
if (!event->hw.idx || is_limited_pmc(event->hw.idx))
continue;
val = read_pmc(event->hw.idx);
- if (pmc_overflow(val)) {
+ if ((int)val < 0) {
/* event has overflowed */
found = 1;
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;
static struct cpuidle_device __percpu *pseries_cpuidle_devices;
static struct cpuidle_state *cpuidle_state_table;
-void update_smt_snooze_delay(int snooze)
-{
- struct cpuidle_driver *drv = cpuidle_get_driver();
- if (drv)
- drv->states[0].target_residency = snooze;
-}
-
static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
{
@@ -66,32 +59,22 @@ static int snooze_loop(struct cpuidle_device *dev,
{
unsigned long in_purr;
ktime_t kt_before;
- unsigned long start_snooze;
- long snooze = drv->states[0].target_residency;
+ int cpu = dev->cpu;
idle_loop_prolog(&in_purr, &kt_before);
+ local_irq_enable();
+ set_thread_flag(TIF_POLLING_NRFLAG);
- if (snooze) {
- start_snooze = get_tb() + snooze * tb_ticks_per_usec;
- local_irq_enable();
- set_thread_flag(TIF_POLLING_NRFLAG);
-
- while ((snooze < 0) || (get_tb() < start_snooze)) {
- if (need_resched() || cpu_is_offline(dev->cpu))
- goto out;
- ppc64_runlatch_off();
- HMT_low();
- HMT_very_low();
- }
-
- HMT_medium();
- clear_thread_flag(TIF_POLLING_NRFLAG);
- smp_mb();
- local_irq_disable();
+ while ((!need_resched()) && cpu_online(cpu)) {
+ ppc64_runlatch_off();
+ HMT_low();
+ HMT_very_low();
}
-out:
HMT_medium();
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb();
+
dev->last_residency =
(int)idle_loop_epilog(in_purr, kt_before);
return index;
@@ -172,8 +155,8 @@ static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = {
.name = "CEDE",
.desc = "CEDE",
.flags = CPUIDLE_FLAG_TIME_VALID,
- .exit_latency = 1,
- .target_residency = 10,
+ .exit_latency = 10,
+ .target_residency = 100,
.enter = &dedicated_cede_loop },
};
@@ -190,6 +173,23 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
.enter = &shared_cede_loop },
};
+void update_smt_snooze_delay(int cpu, int residency)
+{
+ struct cpuidle_driver *drv = cpuidle_get_driver();
+ struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
+
+ if (cpuidle_state_table != dedicated_states)
+ return;
+
+ if (residency < 0) {
+ /* Disable the Nap state on that cpu */
+ if (dev)
+ dev->states_usage[1].disable = 1;
+ } else
+ if (drv)
+ drv->states[1].target_residency = residency;
+}
+
static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
unsigned long action, void *hcpu)
{
@@ -246,10 +246,6 @@ static int pseries_cpuidle_driver_init(void)
drv->states[drv->state_count] = /* structure copy */
cpuidle_state_table[idle_state];
- if (cpuidle_state_table == dedicated_states)
- drv->states[drv->state_count].target_residency =
- __get_cpu_var(smt_snooze_delay);
-
drv->state_count += 1;
}