Patch from John Levon The current enum for cpu model ID is painful to maintain. This converts the API to use a string instead. Userspace already has support for this. arch/i386/oprofile/init.c | 10 +++++----- arch/i386/oprofile/nmi_int.c | 24 ++++++++++++------------ arch/i386/oprofile/timer_int.c | 6 +++--- arch/parisc/oprofile/init.c | 6 +++--- arch/parisc/oprofile/timer_int.c | 6 +++--- arch/ppc64/oprofile/init.c | 6 +++--- arch/ppc64/oprofile/timer_int.c | 6 +++--- arch/sparc64/oprofile/init.c | 6 +++--- arch/sparc64/oprofile/timer_int.c | 6 +++--- drivers/oprofile/oprof.c | 9 +++++++-- drivers/oprofile/oprof.h | 1 - drivers/oprofile/oprofile_files.c | 4 +--- drivers/oprofile/oprofilefs.c | 23 +++++++++++++++++++++++ include/linux/oprofile.h | 30 ++++++++++-------------------- 14 files changed, 79 insertions(+), 64 deletions(-) diff -puN arch/i386/oprofile/init.c~oprofile_cpu-as-string arch/i386/oprofile/init.c --- 25/arch/i386/oprofile/init.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/i386/oprofile/init.c Fri Jan 17 13:40:24 2003 @@ -16,14 +16,14 @@ * code unlike the NMI-based code. */ -extern int nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern int nmi_init(struct oprofile_operations ** ops); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { #ifdef CONFIG_X86_LOCAL_APIC - if (!nmi_init(ops, cpu)) + if (!nmi_init(ops)) #endif - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -puN arch/i386/oprofile/nmi_int.c~oprofile_cpu-as-string arch/i386/oprofile/nmi_int.c --- 25/arch/i386/oprofile/nmi_int.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/i386/oprofile/nmi_int.c Fri Jan 17 13:40:24 2003 @@ -217,7 +217,7 @@ struct oprofile_operations nmi_ops = { #if !defined(CONFIG_X86_64) -static int __init p4_init(enum oprofile_cpu * cpu) +static int __init p4_init(void) { __u8 cpu_model = current_cpu_data.x86_model; @@ -225,17 +225,17 @@ static int __init p4_init(enum oprofile_ return 0; #ifndef CONFIG_SMP - *cpu = OPROFILE_CPU_P4; + nmi_ops.cpu_type = "i386/p4"; model = &op_p4_spec; #else switch (smp_num_siblings) { case 1: - *cpu = OPROFILE_CPU_P4; + nmi_ops.cpu_type = "i386/p4"; model = &op_p4_spec; return 1; case 2: - *cpu = OPROFILE_CPU_P4_HT2; + nmi_ops.cpu_type = "i386/p4-ht"; model = &op_p4_ht2_spec; return 1; } @@ -247,16 +247,16 @@ static int __init p4_init(enum oprofile_ } -static int __init ppro_init(enum oprofile_cpu * cpu) +static int __init ppro_init(void) { __u8 cpu_model = current_cpu_data.x86_model; if (cpu_model > 5) { - *cpu = OPROFILE_CPU_PIII; + nmi_ops.cpu_type = "i386/piii"; } else if (cpu_model > 2) { - *cpu = OPROFILE_CPU_PII; + nmi_ops.cpu_type = "i386/pii"; } else { - *cpu = OPROFILE_CPU_PPRO; + nmi_ops.cpu_type = "i386/ppro"; } model = &op_ppro_spec; @@ -265,7 +265,7 @@ static int __init ppro_init(enum oprofil #endif /* !CONFIG_X86_64 */ -int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init nmi_init(struct oprofile_operations ** ops) { __u8 vendor = current_cpu_data.x86_vendor; __u8 family = current_cpu_data.x86; @@ -279,7 +279,7 @@ int __init nmi_init(struct oprofile_oper if (family < 6) return 0; model = &op_athlon_spec; - *cpu = OPROFILE_CPU_ATHLON; + nmi_ops.cpu_type = "i386/athlon"; break; #if !defined(CONFIG_X86_64) @@ -287,13 +287,13 @@ int __init nmi_init(struct oprofile_oper switch (family) { /* Pentium IV */ case 0xf: - if (!p4_init(cpu)) + if (!p4_init()) return 0; break; /* A P6-class processor */ case 6: - if (!ppro_init(cpu)) + if (!ppro_init()) return 0; break; diff -puN arch/i386/oprofile/timer_int.c~oprofile_cpu-as-string arch/i386/oprofile/timer_int.c --- 25/arch/i386/oprofile/timer_int.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/i386/oprofile/timer_int.c Fri Jan 17 13:40:24 2003 @@ -45,13 +45,13 @@ static void timer_stop(void) static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -puN arch/parisc/oprofile/init.c~oprofile_cpu-as-string arch/parisc/oprofile/init.c --- 25/arch/parisc/oprofile/init.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/parisc/oprofile/init.c Fri Jan 17 13:40:24 2003 @@ -11,10 +11,10 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -puN arch/parisc/oprofile/timer_int.c~oprofile_cpu-as-string arch/parisc/oprofile/timer_int.c --- 25/arch/parisc/oprofile/timer_int.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/parisc/oprofile/timer_int.c Fri Jan 17 13:40:24 2003 @@ -44,13 +44,13 @@ static void timer_stop(void) static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -puN arch/ppc64/oprofile/init.c~oprofile_cpu-as-string arch/ppc64/oprofile/init.c --- 25/arch/ppc64/oprofile/init.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/ppc64/oprofile/init.c Fri Jan 17 13:40:24 2003 @@ -11,10 +11,10 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -puN arch/ppc64/oprofile/timer_int.c~oprofile_cpu-as-string arch/ppc64/oprofile/timer_int.c --- 25/arch/ppc64/oprofile/timer_int.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/ppc64/oprofile/timer_int.c Fri Jan 17 13:40:24 2003 @@ -44,13 +44,13 @@ static void timer_stop(void) static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -puN arch/sparc64/oprofile/init.c~oprofile_cpu-as-string arch/sparc64/oprofile/init.c --- 25/arch/sparc64/oprofile/init.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/sparc64/oprofile/init.c Fri Jan 17 13:40:24 2003 @@ -11,10 +11,10 @@ #include #include -extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +extern void timer_init(struct oprofile_operations ** ops); -int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +int __init oprofile_arch_init(struct oprofile_operations ** ops) { - timer_init(ops, cpu); + timer_init(ops); return 0; } diff -puN arch/sparc64/oprofile/timer_int.c~oprofile_cpu-as-string arch/sparc64/oprofile/timer_int.c --- 25/arch/sparc64/oprofile/timer_int.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/arch/sparc64/oprofile/timer_int.c Fri Jan 17 13:40:24 2003 @@ -44,13 +44,13 @@ static void timer_stop(void) static struct oprofile_operations timer_ops = { .start = timer_start, - .stop = timer_stop + .stop = timer_stop, + .cpu_type = "timer" }; -void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) +void __init timer_init(struct oprofile_operations ** ops) { *ops = &timer_ops; - *cpu = OPROFILE_CPU_TIMER; printk(KERN_INFO "oprofile: using timer interrupt.\n"); } diff -puN drivers/oprofile/oprof.c~oprofile_cpu-as-string drivers/oprofile/oprof.c --- 25/drivers/oprofile/oprof.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/drivers/oprofile/oprof.c Fri Jan 17 13:40:24 2003 @@ -20,7 +20,6 @@ #include "oprofile_stats.h" struct oprofile_operations * oprofile_ops; -enum oprofile_cpu oprofile_cpu_type; unsigned long oprofile_started; static unsigned long is_setup; static DECLARE_MUTEX(start_sem); @@ -127,10 +126,16 @@ static int __init oprofile_init(void) /* Architecture must fill in the interrupt ops and the * logical CPU type. */ - err = oprofile_arch_init(&oprofile_ops, &oprofile_cpu_type); + err = oprofile_arch_init(&oprofile_ops); if (err) goto out; + if (!oprofile_ops->cpu_type) { + printk(KERN_ERR "oprofile: cpu_type not set !\n"); + err = -EFAULT; + goto out; + } + err = oprofilefs_register(); if (err) goto out; diff -puN drivers/oprofile/oprof.h~oprofile_cpu-as-string drivers/oprofile/oprof.h --- 25/drivers/oprofile/oprof.h~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/drivers/oprofile/oprof.h Fri Jan 17 13:40:24 2003 @@ -24,7 +24,6 @@ struct oprofile_operations; extern unsigned long fs_buffer_size; extern unsigned long fs_cpu_buffer_size; extern unsigned long fs_buffer_watershed; -extern enum oprofile_cpu oprofile_cpu_type; extern struct oprofile_operations * oprofile_ops; extern unsigned long oprofile_started; diff -puN drivers/oprofile/oprofile_files.c~oprofile_cpu-as-string drivers/oprofile/oprofile_files.c --- 25/drivers/oprofile/oprofile_files.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/drivers/oprofile/oprofile_files.c Fri Jan 17 13:40:24 2003 @@ -21,9 +21,7 @@ unsigned long fs_buffer_watershed = 3276 static ssize_t cpu_type_read(struct file * file, char * buf, size_t count, loff_t * offset) { - unsigned long cpu_type = oprofile_cpu_type; - - return oprofilefs_ulong_to_user(&cpu_type, buf, count, offset); + return oprofilefs_str_to_user(oprofile_ops->cpu_type, buf, count, offset); } diff -puN drivers/oprofile/oprofilefs.c~oprofile_cpu-as-string drivers/oprofile/oprofilefs.c --- 25/drivers/oprofile/oprofilefs.c~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/drivers/oprofile/oprofilefs.c Fri Jan 17 13:40:24 2003 @@ -44,6 +44,29 @@ static struct super_operations s_ops = { .drop_inode = generic_delete_inode, }; + +ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset) +{ + size_t len = strlen(str); + + if (!count) + return 0; + + if (*offset > len) + return 0; + + if (count > len - *offset) + count = len - *offset; + + if (copy_to_user(buf, str + *offset, count)) + return -EFAULT; + + *offset += count; + + return count; +} + + #define TMPBUFSIZE 50 ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count, loff_t * offset) diff -puN include/linux/oprofile.h~oprofile_cpu-as-string include/linux/oprofile.h --- 25/include/linux/oprofile.h~oprofile_cpu-as-string Fri Jan 17 13:40:24 2003 +++ 25-akpm/include/linux/oprofile.h Fri Jan 17 13:40:24 2003 @@ -21,24 +21,6 @@ struct super_block; struct dentry; struct file_operations; -/* This is duplicated from user-space so - * must be kept in sync :( - */ -enum oprofile_cpu { - OPROFILE_CPU_PPRO, - OPROFILE_CPU_PII, - OPROFILE_CPU_PIII, - OPROFILE_CPU_ATHLON, - OPROFILE_CPU_TIMER, - OPROFILE_UNUSED1, /* 2.4's RTC mode */ - OPROFILE_CPU_P4, - OPROFILE_CPU_IA64, - OPROFILE_CPU_IA64_1, - OPROFILE_CPU_IA64_2, - OPROFILE_CPU_HAMMER, - OPROFILE_CPU_P4_HT2 -}; - /* Operations structure to be filled in */ struct oprofile_operations { /* create any necessary configuration files in the oprofile fs. @@ -52,14 +34,16 @@ struct oprofile_operations { int (*start)(void); /* Stop delivering interrupts. */ void (*stop)(void); + /* CPU identification string. */ + char * cpu_type; }; /** * One-time initialisation. *ops must be set to a filled-in - * operations structure. oprofile_cpu_type must be set. + * operations structure. * Return 0 on success. */ -int oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu); +int oprofile_arch_init(struct oprofile_operations ** ops); /** * Add a sample. This may be called from any context. Pass @@ -91,6 +75,12 @@ struct dentry * oprofilefs_mkdir(struct char const * name); /** + * Write the given asciz string to the given user buffer @buf, updating *offset + * appropriately. Returns bytes written or -EFAULT. + */ +ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset); + +/** * Convert an unsigned long value into ASCII and copy it to the user buffer @buf, * updating *offset appropriately. Returns bytes written or -EFAULT. */ _