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
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.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-$(CONFIG_ALPHA_GENERIC) += op_model_ev4.o \
......
......@@ -3,8 +3,9 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.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 \
op_model_ppro.o op_model_p4.o
......@@ -11,22 +11,19 @@
#include <linux/init.h>
/* We support CPUs that have performance counters like the Pentium Pro
* with NMI mode samples. Other x86 CPUs use a simple interrupt keyed
* off the timer interrupt, which cannot profile interrupts-disabled
* code unlike the NMI-based code.
* with the NMI mode driver.
*/
extern int nmi_init(struct oprofile_operations ** ops);
extern void nmi_exit(void);
extern void timer_init(struct oprofile_operations ** ops);
int __init oprofile_arch_init(struct oprofile_operations ** ops)
{
#ifdef CONFIG_X86_LOCAL_APIC
if (!nmi_init(ops))
return nmi_init(ops);
#else
return -ENODEV;
#endif
timer_init(ops);
return 0;
}
......
......@@ -314,13 +314,13 @@ int __init nmi_init(struct oprofile_operations ** ops)
__u8 family = current_cpu_data.x86;
if (!cpu_has_apic)
return 0;
return -ENODEV;
switch (vendor) {
case X86_VENDOR_AMD:
/* Needs to be at least an Athlon (or hammer in 32bit mode) */
if (family < 6)
return 0;
return -ENODEV;
model = &op_athlon_spec;
nmi_ops.cpu_type = "i386/athlon";
break;
......@@ -331,30 +331,30 @@ int __init nmi_init(struct oprofile_operations ** ops)
/* Pentium IV */
case 0xf:
if (!p4_init())
return 0;
return -ENODEV;
break;
/* A P6-class processor */
case 6:
if (!ppro_init())
return 0;
return -ENODEV;
break;
default:
return 0;
return -ENODEV;
}
break;
#endif /* !CONFIG_X86_64 */
default:
return 0;
return -ENODEV;
}
init_driverfs();
using_nmi = 1;
*ops = &nmi_ops;
printk(KERN_INFO "oprofile: using NMI interrupt.\n");
return 1;
return 0;
}
......
......@@ -3,6 +3,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.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);
int __init oprofile_arch_init(struct oprofile_operations ** ops)
{
timer_init(ops);
return 0;
return -ENODEV;
}
......
/**
* @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
DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.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);
int __init oprofile_arch_init(struct oprofile_operations ** ops)
{
timer_init(ops);
return 0;
return -ENODEV;
}
......
/**
* @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
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.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);
int __init oprofile_arch_init(struct oprofile_operations ** ops)
{
timer_init(ops);
return 0;
return -ENODEV;
}
......
/**
* @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
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.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
......@@ -23,11 +24,9 @@ $(obj)/op_model_athlon.c: ${INCL}
@ln -sf ../../i386/oprofile/op_model_athlon.c $(obj)/op_model_athlon.c
$(obj)/init.c: ${INCL}
@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:
@ln -sf ../../i386/oprofile/op_counter.h $(obj)/op_counter.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
......@@ -119,14 +119,23 @@ void oprofile_shutdown(void)
}
extern void timer_init(struct oprofile_operations ** ops);
static int __init oprofile_init(void)
{
int err;
/* 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);
if (err == -ENODEV) {
timer_init(&oprofile_ops);
err = 0;
}
if (err)
goto out;
......
......@@ -14,8 +14,6 @@
#include <linux/oprofile.h>
#include <asm/ptrace.h>
#include "op_counter.h"
static int timer_notify(struct notifier_block * self, unsigned long val, void * 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