cc4f5a1f8ef206e5b3255928bdaa7184b2d42619
[linux-2.6.git] / drivers / oprofile / oprofile_files.c
1 /**
2  * @file oprofile_files.c
3  *
4  * @remark Copyright 2002 OProfile authors
5  * @remark Read the file COPYING
6  *
7  * @author John Levon <levon@movementarian.org>
8  */
9
10 #include <linux/fs.h>
11 #include <linux/oprofile.h>
12 #include <linux/jiffies.h>
13
14 #include "event_buffer.h"
15 #include "oprofile_stats.h"
16 #include "oprof.h"
17  
18 unsigned long fs_buffer_size = 131072;
19 unsigned long fs_cpu_buffer_size = 8192;
20 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
21
22 static ssize_t timeout_read(struct file *file, char __user *buf,
23                 size_t count, loff_t *offset)
24 {
25         return oprofilefs_ulong_to_user(jiffies_to_msecs(timeout_jiffies),
26                                 buf, count, offset);
27 }
28
29
30 static ssize_t timeout_write(struct file *file, char const __user *buf,
31                 size_t count, loff_t *offset)
32 {
33         unsigned long val;
34         int retval;
35
36         if (*offset)
37                 return -EINVAL;
38
39         retval = oprofilefs_ulong_from_user(&val, buf, count);
40         if (retval)
41                 return retval;
42
43         retval = oprofile_set_timeout(val);
44
45         if (retval)
46                 return retval;
47         return count;
48 }
49
50 static const struct file_operations timeout_fops = {
51         .read           = timeout_read,
52         .write          = timeout_write,
53 };
54
55
56 static ssize_t depth_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
57 {
58         return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset);
59 }
60
61
62 static ssize_t depth_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
63 {
64         unsigned long val;
65         int retval;
66
67         if (*offset)
68                 return -EINVAL;
69
70         retval = oprofilefs_ulong_from_user(&val, buf, count);
71         if (retval)
72                 return retval;
73
74         retval = oprofile_set_backtrace(val);
75
76         if (retval)
77                 return retval;
78         return count;
79 }
80
81
82 static const struct file_operations depth_fops = {
83         .read           = depth_read,
84         .write          = depth_write
85 };
86
87  
88 static ssize_t pointer_size_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
89 {
90         return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset);
91 }
92
93
94 static const struct file_operations pointer_size_fops = {
95         .read           = pointer_size_read,
96 };
97
98
99 static ssize_t cpu_type_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
100 {
101         return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset);
102 }
103  
104  
105 static const struct file_operations cpu_type_fops = {
106         .read           = cpu_type_read,
107 };
108  
109  
110 static ssize_t enable_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
111 {
112         return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset);
113 }
114
115
116 static ssize_t enable_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
117 {
118         unsigned long val;
119         int retval;
120
121         if (*offset)
122                 return -EINVAL;
123         retval = oprofilefs_ulong_from_user(&val, buf, count);
124         if (retval)
125                 return retval;
126
127         if (val)
128                 retval = oprofile_start();
129         else
130                 oprofile_stop();
131
132         if (retval)
133                 return retval;
134         return count;
135 }
136
137  
138 static const struct file_operations enable_fops = {
139         .read           = enable_read,
140         .write          = enable_write,
141 };
142
143
144 static ssize_t dump_write(struct file * file, char const __user * buf, size_t count, loff_t * offset)
145 {
146         wake_up_buffer_waiter();
147         return count;
148 }
149
150
151 static const struct file_operations dump_fops = {
152         .write          = dump_write,
153 };
154  
155 void oprofile_create_files(struct super_block * sb, struct dentry * root)
156 {
157         oprofilefs_create_file(sb, root, "enable", &enable_fops);
158         oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
159         oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
160         oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
161         oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
162         oprofilefs_create_ulong(sb, root, "cpu_buffer_size", &fs_cpu_buffer_size);
163         oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops); 
164         oprofilefs_create_file(sb, root, "backtrace_depth", &depth_fops);
165         oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops);
166         oprofilefs_create_file(sb, root, "timeout_ms", &timeout_fops);
167         oprofile_create_stats_files(sb, root);
168         if (oprofile_ops.create_files)
169                 oprofile_ops.create_files(sb, root);
170 }