Branch data Line data Source code
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 : : #define BUFFER_SIZE_DEFAULT 131072
19 : : #define CPU_BUFFER_SIZE_DEFAULT 8192
20 : : #define BUFFER_WATERSHED_DEFAULT 32768 /* FIXME: tune */
21 : : #define TIME_SLICE_DEFAULT 1
22 : :
23 : : unsigned long oprofile_buffer_size;
24 : : unsigned long oprofile_cpu_buffer_size;
25 : : unsigned long oprofile_buffer_watershed;
26 : : unsigned long oprofile_time_slice;
27 : :
28 : : #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
29 : :
30 : : static ssize_t timeout_read(struct file *file, char __user *buf,
31 : : size_t count, loff_t *offset)
32 : : {
33 : : return oprofilefs_ulong_to_user(jiffies_to_msecs(oprofile_time_slice),
34 : : buf, count, offset);
35 : : }
36 : :
37 : :
38 : : static ssize_t timeout_write(struct file *file, char const __user *buf,
39 : : size_t count, loff_t *offset)
40 : : {
41 : : unsigned long val;
42 : : int retval;
43 : :
44 : : if (*offset)
45 : : return -EINVAL;
46 : :
47 : : retval = oprofilefs_ulong_from_user(&val, buf, count);
48 : : if (retval <= 0)
49 : : return retval;
50 : :
51 : : retval = oprofile_set_timeout(val);
52 : :
53 : : if (retval)
54 : : return retval;
55 : : return count;
56 : : }
57 : :
58 : :
59 : : static const struct file_operations timeout_fops = {
60 : : .read = timeout_read,
61 : : .write = timeout_write,
62 : : .llseek = default_llseek,
63 : : };
64 : :
65 : : #endif
66 : :
67 : :
68 : 0 : static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
69 : : {
70 : 0 : return oprofilefs_ulong_to_user(oprofile_backtrace_depth, buf, count,
71 : : offset);
72 : : }
73 : :
74 : :
75 : 0 : static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
76 : : {
77 : : unsigned long val;
78 : : int retval;
79 : :
80 [ # # ]: 0 : if (*offset)
81 : : return -EINVAL;
82 : :
83 [ # # ]: 0 : if (!oprofile_ops.backtrace)
84 : : return -EINVAL;
85 : :
86 : 0 : retval = oprofilefs_ulong_from_user(&val, buf, count);
87 [ # # ]: 0 : if (retval <= 0)
88 : : return retval;
89 : :
90 : 0 : retval = oprofile_set_ulong(&oprofile_backtrace_depth, val);
91 [ # # ]: 0 : if (retval)
92 : : return retval;
93 : :
94 : 0 : return count;
95 : : }
96 : :
97 : :
98 : : static const struct file_operations depth_fops = {
99 : : .read = depth_read,
100 : : .write = depth_write,
101 : : .llseek = default_llseek,
102 : : };
103 : :
104 : :
105 : 0 : static ssize_t pointer_size_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
106 : : {
107 : 0 : return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset);
108 : : }
109 : :
110 : :
111 : : static const struct file_operations pointer_size_fops = {
112 : : .read = pointer_size_read,
113 : : .llseek = default_llseek,
114 : : };
115 : :
116 : :
117 : 0 : static ssize_t cpu_type_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
118 : : {
119 : 0 : return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset);
120 : : }
121 : :
122 : :
123 : : static const struct file_operations cpu_type_fops = {
124 : : .read = cpu_type_read,
125 : : .llseek = default_llseek,
126 : : };
127 : :
128 : :
129 : 0 : static ssize_t enable_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
130 : : {
131 : 0 : return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset);
132 : : }
133 : :
134 : :
135 : 0 : static ssize_t enable_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
136 : : {
137 : : unsigned long val;
138 : : int retval;
139 : :
140 [ # # ]: 0 : if (*offset)
141 : : return -EINVAL;
142 : :
143 : 0 : retval = oprofilefs_ulong_from_user(&val, buf, count);
144 [ # # ]: 0 : if (retval <= 0)
145 : : return retval;
146 : :
147 : : retval = 0;
148 [ # # ]: 0 : if (val)
149 : 0 : retval = oprofile_start();
150 : : else
151 : 0 : oprofile_stop();
152 : :
153 [ # # ]: 0 : if (retval)
154 : : return retval;
155 : 0 : return count;
156 : : }
157 : :
158 : :
159 : : static const struct file_operations enable_fops = {
160 : : .read = enable_read,
161 : : .write = enable_write,
162 : : .llseek = default_llseek,
163 : : };
164 : :
165 : :
166 : 0 : static ssize_t dump_write(struct file *file, char const __user *buf, size_t count, loff_t *offset)
167 : : {
168 : 0 : wake_up_buffer_waiter();
169 : 0 : return count;
170 : : }
171 : :
172 : :
173 : : static const struct file_operations dump_fops = {
174 : : .write = dump_write,
175 : : .llseek = noop_llseek,
176 : : };
177 : :
178 : 0 : void oprofile_create_files(struct dentry *root)
179 : : {
180 : : /* reinitialize default values */
181 : 0 : oprofile_buffer_size = BUFFER_SIZE_DEFAULT;
182 : 0 : oprofile_cpu_buffer_size = CPU_BUFFER_SIZE_DEFAULT;
183 : 0 : oprofile_buffer_watershed = BUFFER_WATERSHED_DEFAULT;
184 : 0 : oprofile_time_slice = msecs_to_jiffies(TIME_SLICE_DEFAULT);
185 : :
186 : 0 : oprofilefs_create_file(root, "enable", &enable_fops);
187 : 0 : oprofilefs_create_file_perm(root, "dump", &dump_fops, 0666);
188 : 0 : oprofilefs_create_file(root, "buffer", &event_buffer_fops);
189 : 0 : oprofilefs_create_ulong(root, "buffer_size", &oprofile_buffer_size);
190 : 0 : oprofilefs_create_ulong(root, "buffer_watershed", &oprofile_buffer_watershed);
191 : 0 : oprofilefs_create_ulong(root, "cpu_buffer_size", &oprofile_cpu_buffer_size);
192 : 0 : oprofilefs_create_file(root, "cpu_type", &cpu_type_fops);
193 : 0 : oprofilefs_create_file(root, "backtrace_depth", &depth_fops);
194 : 0 : oprofilefs_create_file(root, "pointer_size", &pointer_size_fops);
195 : : #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
196 : : oprofilefs_create_file(root, "time_slice", &timeout_fops);
197 : : #endif
198 : 0 : oprofile_create_stats_files(root);
199 [ # # ]: 0 : if (oprofile_ops.create_files)
200 : 0 : oprofile_ops.create_files(root);
201 : 0 : }
|