ia64 oprofile support for 2.6.0-test4
PATCH 1/1 ia64 oprofile support for 2.6.0-test4
I have revised the oprofile patch for ia64 to provide just the basic timer interrupt mechanism to avoid interferring with the perfmon 2.0 support. I have verified the oprofile ia64 patch applies cleanly and build a working kernel with the 2.6.0-test4 kernel and the linux-2.6.0-test4-ia64-030826.diff.bz2 patch.
More work is required to get oprofile to work with the perfmon 2.0. However, the patch as it is currently implements should not cause problems for the perfom 2.0 support.
-Will
arch/ia64/kernel/time.c renamed from arch/ia64/kernel/time.c.orig +44 -30
@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/efi.h> #include <linux/timex.h> +#include <linux/profile.h> #include <asm/delay.h> #include <asm/hw_irq.h>
@@ -39,29 +40,6 @@#endif static void -do_profile (unsigned long ip) -{ -extern cpumask_t prof_cpu_mask; - -if (!prof_buffer) -return ; - -if (!cpu_isset (smp_processor_id (), prof_cpu_mask)) -return ; - - ip -= (unsigned long ) _stext; - ip >>= prof_shift; -/* -* Don't ignore out-of-bounds IP values silently, put them into the last -* histogram slot, so if present, they will show up as a sharp peak. -*/ -if (ip > prof_len -1 ) - ip = prof_len -1 ; - -atomic_inc ((atomic_t *) &prof_buffer[ip]); -} - -static void itc_reset (void ) { }
@@ -199,6 +177,47 @@ tv->tv_usec = usec; } +/* +* The profiling function is SMP safe. (nothing can mess +* around with "current", and the profiling counters are +* updated with atomic operations). This is especially +* useful with a profiling multiplier != 1 +*/ +static inline void +ia64_do_profile (struct pt_regs * regs) +{ +unsigned long eip; +extern unsigned long prof_cpu_mask; + +profile_hook (regs); + +if (user_mode (regs)) +return ; + +if (!prof_buffer) +return ; + + eip =instruction_pointer (regs); + +/* +* Only measure the CPUs specified by /proc/irq/prof_cpu_mask. +* (default is all CPUs.) +*/ +if (!((1 <<smp_processor_id ()) & prof_cpu_mask)) +return ; + + eip -= (unsigned long ) &_stext; + eip >>= prof_shift; +/* +* Don't ignore out-of-bounds EIP values silently, +* put them into the last histogram slot, so if +* present, they will show up as a sharp peak. +*/ +if (eip > prof_len-1 ) + eip = prof_len-1 ; +atomic_inc ((atomic_t *)&prof_buffer[eip]); +} +static irqreturn_t timer_interrupt (int irq,void *dev_id,struct pt_regs *regs) {
@@ -210,14 +229,9 @@printk (KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n" ,ia64_get_itc (), new_itm); +ia64_do_profile (regs); +while (1 ) { -/* -* Do kernel PC profiling here. We multiply the instruction number by -* four so that we can use a prof_shift of 2 to get instruction-level -* instead of just bundle-level accuracy. -*/ -if (!user_mode (regs)) -do_profile (regs->cr_iip +4 *ia64_psr (regs)->ri);#ifdef CONFIG_SMP smp_do_timer (regs);
arch/ia64/Makefile renamed from arch/ia64/Makefile.orig +1 -0
@@ -65,6 +65,7 @@ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ +drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot
arch/ia64/oprofile/init.c new file +25 -0
@@ -0,0 +1,25 @@ +/** +* @file init.c +* +* @remark Copyright 2002 OProfile authors +* @remark Read the file COPYING +* +* @author John Levon <[email protected]> +*/ + +#include <linux/kernel.h> +#include <linux/oprofile.h> +#include <linux/init.h> +#include <linux/errno.h> + +extern void timer_init (struct oprofile_operations ** ops); + +int __init oprofile_arch_init (struct oprofile_operations ** ops) +{ +return -ENODEV ; +} + + +void oprofile_arch_exit (void ) +{ +}
arch/ia64/oprofile/Kconfig new file +23 -0
@@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu +
arch/ia64/oprofile/Makefile new file +9 -0
@@ -0,0 +1,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 \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) init.o
arch/ia64/Kconfig renamed from arch/ia64/Kconfig.orig +2 -0
@@ -589,6 +589,8 @@ source "arch/ia64/hp/sim/Kconfig" +source "arch/ia64/oprofile/Kconfig" + menu "Kernel hacking"
include/asm-ia64/hw_irq.h renamed from include/asm-ia64/hw_irq.h.orig +1 -0
@@ -9,6 +9,7 @@#include <linux/interrupt.h> #include <linux/sched.h> #include <linux/types.h> +#include <linux/profile.h> #include <asm/machvec.h> #include <asm/ptrace.h>
include/asm-ia64/ptrace.h renamed from include/asm-ia64/ptrace.h.orig +7 -0
@@ -223,6 +223,13 @@ };#ifdef __KERNEL__ +/* +* We use the ia64_psr(regs)->ri to determine which of the three +* instructions in bundle took the sample. The instructions in the +* ia64 do not fall on nice four byte boundaries, so there is no point +* in multiplying ia64_psr(regs)->ri by 4. +*/ +#define instruction_pointer (regs) ((regs)->cr_iip + ia64_psr(regs)->ri)/* given a pointer to a task_struct, return the user's pt_regs */ # define ia64_task_regs (t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)# define ia64_psr (regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Will Cohen
Will> + eip = instruction_pointer(regs);
eip? How about calling it "ip", which is the register name and what's used everywhere else in the ia64 tree.
Will> +/*
Will> + * We use the ia64_psr(regs)->ri to determine which of the three Will> + * instructions in bundle took the sample. The instructions in the Will> + * ia64 do not fall on nice four byte boundaries, so there is no point Will> + * in multiplying ia64_psr(regs)->ri by 4.
Will> + */
Will> +#define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
How are you going to get instruction-level precision with this?
Given this:
Will> - ip >>= prof_shift;
you'd have to use a prof_shift of 0, which is wasteful. If you multiply ri by 4, you can use a prof_shift of 2, reducing the histogram size by a factor of 4 while still getting instruction-level accuracy.
I can see why you don't want to do the multiply-by-four in instruction_pointer(), but if that's what you want to avoid, I think ia64_do_profile() should should do it so we can get the desired effect.
--david
Quoted 16 lines · David Mosberger
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 1 line · Will Cohen
Will> + eip = instruction_pointer(regs);eip? How about calling it "ip", which is the register name and what's used everywhere else in the ia64 tree.
Will> +/*
Will> + * We use the ia64_psr(regs)->ri to determine which of the three Will> + * instructions in bundle took the sample. The instructions in the Will> + * ia64 do not fall on nice four byte boundaries, so there is no point Will> + * in multiplying ia64_psr(regs)->ri by 4.
Will> + */
Will> +#defineinstruction_pointer(regs)((regs)->cr_iip + ia64_psr(regs)->ri)
Quoted 1 line
How are you going to get instruction-level precision with this?
I looked at gdb handled this. It appeared for setting break points and disassembling code gdb handles the instructions in the bundle in this manner. Putting the instruction number as the low bits in the address, 0, 1, or 2.
Quoted 9 lines
Given this:
Will> - ip >>= prof_shift;you'd have to use a
prof_shiftof 0, which is wasteful. If you multiply ri by 4, you can use aprof_shiftof 2, reducing the histogram size by a factor of 4 while still getting instruction-level accuracy.
Quoted 6 lines
I can see why you don't want to do the multiply-by-four in
instruction_pointer(), but if that's what you want to avoid, I thinkia64_do_profile()should should do it so we can get the desired effect.--david
For OProfile it didn't make a difference, but for the histograms it is wasteful. I didn't think about the impact on the traditional histogram. There are two different ways that the instructions within a bundle are being handled: gdb and the kernel profiling code. I chose the gdb approach.
Do the histogram analysis tools currently handle the fiction of bundle instruction 0 at address ending in 0, bundle instruction 1 ending in 4, and bundle instruction 2 in 8? GDB doesn't.
-Will
I have revised the patch based on the comments below:
1) use ip instead of eip
2) multiply ri by 4, to get more compact histograms
-Will
Quoted 27 lines · David Mosberger
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 1 line · Will Cohen
Will> + eip = instruction_pointer(regs);eip? How about calling it "ip", which is the register name and what's used everywhere else in the ia64 tree.
Will> +/*
Will> + * We use the ia64_psr(regs)->ri to determine which of the three Will> + * instructions in bundle took the sample. The instructions in the Will> + * ia64 do not fall on nice four byte boundaries, so there is no point Will> + * in multiplying ia64_psr(regs)->ri by 4.
Will> + */
Will> +#defineinstruction_pointer(regs)((regs)->cr_iip + ia64_psr(regs)->ri)How are you going to get instruction-level precision with this?
Given this:
Will> - ip >>= prof_shift;you'd have to use a
prof_shiftof 0, which is wasteful. If you multiply ri by 4, you can use aprof_shiftof 2, reducing the histogram size by a factor of 4 while still getting instruction-level accuracy.
Quoted 6 lines
I can see why you don't want to do the multiply-by-four in
instruction_pointer(), but if that's what you want to avoid, I thinkia64_do_profile()should should do it so we can get the desired effect.--david
arch/ia64/kernel/time.c renamed from arch/ia64/kernel/time.c.orig +44 -30
@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/efi.h> #include <linux/timex.h> +#include <linux/profile.h> #include <asm/delay.h> #include <asm/hw_irq.h>
@@ -39,29 +40,6 @@#endif static void -do_profile (unsigned long ip) -{ -extern cpumask_t prof_cpu_mask; - -if (!prof_buffer) -return ; - -if (!cpu_isset (smp_processor_id (), prof_cpu_mask)) -return ; - - ip -= (unsigned long ) _stext; - ip >>= prof_shift; -/* -* Don't ignore out-of-bounds IP values silently, put them into the last -* histogram slot, so if present, they will show up as a sharp peak. -*/ -if (ip > prof_len -1 ) - ip = prof_len -1 ; - -atomic_inc ((atomic_t *) &prof_buffer[ip]); -} - -static void itc_reset (void ) { }
@@ -199,6 +177,47 @@ tv->tv_usec = usec; } +/* +* The profiling function is SMP safe. (nothing can mess +* around with "current", and the profiling counters are +* updated with atomic operations). This is especially +* useful with a profiling multiplier != 1 +*/ +static inline void +ia64_do_profile (struct pt_regs * regs) +{ +unsigned long ip; +extern unsigned long prof_cpu_mask; + +profile_hook (regs); + +if (user_mode (regs)) +return ; + +if (!prof_buffer) +return ; + + ip =instruction_pointer (regs); + +/* +* Only measure the CPUs specified by /proc/irq/prof_cpu_mask. +* (default is all CPUs.) +*/ +if (!((1 <<smp_processor_id ()) & prof_cpu_mask)) +return ; + + ip -= (unsigned long ) &_stext; + ip >>= prof_shift; +/* +* Don't ignore out-of-bounds IP values silently, +* put them into the last histogram slot, so if +* present, they will show up as a sharp peak. +*/ +if (ip > prof_len-1 ) + ip = prof_len-1 ; +atomic_inc ((atomic_t *)&prof_buffer[ip]); +} +static irqreturn_t timer_interrupt (int irq,void *dev_id,struct pt_regs *regs) {
@@ -210,14 +229,9 @@printk (KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n" ,ia64_get_itc (), new_itm); +ia64_do_profile (regs); +while (1 ) { -/* -* Do kernel PC profiling here. We multiply the instruction number by -* four so that we can use a prof_shift of 2 to get instruction-level -* instead of just bundle-level accuracy. -*/ -if (!user_mode (regs)) -do_profile (regs->cr_iip +4 *ia64_psr (regs)->ri);#ifdef CONFIG_SMP smp_do_timer (regs);
arch/ia64/Makefile renamed from arch/ia64/Makefile.orig +1 -0
@@ -65,6 +65,7 @@ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ +drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot
arch/ia64/oprofile/init.c new file +25 -0
@@ -0,0 +1,25 @@ +/** +* @file init.c +* +* @remark Copyright 2002 OProfile authors +* @remark Read the file COPYING +* +* @author John Levon <[email protected]> +*/ + +#include <linux/kernel.h> +#include <linux/oprofile.h> +#include <linux/init.h> +#include <linux/errno.h> + +extern void timer_init (struct oprofile_operations ** ops); + +int __init oprofile_arch_init (struct oprofile_operations ** ops) +{ +return -ENODEV ; +} + + +void oprofile_arch_exit (void ) +{ +}
arch/ia64/oprofile/Kconfig new file +23 -0
@@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu +
arch/ia64/oprofile/Makefile new file +9 -0
@@ -0,0 +1,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 \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) init.o
arch/ia64/Kconfig renamed from arch/ia64/Kconfig.orig +2 -0
@@ -589,6 +589,8 @@ source "arch/ia64/hp/sim/Kconfig" +source "arch/ia64/oprofile/Kconfig" + menu "Kernel hacking"
include/asm-ia64/hw_irq.h renamed from include/asm-ia64/hw_irq.h.orig +1 -0
@@ -9,6 +9,7 @@#include <linux/interrupt.h> #include <linux/sched.h> #include <linux/types.h> +#include <linux/profile.h> #include <asm/machvec.h> #include <asm/ptrace.h>
include/asm-ia64/ptrace.h renamed from include/asm-ia64/ptrace.h.orig +8 -0
@@ -223,6 +223,14 @@ };#ifdef __KERNEL__ +/* +* We use the ia64_psr(regs)->ri to determine which of the three +* instructions in bundle (16 bytes) took the sample. The instructions +* in the ia64 do not fall on nice four byte boundaries. However, to +* save space in the histogram, the instructions are mapped to 4 +* byte boundaries. +*/ +#define instruction_pointer (regs) ((regs)->cr_iip + 4*ia64_psr(regs)->ri)/* given a pointer to a task_struct, return the user's pt_regs */ # define ia64_task_regs (t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)# define ia64_psr (regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Will Cohen
Will> For OProfile it didn't make a difference, but for the Will> histograms it is wasteful. I didn't think about the impact on Will> the traditional histogram.
You can't just break existing data formats for absolutely no reason.
Will> Do the histogram analysis tools currently handle
Yes. For example, I use "readprofile -b" from time to time to get instruction-level histograms.
Will> the fiction of bundle instruction 0 at address ending in 0, Will> bundle instruction 1 ending in 4, and bundle instruction 2 in Will> 8? GDB doesn't.
And encoding the slot number in bits 0 and 1 is somehow less fictitious? ;-)
--david
Quoted 14 lines · David Mosberger
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 1 line · Will Cohen
Will> For OProfile it didn't make a difference, but for the Will> histograms it is wasteful. I didn't think about the impact on Will> the traditional histogram.
You can't just break existing data formats for absolutely no reason.
Will> Do the histogram analysis tools currently handle
Yes. For example, I use "readprofile -b" from time to time to get instruction-level histograms.
Quoted 6 lines
Will> the fiction of bundle instruction 0 at address ending in 0, Will> bundle instruction 1 ending in 4, and bundle instruction 2 in Will> 8? GDB doesn't.
And encoding the slot number in bits 0 and 1 is somehow less fictitious? ;-)
They are equally fictitious. I just happen to pick the wrong one. I changed the patch to be compatible with the existing data format used for the kernel profiling.
-Will
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Will Cohen
Will> I have revised the patch based on the comments below: 1) use Will> ip instead of eip 2) multiply ri by 4, to get more compact Will> histograms
Hmmh, I'm not sure I like this patch better. Like I mentioned in the earlier mail, it does make sense to encode the slot number in bits 0 and 1 for instruction_pointer(). That is the canonical representation used by IA-64 Linux (and ELF, gdb, etc.). The traditional histogram is a special case, because there it is more useful to get the slot number bits close to the bundle-address bits, so I think we should special-case this in ia64_do_profile() instead. Perhaps something along the lines of:
ip = instruction_pointer(regs); /* for histogram, encode slot bits in address bits 2 and 3: */ slot = ip & 3; ip = (ip & ~3UL) + 4*slot;
--david
Revised the instruction_pointer to return the canonical ip and ia64_do_profile() to adjust the resulting ip value for the histogram.
-Will
Quoted 16 lines · David Mosberger
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 1 line · Will Cohen
Will> I have revised the patch based on the comments below: 1) use Will> ip instead of eip 2) multiply ri by 4, to get more compact Will> histograms
Hmmh, I'm not sure I like this patch better. Like I mentioned in the earlier mail, it does make sense to encode the slot number in bits 0 and 1 for
instruction_pointer(). That is the canonical representation used by IA-64 Linux (and ELF, gdb, etc.). The traditional histogram is a special case, because there it is more useful to get the slot number bits close to the bundle-address bits, so I think we should special-case this inia64_do_profile()instead. Perhaps something along the lines of:
Quoted 6 lines
ip = instruction_pointer(regs); /* for histogram, encode slot bits in address bits 2 and 3: */ slot = ip & 3; ip = (ip & ~3UL) + 4*slot;--david
arch/ia64/kernel/time.c renamed from arch/ia64/kernel/time.c.orig +49 -30
@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/efi.h> #include <linux/timex.h> +#include <linux/profile.h> #include <asm/delay.h> #include <asm/hw_irq.h>
@@ -39,29 +40,6 @@#endif static void -do_profile (unsigned long ip) -{ -extern cpumask_t prof_cpu_mask; - -if (!prof_buffer) -return ; - -if (!cpu_isset (smp_processor_id (), prof_cpu_mask)) -return ; - - ip -= (unsigned long ) _stext; - ip >>= prof_shift; -/* -* Don't ignore out-of-bounds IP values silently, put them into the last -* histogram slot, so if present, they will show up as a sharp peak. -*/ -if (ip > prof_len -1 ) - ip = prof_len -1 ; - -atomic_inc ((atomic_t *) &prof_buffer[ip]); -} - -static void itc_reset (void ) { }
@@ -199,6 +177,52 @@ tv->tv_usec = usec; } +/* +* The profiling function is SMP safe. (nothing can mess +* around with "current", and the profiling counters are +* updated with atomic operations). This is especially +* useful with a profiling multiplier != 1 +*/ +static inline void +ia64_do_profile (struct pt_regs * regs) +{ +unsigned long ip, slot; +extern unsigned long prof_cpu_mask; + +profile_hook (regs); + +if (user_mode (regs)) +return ; + +if (!prof_buffer) +return ; + + ip =instruction_pointer (regs); +/* Conserve space in histogram by encoding slot bits in address +* bits 2 and 3 rather than bits 0 and 1. +*/ + slot = ip &3 ; + ip = (ip & ~3UL ) +4 *slot; + +/* +* Only measure the CPUs specified by /proc/irq/prof_cpu_mask. +* (default is all CPUs.) +*/ +if (!((1 <<smp_processor_id ()) & prof_cpu_mask)) +return ; + + ip -= (unsigned long ) &_stext; + ip >>= prof_shift; +/* +* Don't ignore out-of-bounds IP values silently, +* put them into the last histogram slot, so if +* present, they will show up as a sharp peak. +*/ +if (ip > prof_len-1 ) + ip = prof_len-1 ; +atomic_inc ((atomic_t *)&prof_buffer[ip]); +} +static irqreturn_t timer_interrupt (int irq,void *dev_id,struct pt_regs *regs) {
@@ -210,14 +234,9 @@printk (KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n" ,ia64_get_itc (), new_itm); +ia64_do_profile (regs); +while (1 ) { -/* -* Do kernel PC profiling here. We multiply the instruction number by -* four so that we can use a prof_shift of 2 to get instruction-level -* instead of just bundle-level accuracy. -*/ -if (!user_mode (regs)) -do_profile (regs->cr_iip +4 *ia64_psr (regs)->ri);#ifdef CONFIG_SMP smp_do_timer (regs);
arch/ia64/Makefile renamed from arch/ia64/Makefile.orig +1 -0
@@ -65,6 +65,7 @@ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ +drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot
arch/ia64/oprofile/init.c new file +25 -0
@@ -0,0 +1,25 @@ +/** +* @file init.c +* +* @remark Copyright 2002 OProfile authors +* @remark Read the file COPYING +* +* @author John Levon <[email protected]> +*/ + +#include <linux/kernel.h> +#include <linux/oprofile.h> +#include <linux/init.h> +#include <linux/errno.h> + +extern void timer_init (struct oprofile_operations ** ops); + +int __init oprofile_arch_init (struct oprofile_operations ** ops) +{ +return -ENODEV ; +} + + +void oprofile_arch_exit (void ) +{ +}
arch/ia64/oprofile/Kconfig new file +23 -0
@@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu +
arch/ia64/oprofile/Makefile new file +9 -0
@@ -0,0 +1,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 \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) init.o
arch/ia64/Kconfig renamed from arch/ia64/Kconfig.orig +2 -0
@@ -589,6 +589,8 @@ source "arch/ia64/hp/sim/Kconfig" +source "arch/ia64/oprofile/Kconfig" + menu "Kernel hacking"
include/asm-ia64/hw_irq.h renamed from include/asm-ia64/hw_irq.h.orig +1 -0
@@ -9,6 +9,7 @@#include <linux/interrupt.h> #include <linux/sched.h> #include <linux/types.h> +#include <linux/profile.h> #include <asm/machvec.h> #include <asm/ptrace.h>
include/asm-ia64/ptrace.h renamed from include/asm-ia64/ptrace.h.orig +6 -0
@@ -223,6 +223,12 @@ };#ifdef __KERNEL__ +/* +* We use the ia64_psr(regs)->ri to determine which of the three +* instructions in bundle (16 bytes) took the sample. Generate +* the canonical representation by adding to instruction pointer. +*/ +#define instruction_pointer (regs) ((regs)->cr_iip + ia64_psr(regs)->ri)/* given a pointer to a task_struct, return the user's pt_regs */ # define ia64_task_regs (t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)# define ia64_psr (regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Will Cohen
Will> Revised the instruction_pointer to return the canonical ip and Will> ia64_do_profile() to adjust the resulting ip value for the Will> histogram.
Thanks, I applied the patch now, with the following minor changes:
- replaced open-coded prof_cpu_mask test with "cpu_isset()" (otherwise things don't compile with >64 CPUs)
- fixed some extra blank lines/whitespace issues
I'll push the updated tree a bit later today. Once you had a chance to test it, please let me know if I broke something.
Thanks,
--david