Commit 72e8f923 authored by John Levon's avatar John Levon Committed by Linus Torvalds

[PATCH] OProfile update

Consolidate all the arch copies of timer_int.c into one place. Also fixes
a problem with PA-RISC not using instruction_pointer() when it should.
parent c8a9c4b3
...@@ -5,7 +5,8 @@ obj-$(CONFIG_OPROFILE) += oprofile.o ...@@ -5,7 +5,8 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o ) oprofilefs.o oprofile_stats.o \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) common.o oprofile-y := $(DRIVER_OBJS) common.o
oprofile-$(CONFIG_ALPHA_GENERIC) += op_model_ev4.o \ oprofile-$(CONFIG_ALPHA_GENERIC) += op_model_ev4.o \
......
...@@ -3,8 +3,9 @@ obj-$(CONFIG_OPROFILE) += oprofile.o ...@@ -3,8 +3,9 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o ) oprofilefs.o oprofile_stats.o \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) init.o timer_int.o oprofile-y := $(DRIVER_OBJS) init.o
oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \ oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \
op_model_ppro.o op_model_p4.o op_model_ppro.o op_model_p4.o
...@@ -11,22 +11,19 @@ ...@@ -11,22 +11,19 @@
#include <linux/init.h> #include <linux/init.h>
/* We support CPUs that have performance counters like the Pentium Pro /* We support CPUs that have performance counters like the Pentium Pro
* with NMI mode samples. Other x86 CPUs use a simple interrupt keyed * with the NMI mode driver.
* off the timer interrupt, which cannot profile interrupts-disabled
* code unlike the NMI-based code.
*/ */
extern int nmi_init(struct oprofile_operations ** ops); extern int nmi_init(struct oprofile_operations ** ops);
extern void nmi_exit(void); extern void nmi_exit(void);
extern void timer_init(struct oprofile_operations ** ops);
int __init oprofile_arch_init(struct oprofile_operations ** ops) int __init oprofile_arch_init(struct oprofile_operations ** ops)
{ {
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
if (!nmi_init(ops)) return nmi_init(ops);
#else
return -ENODEV;
#endif #endif
timer_init(ops);
return 0;
} }
......
...@@ -314,13 +314,13 @@ int __init nmi_init(struct oprofile_operations ** ops) ...@@ -314,13 +314,13 @@ int __init nmi_init(struct oprofile_operations ** ops)
__u8 family = current_cpu_data.x86; __u8 family = current_cpu_data.x86;
if (!cpu_has_apic) if (!cpu_has_apic)
return 0; return -ENODEV;
switch (vendor) { switch (vendor) {
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
/* Needs to be at least an Athlon (or hammer in 32bit mode) */ /* Needs to be at least an Athlon (or hammer in 32bit mode) */
if (family < 6) if (family < 6)
return 0; return -ENODEV;
model = &op_athlon_spec; model = &op_athlon_spec;
nmi_ops.cpu_type = "i386/athlon"; nmi_ops.cpu_type = "i386/athlon";
break; break;
...@@ -331,30 +331,30 @@ int __init nmi_init(struct oprofile_operations ** ops) ...@@ -331,30 +331,30 @@ int __init nmi_init(struct oprofile_operations ** ops)
/* Pentium IV */ /* Pentium IV */
case 0xf: case 0xf:
if (!p4_init()) if (!p4_init())
return 0; return -ENODEV;
break; break;
/* A P6-class processor */ /* A P6-class processor */
case 6: case 6:
if (!ppro_init()) if (!ppro_init())
return 0; return -ENODEV;
break; break;
default: default:
return 0; return -ENODEV;
} }
break; break;
#endif /* !CONFIG_X86_64 */ #endif /* !CONFIG_X86_64 */
default: default:
return 0; return -ENODEV;
} }
init_driverfs(); init_driverfs();
using_nmi = 1; using_nmi = 1;
*ops = &nmi_ops; *ops = &nmi_ops;
printk(KERN_INFO "oprofile: using NMI interrupt.\n"); printk(KERN_INFO "oprofile: using NMI interrupt.\n");
return 1; return 0;
} }
......
...@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o ...@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o ) oprofilefs.o oprofile_stats.o \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) init.o timer_int.o oprofile-y := $(DRIVER_OBJS) init.o
...@@ -15,8 +15,7 @@ extern void timer_init(struct oprofile_operations ** ops); ...@@ -15,8 +15,7 @@ extern void timer_init(struct oprofile_operations ** ops);
int __init oprofile_arch_init(struct oprofile_operations ** ops) int __init oprofile_arch_init(struct oprofile_operations ** ops)
{ {
timer_init(ops); return -ENODEV;
return 0;
} }
......
/**
* @file timer_int.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/oprofile.h>
#include <asm/ptrace.h>
static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
{
struct pt_regs * regs = (struct pt_regs *)data;
int cpu = smp_processor_id();
unsigned long pc = regs->iaoq[0];
int is_kernel = !user_mode(regs);
oprofile_add_sample(pc, is_kernel, 0, cpu);
return 0;
}
static struct notifier_block timer_notifier = {
.notifier_call = timer_notify,
};
static int timer_start(void)
{
return register_profile_notifier(&timer_notifier);
}
static void timer_stop(void)
{
unregister_profile_notifier(&timer_notifier);
}
static struct oprofile_operations timer_ops = {
.start = timer_start,
.stop = timer_stop,
.cpu_type = "timer"
};
void __init timer_init(struct oprofile_operations ** ops)
{
*ops = &timer_ops;
printk(KERN_INFO "oprofile: using timer interrupt.\n");
}
...@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o ...@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o ) oprofilefs.o oprofile_stats.o \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) init.o timer_int.o oprofile-y := $(DRIVER_OBJS) init.o
...@@ -15,8 +15,7 @@ extern void timer_init(struct oprofile_operations ** ops); ...@@ -15,8 +15,7 @@ extern void timer_init(struct oprofile_operations ** ops);
int __init oprofile_arch_init(struct oprofile_operations ** ops) int __init oprofile_arch_init(struct oprofile_operations ** ops)
{ {
timer_init(ops); return -ENODEV;
return 0;
} }
......
/**
* @file timer_int.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/oprofile.h>
#include <linux/profile.h>
#include <asm/ptrace.h>
static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
{
struct pt_regs * regs = (struct pt_regs *)data;
int cpu = smp_processor_id();
unsigned long pc = instruction_pointer(regs);
int is_kernel = !user_mode(regs);
oprofile_add_sample(pc, is_kernel, 0, cpu);
return 0;
}
static struct notifier_block timer_notifier = {
.notifier_call = timer_notify,
};
static int timer_start(void)
{
return register_profile_notifier(&timer_notifier);
}
static void timer_stop(void)
{
unregister_profile_notifier(&timer_notifier);
}
static struct oprofile_operations timer_ops = {
.start = timer_start,
.stop = timer_stop,
.cpu_type = "timer"
};
void __init timer_init(struct oprofile_operations ** ops)
{
*ops = &timer_ops;
printk(KERN_INFO "oprofile: using timer interrupt.\n");
}
...@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o ...@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o ) oprofilefs.o oprofile_stats.o \
timer_int.o )
oprofile-y := $(DRIVER_OBJS) init.o timer_int.o oprofile-y := $(DRIVER_OBJS) init.o
...@@ -15,8 +15,7 @@ extern void timer_init(struct oprofile_operations ** ops); ...@@ -15,8 +15,7 @@ extern void timer_init(struct oprofile_operations ** ops);
int __init oprofile_arch_init(struct oprofile_operations ** ops) int __init oprofile_arch_init(struct oprofile_operations ** ops)
{ {
timer_init(ops); return -ENODEV;
return 0;
} }
......
/**
* @file timer_int.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/oprofile.h>
#include <linux/profile.h>
#include <asm/ptrace.h>
static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
{
struct pt_regs * regs = (struct pt_regs *)data;
int cpu = smp_processor_id();
unsigned long pc = instruction_pointer(regs);
int is_kernel = !user_mode(regs);
oprofile_add_sample(pc, is_kernel, 0, cpu);
return 0;
}
static struct notifier_block timer_notifier = {
.notifier_call = timer_notify,
};
static int timer_start(void)
{
return register_profile_notifier(&timer_notifier);
}
static void timer_stop(void)
{
unregister_profile_notifier(&timer_notifier);
}
static struct oprofile_operations timer_ops = {
.start = timer_start,
.stop = timer_stop,
.cpu_type = "timer"
};
void __init timer_init(struct oprofile_operations ** ops)
{
*ops = &timer_ops;
printk(KERN_INFO "oprofile: using timer interrupt.\n");
}
...@@ -9,9 +9,10 @@ obj-$(CONFIG_OPROFILE) += oprofile.o ...@@ -9,9 +9,10 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \ oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \ event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o ) oprofilefs.o oprofile_stats.o \
timer_int.o )
oprofile-objs := $(DRIVER_OBJS) init.o timer_int.o oprofile-objs := $(DRIVER_OBJS) init.o
oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o
...@@ -23,11 +24,9 @@ $(obj)/op_model_athlon.c: ${INCL} ...@@ -23,11 +24,9 @@ $(obj)/op_model_athlon.c: ${INCL}
@ln -sf ../../i386/oprofile/op_model_athlon.c $(obj)/op_model_athlon.c @ln -sf ../../i386/oprofile/op_model_athlon.c $(obj)/op_model_athlon.c
$(obj)/init.c: ${INCL} $(obj)/init.c: ${INCL}
@ln -sf ../../i386/oprofile/init.c $(obj)/init.c @ln -sf ../../i386/oprofile/init.c $(obj)/init.c
$(obj)/timer_int.c: ${INCL}
@ln -sf ../../i386/oprofile/timer_int.c $(obj)/timer_int.c
$(obj)/op_counter.h: $(obj)/op_counter.h:
@ln -sf ../../i386/oprofile/op_counter.h $(obj)/op_counter.h @ln -sf ../../i386/oprofile/op_counter.h $(obj)/op_counter.h
$(obj)/op_x86_model.h: $(obj)/op_x86_model.h:
@ln -sf ../../i386/oprofile/op_x86_model.h $(obj)/op_x86_model.h @ln -sf ../../i386/oprofile/op_x86_model.h $(obj)/op_x86_model.h
clean-files += op_x86_model.h op_counter.h timer_int.c init.c \ clean-files += op_x86_model.h op_counter.h init.c \
op_model_athlon.c nmi_int.c op_model_athlon.c nmi_int.c
...@@ -119,14 +119,23 @@ void oprofile_shutdown(void) ...@@ -119,14 +119,23 @@ void oprofile_shutdown(void)
} }
extern void timer_init(struct oprofile_operations ** ops);
static int __init oprofile_init(void) static int __init oprofile_init(void)
{ {
int err; int err;
/* Architecture must fill in the interrupt ops and the /* Architecture must fill in the interrupt ops and the
* logical CPU type. * logical CPU type, or we can fall back to the timer
* interrupt profiler.
*/ */
err = oprofile_arch_init(&oprofile_ops); err = oprofile_arch_init(&oprofile_ops);
if (err == -ENODEV) {
timer_init(&oprofile_ops);
err = 0;
}
if (err) if (err)
goto out; goto out;
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include "op_counter.h"
static int timer_notify(struct notifier_block * self, unsigned long val, void * data) static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
{ {
struct pt_regs * regs = (struct pt_regs *)data; struct pt_regs * regs = (struct pt_regs *)data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment