diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-02 17:39:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-02 17:39:49 -0400 |
commit | e7e2e511ba7d5850a7ecedcb452acf9d25a9a768 (patch) | |
tree | 9dcee89d54bfc0430ef00839aead87be6189a21a | |
parent | 6d039f8f037fda35da8124f09c4d2bbe55c9a575 (diff) | |
parent | fe956a1d4081ce1a959f87df397a15e252201f10 (diff) |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc fixes from Ben Herrenschmidt:
"Here is not quite a handful of powerpc fixes for rc3.
The windfarm fix is a regression fix (though not a new one), the PMU
interrupt rename is not a fix per-se but has been submitted a long
time ago and I kept forgetting to put it in (it puts us back in sync
with x86), the other perf bit is just about putting an API/ABI bit
definition in the right place for userspace to consume, and finally,
we have a fix for the VPHN (Virtual Partition Home Node) feature
(notification that the hypervisor is moving nodes around) which could
cause lockups so we may as well fix it now"
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
powerpc/windfarm: Fix noisy slots-fan on Xserve (rm31)
powerpc: VPHN topology change updates all siblings
powerpc/perf: Export PERF_EVENT_CONFIG_EBB_SHIFT to userspace
powerpc: Rename PMU interrupts from CNT to PMI
-rw-r--r-- | arch/powerpc/include/asm/perf_event_server.h | 6 | ||||
-rw-r--r-- | arch/powerpc/include/asm/smp.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/perf_event.h | 18 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/powerpc/mm/numa.c | 59 | ||||
-rw-r--r-- | arch/powerpc/perf/core-book3s.c | 2 | ||||
-rw-r--r-- | arch/powerpc/perf/power8-pmu.c | 6 | ||||
-rw-r--r-- | drivers/macintosh/windfarm_rm31.c | 18 |
9 files changed, 82 insertions, 34 deletions
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 2dd7bfc459be..8b2492644754 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <asm/hw_irq.h> | 13 | #include <asm/hw_irq.h> |
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <uapi/asm/perf_event.h> | ||
15 | 16 | ||
16 | #define MAX_HWEVENTS 8 | 17 | #define MAX_HWEVENTS 8 |
17 | #define MAX_EVENT_ALTERNATIVES 8 | 18 | #define MAX_EVENT_ALTERNATIVES 8 |
@@ -69,11 +70,6 @@ struct power_pmu { | |||
69 | #define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */ | 70 | #define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */ |
70 | #define PPMU_ONLY_COUNT_RUN 4 /* only counting in run state */ | 71 | #define PPMU_ONLY_COUNT_RUN 4 /* only counting in run state */ |
71 | 72 | ||
72 | /* | ||
73 | * We use the event config bit 63 as a flag to request EBB. | ||
74 | */ | ||
75 | #define EVENT_CONFIG_EBB_SHIFT 63 | ||
76 | |||
77 | extern int register_power_pmu(struct power_pmu *); | 73 | extern int register_power_pmu(struct power_pmu *); |
78 | 74 | ||
79 | struct pt_regs; | 75 | struct pt_regs; |
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index ffbaabebcdca..48cfc858abd6 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -145,6 +145,10 @@ extern void __cpu_die(unsigned int cpu); | |||
145 | #define smp_setup_cpu_maps() | 145 | #define smp_setup_cpu_maps() |
146 | static inline void inhibit_secondary_onlining(void) {} | 146 | static inline void inhibit_secondary_onlining(void) {} |
147 | static inline void uninhibit_secondary_onlining(void) {} | 147 | static inline void uninhibit_secondary_onlining(void) {} |
148 | static inline const struct cpumask *cpu_sibling_mask(int cpu) | ||
149 | { | ||
150 | return cpumask_of(cpu); | ||
151 | } | ||
148 | 152 | ||
149 | #endif /* CONFIG_SMP */ | 153 | #endif /* CONFIG_SMP */ |
150 | 154 | ||
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index 5182c8622b54..48be855ef37b 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild | |||
@@ -20,6 +20,7 @@ header-y += mman.h | |||
20 | header-y += msgbuf.h | 20 | header-y += msgbuf.h |
21 | header-y += nvram.h | 21 | header-y += nvram.h |
22 | header-y += param.h | 22 | header-y += param.h |
23 | header-y += perf_event.h | ||
23 | header-y += poll.h | 24 | header-y += poll.h |
24 | header-y += posix_types.h | 25 | header-y += posix_types.h |
25 | header-y += ps3fb.h | 26 | header-y += ps3fb.h |
diff --git a/arch/powerpc/include/uapi/asm/perf_event.h b/arch/powerpc/include/uapi/asm/perf_event.h new file mode 100644 index 000000000000..80a4d40cf5bc --- /dev/null +++ b/arch/powerpc/include/uapi/asm/perf_event.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Michael Ellerman, IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; version 2 of the | ||
7 | * License. | ||
8 | */ | ||
9 | |||
10 | #ifndef _UAPI_ASM_POWERPC_PERF_EVENT_H | ||
11 | #define _UAPI_ASM_POWERPC_PERF_EVENT_H | ||
12 | |||
13 | /* | ||
14 | * We use bit 63 of perf_event_attr.config as a flag to request EBB. | ||
15 | */ | ||
16 | #define PERF_EVENT_CONFIG_EBB_SHIFT 63 | ||
17 | |||
18 | #endif /* _UAPI_ASM_POWERPC_PERF_EVENT_H */ | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 2e51cde616d2..c69440cef7af 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -362,7 +362,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
362 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs); | 362 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs); |
363 | seq_printf(p, " Spurious interrupts\n"); | 363 | seq_printf(p, " Spurious interrupts\n"); |
364 | 364 | ||
365 | seq_printf(p, "%*s: ", prec, "CNT"); | 365 | seq_printf(p, "%*s: ", prec, "PMI"); |
366 | for_each_online_cpu(j) | 366 | for_each_online_cpu(j) |
367 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs); | 367 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs); |
368 | seq_printf(p, " Performance monitoring interrupts\n"); | 368 | seq_printf(p, " Performance monitoring interrupts\n"); |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 08397217e8ac..5850798826cd 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
28 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <asm/cputhreads.h> | ||
30 | #include <asm/sparsemem.h> | 31 | #include <asm/sparsemem.h> |
31 | #include <asm/prom.h> | 32 | #include <asm/prom.h> |
32 | #include <asm/smp.h> | 33 | #include <asm/smp.h> |
@@ -1318,7 +1319,8 @@ static int update_cpu_associativity_changes_mask(void) | |||
1318 | } | 1319 | } |
1319 | } | 1320 | } |
1320 | if (changed) { | 1321 | if (changed) { |
1321 | cpumask_set_cpu(cpu, changes); | 1322 | cpumask_or(changes, changes, cpu_sibling_mask(cpu)); |
1323 | cpu = cpu_last_thread_sibling(cpu); | ||
1322 | } | 1324 | } |
1323 | } | 1325 | } |
1324 | 1326 | ||
@@ -1426,7 +1428,7 @@ static int update_cpu_topology(void *data) | |||
1426 | if (!data) | 1428 | if (!data) |
1427 | return -EINVAL; | 1429 | return -EINVAL; |
1428 | 1430 | ||
1429 | cpu = get_cpu(); | 1431 | cpu = smp_processor_id(); |
1430 | 1432 | ||
1431 | for (update = data; update; update = update->next) { | 1433 | for (update = data; update; update = update->next) { |
1432 | if (cpu != update->cpu) | 1434 | if (cpu != update->cpu) |
@@ -1446,12 +1448,12 @@ static int update_cpu_topology(void *data) | |||
1446 | */ | 1448 | */ |
1447 | int arch_update_cpu_topology(void) | 1449 | int arch_update_cpu_topology(void) |
1448 | { | 1450 | { |
1449 | unsigned int cpu, changed = 0; | 1451 | unsigned int cpu, sibling, changed = 0; |
1450 | struct topology_update_data *updates, *ud; | 1452 | struct topology_update_data *updates, *ud; |
1451 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; | 1453 | unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; |
1452 | cpumask_t updated_cpus; | 1454 | cpumask_t updated_cpus; |
1453 | struct device *dev; | 1455 | struct device *dev; |
1454 | int weight, i = 0; | 1456 | int weight, new_nid, i = 0; |
1455 | 1457 | ||
1456 | weight = cpumask_weight(&cpu_associativity_changes_mask); | 1458 | weight = cpumask_weight(&cpu_associativity_changes_mask); |
1457 | if (!weight) | 1459 | if (!weight) |
@@ -1464,19 +1466,46 @@ int arch_update_cpu_topology(void) | |||
1464 | cpumask_clear(&updated_cpus); | 1466 | cpumask_clear(&updated_cpus); |
1465 | 1467 | ||
1466 | for_each_cpu(cpu, &cpu_associativity_changes_mask) { | 1468 | for_each_cpu(cpu, &cpu_associativity_changes_mask) { |
1467 | ud = &updates[i++]; | 1469 | /* |
1468 | ud->cpu = cpu; | 1470 | * If siblings aren't flagged for changes, updates list |
1469 | vphn_get_associativity(cpu, associativity); | 1471 | * will be too short. Skip on this update and set for next |
1470 | ud->new_nid = associativity_to_nid(associativity); | 1472 | * update. |
1471 | 1473 | */ | |
1472 | if (ud->new_nid < 0 || !node_online(ud->new_nid)) | 1474 | if (!cpumask_subset(cpu_sibling_mask(cpu), |
1473 | ud->new_nid = first_online_node; | 1475 | &cpu_associativity_changes_mask)) { |
1476 | pr_info("Sibling bits not set for associativity " | ||
1477 | "change, cpu%d\n", cpu); | ||
1478 | cpumask_or(&cpu_associativity_changes_mask, | ||
1479 | &cpu_associativity_changes_mask, | ||
1480 | cpu_sibling_mask(cpu)); | ||
1481 | cpu = cpu_last_thread_sibling(cpu); | ||
1482 | continue; | ||
1483 | } | ||
1474 | 1484 | ||
1475 | ud->old_nid = numa_cpu_lookup_table[cpu]; | 1485 | /* Use associativity from first thread for all siblings */ |
1476 | cpumask_set_cpu(cpu, &updated_cpus); | 1486 | vphn_get_associativity(cpu, associativity); |
1487 | new_nid = associativity_to_nid(associativity); | ||
1488 | if (new_nid < 0 || !node_online(new_nid)) | ||
1489 | new_nid = first_online_node; | ||
1490 | |||
1491 | if (new_nid == numa_cpu_lookup_table[cpu]) { | ||
1492 | cpumask_andnot(&cpu_associativity_changes_mask, | ||
1493 | &cpu_associativity_changes_mask, | ||
1494 | cpu_sibling_mask(cpu)); | ||
1495 | cpu = cpu_last_thread_sibling(cpu); | ||
1496 | continue; | ||
1497 | } | ||
1477 | 1498 | ||
1478 | if (i < weight) | 1499 | for_each_cpu(sibling, cpu_sibling_mask(cpu)) { |
1479 | ud->next = &updates[i]; | 1500 | ud = &updates[i++]; |
1501 | ud->cpu = sibling; | ||
1502 | ud->new_nid = new_nid; | ||
1503 | ud->old_nid = numa_cpu_lookup_table[sibling]; | ||
1504 | cpumask_set_cpu(sibling, &updated_cpus); | ||
1505 | if (i < weight) | ||
1506 | ud->next = &updates[i]; | ||
1507 | } | ||
1508 | cpu = cpu_last_thread_sibling(cpu); | ||
1480 | } | 1509 | } |
1481 | 1510 | ||
1482 | stop_machine(update_cpu_topology, &updates[0], &updated_cpus); | 1511 | stop_machine(update_cpu_topology, &updates[0], &updated_cpus); |
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 24a45f91c65f..eeae308cf982 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -484,7 +484,7 @@ static bool is_ebb_event(struct perf_event *event) | |||
484 | * use bit 63 of the event code for something else if they wish. | 484 | * use bit 63 of the event code for something else if they wish. |
485 | */ | 485 | */ |
486 | return (ppmu->flags & PPMU_EBB) && | 486 | return (ppmu->flags & PPMU_EBB) && |
487 | ((event->attr.config >> EVENT_CONFIG_EBB_SHIFT) & 1); | 487 | ((event->attr.config >> PERF_EVENT_CONFIG_EBB_SHIFT) & 1); |
488 | } | 488 | } |
489 | 489 | ||
490 | static int ebb_event_check(struct perf_event *event) | 490 | static int ebb_event_check(struct perf_event *event) |
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 7466374d2787..2ee4a707f0df 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c | |||
@@ -118,7 +118,7 @@ | |||
118 | (EVENT_UNIT_MASK << EVENT_UNIT_SHIFT) | \ | 118 | (EVENT_UNIT_MASK << EVENT_UNIT_SHIFT) | \ |
119 | (EVENT_COMBINE_MASK << EVENT_COMBINE_SHIFT) | \ | 119 | (EVENT_COMBINE_MASK << EVENT_COMBINE_SHIFT) | \ |
120 | (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \ | 120 | (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT) | \ |
121 | (EVENT_EBB_MASK << EVENT_CONFIG_EBB_SHIFT) | \ | 121 | (EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT) | \ |
122 | EVENT_PSEL_MASK) | 122 | EVENT_PSEL_MASK) |
123 | 123 | ||
124 | /* MMCRA IFM bits - POWER8 */ | 124 | /* MMCRA IFM bits - POWER8 */ |
@@ -233,10 +233,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long | |||
233 | pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; | 233 | pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; |
234 | unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; | 234 | unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; |
235 | cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK; | 235 | cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK; |
236 | ebb = (event >> EVENT_CONFIG_EBB_SHIFT) & EVENT_EBB_MASK; | 236 | ebb = (event >> PERF_EVENT_CONFIG_EBB_SHIFT) & EVENT_EBB_MASK; |
237 | 237 | ||
238 | /* Clear the EBB bit in the event, so event checks work below */ | 238 | /* Clear the EBB bit in the event, so event checks work below */ |
239 | event &= ~(EVENT_EBB_MASK << EVENT_CONFIG_EBB_SHIFT); | 239 | event &= ~(EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT); |
240 | 240 | ||
241 | if (pmc) { | 241 | if (pmc) { |
242 | if (pmc > 6) | 242 | if (pmc > 6) |
diff --git a/drivers/macintosh/windfarm_rm31.c b/drivers/macintosh/windfarm_rm31.c index 0b9a79b2f48a..82fc86a90c1a 100644 --- a/drivers/macintosh/windfarm_rm31.c +++ b/drivers/macintosh/windfarm_rm31.c | |||
@@ -439,15 +439,15 @@ static void backside_setup_pid(void) | |||
439 | 439 | ||
440 | /* Slots fan */ | 440 | /* Slots fan */ |
441 | static const struct wf_pid_param slots_param = { | 441 | static const struct wf_pid_param slots_param = { |
442 | .interval = 5, | 442 | .interval = 1, |
443 | .history_len = 2, | 443 | .history_len = 20, |
444 | .gd = 30 << 20, | 444 | .gd = 0, |
445 | .gp = 5 << 20, | 445 | .gp = 0, |
446 | .gr = 0, | 446 | .gr = 0x00100000, |
447 | .itarget = 40 << 16, | 447 | .itarget = 3200000, |
448 | .additive = 1, | 448 | .additive = 0, |
449 | .min = 300, | 449 | .min = 20, |
450 | .max = 4000, | 450 | .max = 100, |
451 | }; | 451 | }; |
452 | 452 | ||
453 | static void slots_fan_tick(void) | 453 | static void slots_fan_tick(void) |