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) |
