diff options
Diffstat (limited to 'arch/cris/kernel/profile.c')
| -rw-r--r-- | arch/cris/kernel/profile.c | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c index 69c52189f04..cd9f15b92f8 100644 --- a/arch/cris/kernel/profile.c +++ b/arch/cris/kernel/profile.c @@ -2,72 +2,85 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/proc_fs.h> +#include <linux/slab.h> #include <linux/types.h> #include <asm/ptrace.h> #include <asm/uaccess.h> #define SAMPLE_BUFFER_SIZE 8192 -static char* sample_buffer; -static char* sample_buffer_pos; +static char *sample_buffer; +static char *sample_buffer_pos; static int prof_running = 0; -void -cris_profile_sample(struct pt_regs* regs) +void cris_profile_sample(struct pt_regs *regs) { - if (!prof_running) - return; - if (user_mode(regs)) - *(unsigned int*)sample_buffer_pos = current->pid; - else - *(unsigned int*)sample_buffer_pos = 0; - *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); - sample_buffer_pos += 8; - if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) - sample_buffer_pos = sample_buffer; + if (!prof_running) + return; + + if (user_mode(regs)) + *(unsigned int*)sample_buffer_pos = current->pid; + else + *(unsigned int*)sample_buffer_pos = 0; + + *(unsigned int *)(sample_buffer_pos + 4) = instruction_pointer(regs); + sample_buffer_pos += 8; + + if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) + sample_buffer_pos = sample_buffer; } static ssize_t -read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) +read_cris_profile(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - unsigned long p = *ppos; - if (p > SAMPLE_BUFFER_SIZE) - return 0; - if (p + count > SAMPLE_BUFFER_SIZE) - count = SAMPLE_BUFFER_SIZE - p; - if (copy_to_user(buf, sample_buffer + p,count)) - return -EFAULT; - memset(sample_buffer + p, 0, count); - *ppos += count; - return count; + unsigned long p = *ppos; + ssize_t ret; + + ret = simple_read_from_buffer(buf, count, ppos, sample_buffer, + SAMPLE_BUFFER_SIZE); + if (ret < 0) + return ret; + + memset(sample_buffer + p, 0, ret); + + return ret; } static ssize_t write_cris_profile(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { - sample_buffer_pos = sample_buffer; - memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); + sample_buffer_pos = sample_buffer; + memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); + return count < SAMPLE_BUFFER_SIZE ? count : SAMPLE_BUFFER_SIZE; } -static struct file_operations cris_proc_profile_operations = { +static const struct file_operations cris_proc_profile_operations = { .read = read_cris_profile, .write = write_cris_profile, + .llseek = default_llseek, }; -static int -__init init_cris_profile(void) +static int __init init_cris_profile(void) { - struct proc_dir_entry *entry; - sample_buffer = (char*)kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); - sample_buffer_pos = sample_buffer; - entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); - if (entry) { - entry->proc_fops = &cris_proc_profile_operations; - entry->size = SAMPLE_BUFFER_SIZE; - } - prof_running = 1; - return 0; -} + struct proc_dir_entry *entry; + + sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); + if (!sample_buffer) { + return -ENOMEM; + } + + sample_buffer_pos = sample_buffer; + entry = proc_create("system_profile", S_IWUSR | S_IRUGO, NULL, + &cris_proc_profile_operations); + if (entry) { + proc_set_size(entry, SAMPLE_BUFFER_SIZE); + } + prof_running = 1; + + return 0; +} __initcall(init_cris_profile); + |
