Patches contributed by Eötvös Lorand University
commit b82914ce33146186d554b0f5c41e4e13693614ce
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon May 4 18:54:32 2009 +0200
perf_counter: round-robin per-CPU counters too
This used to be unstable when we had the rq->lock dependencies,
but now that they are that of the past we can turn on percpu
counter RR too.
[ Impact: handle counter over-commit for per-CPU counters too ]
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 8660ae579530..b9679c36bcc2 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1069,18 +1069,14 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu)
{
struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
struct perf_counter_context *ctx = &curr->perf_counter_ctx;
- const int rotate_percpu = 0;
- if (rotate_percpu)
- perf_counter_cpu_sched_out(cpuctx);
+ perf_counter_cpu_sched_out(cpuctx);
perf_counter_task_sched_out(curr, cpu);
- if (rotate_percpu)
- rotate_ctx(&cpuctx->ctx);
+ rotate_ctx(&cpuctx->ctx);
rotate_ctx(ctx);
- if (rotate_percpu)
- perf_counter_cpu_sched_in(cpuctx, cpu);
+ perf_counter_cpu_sched_in(cpuctx, cpu);
perf_counter_task_sched_in(curr, cpu);
}
commit a454ab3110175d710f4f9a96226a26ce4d5d5de2
Author: Ingo Molnar <mingo@elte.hu>
Date: Sun May 3 10:09:03 2009 +0200
x86, mm: fault.c, use printk_once() in is_errata93()
Andrew pointed out that the 'once' variable has a needlessly
function-global scope. We can in fact eliminate it completely,
via the use of printk_once().
[ Impact: cleanup ]
Reported-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 24a36a6426ab..b9ca6d767dbb 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -514,8 +514,6 @@ static void dump_pagetable(unsigned long address)
static int is_errata93(struct pt_regs *regs, unsigned long address)
{
#ifdef CONFIG_X86_64
- static int once;
-
if (address != regs->ip)
return 0;
@@ -525,10 +523,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
address |= 0xffffffffUL << 32;
if ((address >= (u64)_stext && address <= (u64)_etext) ||
(address >= MODULES_VADDR && address <= MODULES_END)) {
- if (!once) {
- printk(errata93_warning);
- once = 1;
- }
+ printk_once(errata93_warning);
regs->ip = address;
return 1;
}
commit 4420471f14b79f2a42e4603be7794ea49b68bca4
Merge: 15e957d08dd4 e0e42142bab9
Author: Ingo Molnar <mingo@elte.hu>
Date: Fri May 1 19:02:50 2009 +0200
Merge branch 'x86/apic' into irq/numa
Conflicts:
arch/x86/kernel/apic/io_apic.c
Merge reason: non-trivial interaction between ongoing work in io_apic.c
and the NUMA migration feature in the irq tree.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --cc arch/x86/kernel/apic/io_apic.c
index e583291fe6c3,8aef5f9d9479..21c30e1121ee
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@@ -2332,6 -2230,115 +2201,118 @@@ static int ioapic_retrigger_irq(unsigne
*/
#ifdef CONFIG_SMP
+ static void send_cleanup_vector(struct irq_cfg *cfg)
+ {
+ cpumask_var_t cleanup_mask;
+
+ if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) {
+ unsigned int i;
+ cfg->move_cleanup_count = 0;
+ for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
+ cfg->move_cleanup_count++;
+ for_each_cpu_and(i, cfg->old_domain, cpu_online_mask)
+ apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR);
+ } else {
+ cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask);
+ cfg->move_cleanup_count = cpumask_weight(cleanup_mask);
+ apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
+ free_cpumask_var(cleanup_mask);
+ }
+ cfg->move_in_progress = 0;
+ }
+
-static void
-__target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
++static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
+ {
+ int apic, pin;
+ struct irq_pin_list *entry;
+ u8 vector = cfg->vector;
+
+ entry = cfg->irq_2_pin;
+ for (;;) {
+ unsigned int reg;
+
+ if (!entry)
+ break;
+
+ apic = entry->apic;
+ pin = entry->pin;
+ /*
+ * With interrupt-remapping, destination information comes
+ * from interrupt-remapping table entry.
+ */
+ if (!irq_remapped(irq))
+ io_apic_write(apic, 0x11 + pin*2, dest);
+ reg = io_apic_read(apic, 0x10 + pin*2);
+ reg &= ~IO_APIC_REDIR_VECTOR_MASK;
+ reg |= vector;
+ io_apic_modify(apic, 0x10 + pin*2, reg);
+ if (!entry->next)
+ break;
+ entry = entry->next;
+ }
+ }
+
++static int
++assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask);
++
+ /*
+ * Either sets desc->affinity to a valid value, and returns
+ * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
+ * leaves desc->affinity untouched.
+ */
+ static unsigned int
+ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+ {
+ struct irq_cfg *cfg;
+ unsigned int irq;
+
+ if (!cpumask_intersects(mask, cpu_online_mask))
+ return BAD_APICID;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+ if (assign_irq_vector(irq, cfg, mask))
+ return BAD_APICID;
+
- /* check that before desc->addinity get updated */
- set_extra_move_desc(desc, mask);
-
+ cpumask_copy(desc->affinity, mask);
+
+ return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+ }
+
-static void
++static int
+ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
+ {
+ struct irq_cfg *cfg;
+ unsigned long flags;
+ unsigned int dest;
+ unsigned int irq;
++ int ret = -1;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ dest = set_desc_affinity(desc, mask);
+ if (dest != BAD_APICID) {
+ /* Only the high 8 bits are valid. */
+ dest = SET_APIC_LOGICAL_ID(dest);
+ __target_IO_APIC_irq(irq, dest, cfg);
++ ret = 0;
+ }
+ spin_unlock_irqrestore(&ioapic_lock, flags);
++
++ return ret;
+ }
+
-static void
++static int
+ set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask)
+ {
+ struct irq_desc *desc;
+
+ desc = irq_to_desc(irq);
+
- set_ioapic_affinity_irq_desc(desc, mask);
++ return set_ioapic_affinity_irq_desc(desc, mask);
+ }
#ifdef CONFIG_INTR_REMAP
commit e0202f56a82cd1170c6f1c520db669431cf26ddc
Author: Ingo Molnar <mingo@elte.hu>
Date: Fri May 1 16:51:44 2009 +0200
perf_counter tools: fix x86 syscall numbers
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/Documentation/perf_counter/builtin-record.c b/Documentation/perf_counter/builtin-record.c
index 4a50abf843ee..9cff266fb614 100644
--- a/Documentation/perf_counter/builtin-record.c
+++ b/Documentation/perf_counter/builtin-record.c
@@ -57,13 +57,13 @@
#define asmlinkage
#ifdef __x86_64__
-#define __NR_perf_counter_open 295
+#define __NR_perf_counter_open 298
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#endif
#ifdef __i386__
-#define __NR_perf_counter_open 333
+#define __NR_perf_counter_open 336
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#endif
diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c
index 1fde12762ca4..9fbc66173de7 100644
--- a/Documentation/perf_counter/builtin-stat.c
+++ b/Documentation/perf_counter/builtin-stat.c
@@ -108,13 +108,13 @@
#define asmlinkage
#ifdef __x86_64__
-#define __NR_perf_counter_open 295
+#define __NR_perf_counter_open 298
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#endif
#ifdef __i386__
-#define __NR_perf_counter_open 333
+#define __NR_perf_counter_open 336
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#endif
diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c
index 8d28864a20c0..b6d989e7b196 100644
--- a/Documentation/perf_counter/builtin-top.c
+++ b/Documentation/perf_counter/builtin-top.c
@@ -89,13 +89,13 @@
#define asmlinkage
#ifdef __x86_64__
-#define __NR_perf_counter_open 295
+#define __NR_perf_counter_open 298
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#endif
#ifdef __i386__
-#define __NR_perf_counter_open 333
+#define __NR_perf_counter_open 336
#define rmb() asm volatile("lfence" ::: "memory")
#define cpu_relax() asm volatile("rep; nop" ::: "memory");
#endif
commit bad760089c1ef7fe525c0f268a4078b9cb483903
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Apr 30 14:14:37 2009 +0200
perf_counter tools: fix infinite loop in perf-report on zeroed event records
Bail out early if a record has zero size - we have no chance to make
reliable progress in that case. Print out the offset where this happens,
and print the number of bytes we missed out on.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/Documentation/perf_counter/perf-report.cc b/Documentation/perf_counter/perf-report.cc
index 1727317352bf..933a07544534 100644
--- a/Documentation/perf_counter/perf-report.cc
+++ b/Documentation/perf_counter/perf-report.cc
@@ -13,6 +13,7 @@
#include <ctype.h>
#include <time.h>
#include <getopt.h>
+#include <assert.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
@@ -226,7 +227,7 @@ void load_kallsyms(void)
while (!feof(file)) {
uint64_t start;
char c;
- char sym[1024];
+ char sym[1024000];
if (getline(&line, &n, file) < 0)
break;
@@ -416,12 +417,23 @@ more:
if (head + event->header.size >= page_size * mmap_window) {
unsigned long shift = page_size * (head / page_size);
+ int ret;
+
+ ret = munmap(buf, page_size * mmap_window);
+ assert(ret == 0);
- munmap(buf, page_size * mmap_window);
offset += shift;
head -= shift;
goto remap;
}
+
+
+ if (!event->header.size) {
+ fprintf(stderr, "zero-sized event at file offset %ld\n", offset + head);
+ fprintf(stderr, "skipping %ld bytes of events.\n", stat.st_size - offset - head);
+ goto done;
+ }
+
head += event->header.size;
if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) {
@@ -458,6 +470,8 @@ more:
if (offset + head < stat.st_size)
goto more;
+done:
+
close(input);
std::map<std::string, int>::iterator hi = hist.begin();
commit 66cf782996f3d57d3cc199f0a2d47a54e2aa5991
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Apr 30 13:53:33 2009 +0200
perf_counter tools: perf stat: make -l default-on
Turn on scaling display by default - this is less confusing.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c
index 112b94ed3298..1fde12762ca4 100644
--- a/Documentation/perf_counter/builtin-stat.c
+++ b/Documentation/perf_counter/builtin-stat.c
@@ -171,7 +171,7 @@ static unsigned int page_size;
static int zero;
-static int scale;
+static int scale = 1;
static const unsigned int default_count[] = {
1000000,
commit aac3f3c2c41ce49a6dbb98d9145265c00a964dc2
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Apr 30 13:52:19 2009 +0200
perf_counter tools: add perf-report to the Makefile
Build it explicitly until it's a proper builtin command.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile
index 543ccf28ac4a..877cf5dedb55 100644
--- a/Documentation/perf_counter/Makefile
+++ b/Documentation/perf_counter/Makefile
@@ -228,7 +228,7 @@ COMPAT_CFLAGS =
COMPAT_OBJS =
LIB_H =
LIB_OBJS =
-PROGRAMS =
+PROGRAMS = perf-report
SCRIPT_PERL =
SCRIPT_SH =
TEST_PROGRAMS =
@@ -808,6 +808,10 @@ clean:
$(RM) $(htmldocs).tar.gz $(manpages).tar.gz
$(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS
+# temporary hack:
+perf-report: perf-report.cc ../../include/linux/perf_counter.h Makefile
+ g++ -g -O2 -Wall -lrt -o $@ $<
+
.PHONY: all install clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
.PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
commit 98144511427c192e4249ff66a3f9debc55c59411
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Apr 29 14:52:50 2009 +0200
perf_counter: add/update copyrights
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index 856b0b852192..47e563bfd4cf 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -1,10 +1,11 @@
/*
* Performance counter x86 architecture code
*
- * Copyright(C) 2008 Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar
- * Copyright(C) 2009 Jaswinder Singh Rajput
- * Copyright(C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ * Copyright (C) 2009 Jaswinder Singh Rajput
+ * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
*
* For licencing details see kernel-base/COPYING
*/
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 582108addefa..a95a171e608c 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1,9 +1,9 @@
/*
* Performance counter core code
*
- * Copyright(C) 2008 Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar
- *
+ * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
*
* For licensing details see kernel-base/COPYING
*/
commit e7fd5d4b3d240f42c30a9e3d20a4689c4d3a795a
Merge: 1130b0296184 56a50adda49b
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Apr 29 14:46:59 2009 +0200
Merge branch 'linus' into perfcounters/core
Merge reason: This brach was on -rc1, refresh it to almost-rc4 to pick up
the latest upstream fixes.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --cc MAINTAINERS
index 16fb45adb53e,c547f4a2bb62..5114b5341df4
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@@ -3482,17 -4372,9 +4372,19 @@@ P: Balbir Sing
M: balbir@linux.vnet.ibm.com
L: linux-kernel@vger.kernel.org
S: Maintained
+ F: include/linux/delayacct.h
+ F: kernel/delayacct.c
+PERFORMANCE COUNTER SUBSYSTEM
+P: Peter Zijlstra
+M: a.p.zijlstra@chello.nl
+P: Paul Mackerras
+M: paulus@samba.org
+P: Ingo Molnar
+M: mingo@elte.hu
+L: linux-kernel@vger.kernel.org
+S: Supported
+
PERSONALITY HANDLING
P: Christoph Hellwig
M: hch@infradead.org
diff --cc arch/x86/kernel/irq.c
index 849cfabb1fdc,c3fe010d74c8..8279fb8df17f
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@@ -63,17 -63,9 +63,17 @@@ static int show_other_interrupts(struc
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
seq_printf(p, " Spurious interrupts\n");
+ seq_printf(p, "%*s: ", prec, "CNT");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
+ seq_printf(p, " Performance counter interrupts\n");
+ seq_printf(p, "%*s: ", prec, "PND");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
+ seq_printf(p, " Performance pending work\n");
#endif
if (generic_interrupt_extension) {
- seq_printf(p, "PLT: ");
+ seq_printf(p, "%*s: ", prec, "PLT");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->generic_irqs);
seq_printf(p, " Platform interrupts\n");
commit fd0731944333db6e9e91b6954c6ef95f4b71ab04
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Apr 29 12:56:58 2009 +0200
x86, vmlinux.lds: fix relocatable symbols
__init_begin/_end symbols should be inside sections as well,
otherwise the relocatable kernel gets confused when freeing
init sections in the wrong place.
[ Impact: fix bootup crash ]
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Tim Abbott <tabbott@MIT.EDU>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
LKML-Reference: <20090429105056.GA28720@uranus.ravnborg.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 0bdbaa579696..4c85b2e2bb65 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -255,8 +255,8 @@ SECTIONS
/* Init code and data - will be freed after init */
. = ALIGN(PAGE_SIZE);
- __init_begin = .; /* paired with __init_end */
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
+ __init_begin = .; /* paired with __init_end */
_sinittext = .;
INIT_TEXT
_einittext = .;
@@ -346,8 +346,11 @@ SECTIONS
#endif
. = ALIGN(PAGE_SIZE);
+
/* freed after init ends here */
- __init_end = .;
+ .init.end : AT(ADDR(.init.end) - LOAD_OFFSET) {
+ __init_end = .;
+ }
#ifdef CONFIG_X86_64
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {