aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/kernel')
-rw-r--r--arch/cris/kernel/profile.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
index 4cfcae620507..aad0a9e5991a 100644
--- a/arch/cris/kernel/profile.c
+++ b/arch/cris/kernel/profile.c
@@ -15,39 +15,47 @@ static int prof_running = 0;
15void 15void
16cris_profile_sample(struct pt_regs* regs) 16cris_profile_sample(struct pt_regs* regs)
17{ 17{
18 if (!prof_running) 18 if (!prof_running)
19 return; 19 return;
20 if (user_mode(regs)) 20
21 *(unsigned int*)sample_buffer_pos = current->pid; 21 if (user_mode(regs))
22 else 22 *(unsigned int*)sample_buffer_pos = current->pid;
23 *(unsigned int*)sample_buffer_pos = 0; 23 else
24 *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); 24 *(unsigned int*)sample_buffer_pos = 0;
25 sample_buffer_pos += 8; 25
26 if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) 26 *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
27 sample_buffer_pos = sample_buffer; 27 sample_buffer_pos += 8;
28
29 if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
30 sample_buffer_pos = sample_buffer;
28} 31}
29 32
30static ssize_t 33static ssize_t
31read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) 34read_cris_profile(struct file *file, char __user *buf,
35 size_t count, loff_t *ppos)
32{ 36{
33 unsigned long p = *ppos; 37 unsigned long p = *ppos;
34 if (p > SAMPLE_BUFFER_SIZE) 38
35 return 0; 39 if (p > SAMPLE_BUFFER_SIZE)
36 if (p + count > SAMPLE_BUFFER_SIZE) 40 return 0;
37 count = SAMPLE_BUFFER_SIZE - p; 41
38 if (copy_to_user(buf, sample_buffer + p,count)) 42 if (p + count > SAMPLE_BUFFER_SIZE)
43 count = SAMPLE_BUFFER_SIZE - p;
44 if (copy_to_user(buf, sample_buffer + p,count))
39 return -EFAULT; 45 return -EFAULT;
40 memset(sample_buffer + p, 0, count); 46
41 *ppos += count; 47 memset(sample_buffer + p, 0, count);
42 return count; 48 *ppos += count;
49
50 return count;
43} 51}
44 52
45static ssize_t 53static ssize_t
46write_cris_profile(struct file *file, const char __user *buf, 54write_cris_profile(struct file *file, const char __user *buf,
47 size_t count, loff_t *ppos) 55 size_t count, loff_t *ppos)
48{ 56{
49 sample_buffer_pos = sample_buffer; 57 sample_buffer_pos = sample_buffer;
50 memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); 58 memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
51} 59}
52 60
53static const struct file_operations cris_proc_profile_operations = { 61static const struct file_operations cris_proc_profile_operations = {
@@ -58,16 +66,23 @@ static const struct file_operations cris_proc_profile_operations = {
58static int 66static int
59__init init_cris_profile(void) 67__init init_cris_profile(void)
60{ 68{
61 struct proc_dir_entry *entry; 69 struct proc_dir_entry *entry;
62 sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); 70
63 sample_buffer_pos = sample_buffer; 71 sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
64 entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); 72 if (!sample_buffer) {
65 if (entry) { 73 return -ENOMEM;
66 entry->proc_fops = &cris_proc_profile_operations; 74 }
67 entry->size = SAMPLE_BUFFER_SIZE; 75
68 } 76 sample_buffer_pos = sample_buffer;
69 prof_running = 1; 77
70 return 0; 78 entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
79 if (entry) {
80 entry->proc_fops = &cris_proc_profile_operations;
81 entry->size = SAMPLE_BUFFER_SIZE;
82 }
83 prof_running = 1;
84
85 return 0;
71} 86}
72 87
73__initcall(init_cris_profile); 88__initcall(init_cris_profile);