Commit 3dbea173 authored by John Levon's avatar John Levon Committed by Linus Torvalds

[PATCH] oprofile: CPU type as string

This patch updates the horrible enum for the logical CPU type with a
string instead.
parent dcd8f32e
...@@ -16,14 +16,14 @@ ...@@ -16,14 +16,14 @@
* code unlike the NMI-based code. * code unlike the NMI-based code.
*/ */
extern int nmi_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, 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)
{ {
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
if (!nmi_init(ops, cpu)) if (!nmi_init(ops))
#endif #endif
timer_init(ops, cpu); timer_init(ops);
return 0; return 0;
} }
...@@ -217,7 +217,7 @@ struct oprofile_operations nmi_ops = { ...@@ -217,7 +217,7 @@ struct oprofile_operations nmi_ops = {
#if !defined(CONFIG_X86_64) #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; __u8 cpu_model = current_cpu_data.x86_model;
...@@ -225,18 +225,18 @@ static int __init p4_init(enum oprofile_cpu * cpu) ...@@ -225,18 +225,18 @@ static int __init p4_init(enum oprofile_cpu * cpu)
return 0; return 0;
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
*cpu = OPROFILE_CPU_P4; nmi_ops.cpu_type = "i386/p4";
model = &op_p4_spec; model = &op_p4_spec;
return 1; return 1;
#else #else
switch (smp_num_siblings) { switch (smp_num_siblings) {
case 1: case 1:
*cpu = OPROFILE_CPU_P4; nmi_ops.cpu_type = "i386/p4";
model = &op_p4_spec; model = &op_p4_spec;
return 1; return 1;
case 2: case 2:
*cpu = OPROFILE_CPU_P4_HT2; nmi_ops.cpu_type = "i386/p4-ht";
model = &op_p4_ht2_spec; model = &op_p4_ht2_spec;
return 1; return 1;
} }
...@@ -248,16 +248,16 @@ static int __init p4_init(enum oprofile_cpu * cpu) ...@@ -248,16 +248,16 @@ static int __init p4_init(enum oprofile_cpu * cpu)
} }
static int __init ppro_init(enum oprofile_cpu * cpu) static int __init ppro_init(void)
{ {
__u8 cpu_model = current_cpu_data.x86_model; __u8 cpu_model = current_cpu_data.x86_model;
if (cpu_model > 5) { if (cpu_model > 5) {
*cpu = OPROFILE_CPU_PIII; nmi_ops.cpu_type = "i386/piii";
} else if (cpu_model > 2) { } else if (cpu_model > 2) {
*cpu = OPROFILE_CPU_PII; nmi_ops.cpu_type = "i386/pii";
} else { } else {
*cpu = OPROFILE_CPU_PPRO; nmi_ops.cpu_type = "i386/ppro";
} }
model = &op_ppro_spec; model = &op_ppro_spec;
...@@ -266,7 +266,7 @@ static int __init ppro_init(enum oprofile_cpu * cpu) ...@@ -266,7 +266,7 @@ static int __init ppro_init(enum oprofile_cpu * cpu)
#endif /* !CONFIG_X86_64 */ #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 vendor = current_cpu_data.x86_vendor;
__u8 family = current_cpu_data.x86; __u8 family = current_cpu_data.x86;
...@@ -280,7 +280,7 @@ int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) ...@@ -280,7 +280,7 @@ int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
if (family < 6) if (family < 6)
return 0; return 0;
model = &op_athlon_spec; model = &op_athlon_spec;
*cpu = OPROFILE_CPU_ATHLON; nmi_ops.cpu_type = "i386/athlon";
break; break;
#if !defined(CONFIG_X86_64) #if !defined(CONFIG_X86_64)
...@@ -288,13 +288,13 @@ int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu) ...@@ -288,13 +288,13 @@ int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
switch (family) { switch (family) {
/* Pentium IV */ /* Pentium IV */
case 0xf: case 0xf:
if (!p4_init(cpu)) if (!p4_init())
return 0; return 0;
break; break;
/* A P6-class processor */ /* A P6-class processor */
case 6: case 6:
if (!ppro_init(cpu)) if (!ppro_init())
return 0; return 0;
break; break;
......
...@@ -45,13 +45,13 @@ static void timer_stop(void) ...@@ -45,13 +45,13 @@ static void timer_stop(void)
static struct oprofile_operations timer_ops = { static struct oprofile_operations timer_ops = {
.start = timer_start, .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; *ops = &timer_ops;
*cpu = OPROFILE_CPU_TIMER;
printk(KERN_INFO "oprofile: using timer interrupt.\n"); printk(KERN_INFO "oprofile: using timer interrupt.\n");
} }
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h> #include <linux/init.h>
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; return 0;
} }
...@@ -44,13 +44,13 @@ static void timer_stop(void) ...@@ -44,13 +44,13 @@ static void timer_stop(void)
static struct oprofile_operations timer_ops = { static struct oprofile_operations timer_ops = {
.start = timer_start, .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; *ops = &timer_ops;
*cpu = OPROFILE_CPU_TIMER;
printk(KERN_INFO "oprofile: using timer interrupt.\n"); printk(KERN_INFO "oprofile: using timer interrupt.\n");
} }
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h> #include <linux/init.h>
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; return 0;
} }
...@@ -44,13 +44,13 @@ static void timer_stop(void) ...@@ -44,13 +44,13 @@ static void timer_stop(void)
static struct oprofile_operations timer_ops = { static struct oprofile_operations timer_ops = {
.start = timer_start, .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; *ops = &timer_ops;
*cpu = OPROFILE_CPU_TIMER;
printk(KERN_INFO "oprofile: using timer interrupt.\n"); printk(KERN_INFO "oprofile: using timer interrupt.\n");
} }
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
#include <linux/oprofile.h> #include <linux/oprofile.h>
#include <linux/init.h> #include <linux/init.h>
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; return 0;
} }
...@@ -44,13 +44,13 @@ static void timer_stop(void) ...@@ -44,13 +44,13 @@ static void timer_stop(void)
static struct oprofile_operations timer_ops = { static struct oprofile_operations timer_ops = {
.start = timer_start, .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; *ops = &timer_ops;
*cpu = OPROFILE_CPU_TIMER;
printk(KERN_INFO "oprofile: using timer interrupt.\n"); printk(KERN_INFO "oprofile: using timer interrupt.\n");
} }
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "oprofile_stats.h" #include "oprofile_stats.h"
struct oprofile_operations * oprofile_ops; struct oprofile_operations * oprofile_ops;
enum oprofile_cpu oprofile_cpu_type;
unsigned long oprofile_started; unsigned long oprofile_started;
static unsigned long is_setup; static unsigned long is_setup;
static DECLARE_MUTEX(start_sem); static DECLARE_MUTEX(start_sem);
...@@ -127,10 +126,16 @@ static int __init oprofile_init(void) ...@@ -127,10 +126,16 @@ static int __init oprofile_init(void)
/* Architecture must fill in the interrupt ops and the /* Architecture must fill in the interrupt ops and the
* logical CPU type. * logical CPU type.
*/ */
err = oprofile_arch_init(&oprofile_ops, &oprofile_cpu_type); err = oprofile_arch_init(&oprofile_ops);
if (err) if (err)
goto out; goto out;
if (!oprofile_ops->cpu_type) {
printk(KERN_ERR "oprofile: cpu_type not set !\n");
err = -EFAULT;
goto out;
}
err = oprofilefs_register(); err = oprofilefs_register();
if (err) if (err)
goto out; goto out;
......
...@@ -24,7 +24,6 @@ struct oprofile_operations; ...@@ -24,7 +24,6 @@ struct oprofile_operations;
extern unsigned long fs_buffer_size; extern unsigned long fs_buffer_size;
extern unsigned long fs_cpu_buffer_size; extern unsigned long fs_cpu_buffer_size;
extern unsigned long fs_buffer_watershed; extern unsigned long fs_buffer_watershed;
extern enum oprofile_cpu oprofile_cpu_type;
extern struct oprofile_operations * oprofile_ops; extern struct oprofile_operations * oprofile_ops;
extern unsigned long oprofile_started; extern unsigned long oprofile_started;
......
...@@ -21,9 +21,7 @@ unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ ...@@ -21,9 +21,7 @@ unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
static ssize_t cpu_type_read(struct file * file, char * buf, size_t count, loff_t * offset) 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_str_to_user(oprofile_ops->cpu_type, buf, count, offset);
return oprofilefs_ulong_to_user(&cpu_type, buf, count, offset);
} }
......
...@@ -44,6 +44,29 @@ static struct super_operations s_ops = { ...@@ -44,6 +44,29 @@ static struct super_operations s_ops = {
.drop_inode = generic_delete_inode, .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 #define TMPBUFSIZE 50
ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count, loff_t * offset) ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count, loff_t * offset)
......
...@@ -21,24 +21,6 @@ struct super_block; ...@@ -21,24 +21,6 @@ struct super_block;
struct dentry; struct dentry;
struct file_operations; 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 */ /* Operations structure to be filled in */
struct oprofile_operations { struct oprofile_operations {
/* create any necessary configuration files in the oprofile fs. /* create any necessary configuration files in the oprofile fs.
...@@ -52,14 +34,16 @@ struct oprofile_operations { ...@@ -52,14 +34,16 @@ struct oprofile_operations {
int (*start)(void); int (*start)(void);
/* Stop delivering interrupts. */ /* Stop delivering interrupts. */
void (*stop)(void); void (*stop)(void);
/* CPU identification string. */
char * cpu_type;
}; };
/** /**
* One-time initialisation. *ops must be set to a filled-in * 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. * 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 * Add a sample. This may be called from any context. Pass
...@@ -90,6 +74,12 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, ...@@ -90,6 +74,12 @@ int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root,
struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root,
char const * name); 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, * Convert an unsigned long value into ASCII and copy it to the user buffer @buf,
* updating *offset appropriately. Returns bytes written or -EFAULT. * updating *offset appropriately. Returns bytes written or -EFAULT.
......
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