ia64/xen-unstable

view patches/linux-2.6.16.13/xenoprof-generic.patch @ 10099:3d3e5a3008f6

Check `global' property of the arch specific virqs.
Signed-off-by Kevin Tian <Kevin.tian@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu May 18 16:19:18 2006 +0100 (2006-05-18)
parents 3dca5b4add2b
children 23591d2c46aa
line source
1 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
2 --- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02 22:38:44.000000000 +0100
3 +++ ./drivers/oprofile/buffer_sync.c 2006-05-04 17:41:51.000000000 +0100
4 @@ -6,6 +6,10 @@
5 *
6 * @author John Levon <levon@movementarian.org>
7 *
8 + * Modified by Aravind Menon for Xen
9 + * These modifications are:
10 + * Copyright (C) 2005 Hewlett-Packard Co.
11 + *
12 * This is the core of the buffer management. Each
13 * CPU buffer is processed and entered into the
14 * global event buffer. Such processing is necessary
15 @@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
16 last_cookie = INVALID_COOKIE;
17 }
19 -static void add_kernel_ctx_switch(unsigned int in_kernel)
20 +static void add_cpu_mode_switch(unsigned int cpu_mode)
21 {
22 add_event_entry(ESCAPE_CODE);
23 - if (in_kernel)
24 - add_event_entry(KERNEL_ENTER_SWITCH_CODE);
25 - else
26 - add_event_entry(KERNEL_EXIT_SWITCH_CODE);
27 + switch (cpu_mode) {
28 + case CPU_MODE_USER:
29 + add_event_entry(USER_ENTER_SWITCH_CODE);
30 + break;
31 + case CPU_MODE_KERNEL:
32 + add_event_entry(KERNEL_ENTER_SWITCH_CODE);
33 + break;
34 + case CPU_MODE_XEN:
35 + add_event_entry(XEN_ENTER_SWITCH_CODE);
36 + break;
37 + default:
38 + break;
39 + }
40 }
41 -
42 +
43 static void
44 add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
45 {
46 @@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
47 * for later lookup from userspace.
48 */
49 static int
50 -add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
51 +add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
52 {
53 - if (in_kernel) {
54 + if (cpu_mode >= CPU_MODE_KERNEL) {
55 add_sample_entry(s->eip, s->event);
56 return 1;
57 } else if (mm) {
58 @@ -496,7 +509,7 @@ void sync_buffer(int cpu)
59 struct mm_struct *mm = NULL;
60 struct task_struct * new;
61 unsigned long cookie = 0;
62 - int in_kernel = 1;
63 + int cpu_mode = 1;
64 unsigned int i;
65 sync_buffer_state state = sb_buffer_start;
66 unsigned long available;
67 @@ -513,12 +526,12 @@ void sync_buffer(int cpu)
68 struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
70 if (is_code(s->eip)) {
71 - if (s->event <= CPU_IS_KERNEL) {
72 + if (s->event <= CPU_MODE_XEN) {
73 /* kernel/userspace switch */
74 - in_kernel = s->event;
75 + cpu_mode = s->event;
76 if (state == sb_buffer_start)
77 state = sb_sample_start;
78 - add_kernel_ctx_switch(s->event);
79 + add_cpu_mode_switch(s->event);
80 } else if (s->event == CPU_TRACE_BEGIN) {
81 state = sb_bt_start;
82 add_trace_begin();
83 @@ -536,7 +549,7 @@ void sync_buffer(int cpu)
84 }
85 } else {
86 if (state >= sb_bt_start &&
87 - !add_sample(mm, s, in_kernel)) {
88 + !add_sample(mm, s, cpu_mode)) {
89 if (state == sb_bt_start) {
90 state = sb_bt_ignore;
91 atomic_inc(&oprofile_stats.bt_lost_no_mapping);
92 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
93 --- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-02 22:38:44.000000000 +0100
94 +++ ./drivers/oprofile/cpu_buffer.c 2006-05-04 17:41:51.000000000 +0100
95 @@ -6,6 +6,10 @@
96 *
97 * @author John Levon <levon@movementarian.org>
98 *
99 + * Modified by Aravind Menon for Xen
100 + * These modifications are:
101 + * Copyright (C) 2005 Hewlett-Packard Co.
102 + *
103 * Each CPU has a local buffer that stores PC value/event
104 * pairs. We also log context switches when we notice them.
105 * Eventually each CPU's buffer is processed into the global
106 @@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
107 goto fail;
109 b->last_task = NULL;
110 - b->last_is_kernel = -1;
111 + b->last_cpu_mode = -1;
112 b->tracing = 0;
113 b->buffer_size = buffer_size;
114 b->tail_pos = 0;
115 @@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
116 * collected will populate the buffer with proper
117 * values to initialize the buffer
118 */
119 - cpu_buf->last_is_kernel = -1;
120 + cpu_buf->last_cpu_mode = -1;
121 cpu_buf->last_task = NULL;
122 }
124 @@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
125 * because of the head/tail separation of the writer and reader
126 * of the CPU buffer.
127 *
128 - * is_kernel is needed because on some architectures you cannot
129 + * cpu_mode is needed because on some architectures you cannot
130 * tell if you are in kernel or user space simply by looking at
131 - * pc. We tag this in the buffer by generating kernel enter/exit
132 - * events whenever is_kernel changes
133 + * pc. We tag this in the buffer by generating kernel/user (and xen)
134 + * enter events whenever cpu_mode changes
135 */
136 static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
137 - int is_kernel, unsigned long event)
138 + int cpu_mode, unsigned long event)
139 {
140 struct task_struct * task;
142 @@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
143 return 0;
144 }
146 - is_kernel = !!is_kernel;
147 + WARN_ON(cpu_mode > CPU_MODE_XEN);
149 task = current;
151 /* notice a switch from user->kernel or vice versa */
152 - if (cpu_buf->last_is_kernel != is_kernel) {
153 - cpu_buf->last_is_kernel = is_kernel;
154 - add_code(cpu_buf, is_kernel);
155 + if (cpu_buf->last_cpu_mode != cpu_mode) {
156 + cpu_buf->last_cpu_mode = cpu_mode;
157 + add_code(cpu_buf, cpu_mode);
158 }
159 -
160 +
161 /* notice a task switch */
162 if (cpu_buf->last_task != task) {
163 cpu_buf->last_task = task;
164 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
165 --- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-02 22:38:44.000000000 +0100
166 +++ ./drivers/oprofile/cpu_buffer.h 2006-05-04 17:41:51.000000000 +0100
167 @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
168 volatile unsigned long tail_pos;
169 unsigned long buffer_size;
170 struct task_struct * last_task;
171 - int last_is_kernel;
172 + int last_cpu_mode;
173 int tracing;
174 struct op_sample * buffer;
175 unsigned long sample_received;
176 @@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
177 void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
179 /* transient events for the CPU buffer -> event buffer */
180 -#define CPU_IS_KERNEL 1
181 -#define CPU_TRACE_BEGIN 2
182 +#define CPU_MODE_USER 0
183 +#define CPU_MODE_KERNEL 1
184 +#define CPU_MODE_XEN 2
185 +#define CPU_TRACE_BEGIN 3
187 #endif /* OPROFILE_CPU_BUFFER_H */
188 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
189 --- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 2006-05-02 22:38:44.000000000 +0100
190 +++ ./drivers/oprofile/event_buffer.h 2006-05-04 17:41:51.000000000 +0100
191 @@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
192 #define CPU_SWITCH_CODE 2
193 #define COOKIE_SWITCH_CODE 3
194 #define KERNEL_ENTER_SWITCH_CODE 4
195 -#define KERNEL_EXIT_SWITCH_CODE 5
196 +#define USER_ENTER_SWITCH_CODE 5
197 #define MODULE_LOADED_CODE 6
198 #define CTX_TGID_CODE 7
199 #define TRACE_BEGIN_CODE 8
200 #define TRACE_END_CODE 9
201 +#define XEN_ENTER_SWITCH_CODE 10
203 #define INVALID_COOKIE ~0UL
204 #define NO_COOKIE 0UL
205 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
206 --- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-02 22:38:44.000000000 +0100
207 +++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100
208 @@ -5,6 +5,10 @@
209 * @remark Read the file COPYING
210 *
211 * @author John Levon <levon@movementarian.org>
212 + *
213 + * Modified by Aravind Menon for Xen
214 + * These modifications are:
215 + * Copyright (C) 2005 Hewlett-Packard Co.
216 */
218 #include <linux/kernel.h>
219 @@ -19,7 +23,7 @@
220 #include "cpu_buffer.h"
221 #include "buffer_sync.h"
222 #include "oprofile_stats.h"
223 -
224 +
225 struct oprofile_operations oprofile_ops;
227 unsigned long oprofile_started;
228 @@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem);
229 */
230 static int timer = 0;
232 +int oprofile_set_active(int active_domains[], unsigned int adomains)
233 +{
234 + int err;
235 +
236 + if (!oprofile_ops.set_active)
237 + return -EINVAL;
238 +
239 + down(&start_sem);
240 + err = oprofile_ops.set_active(active_domains, adomains);
241 + up(&start_sem);
242 + return err;
243 +}
244 +
245 int oprofile_setup(void)
246 {
247 int err;
248 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
249 --- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-02 22:38:44.000000000 +0100
250 +++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100
251 @@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
252 void oprofile_timer_init(struct oprofile_operations * ops);
254 int oprofile_set_backtrace(unsigned long depth);
255 +
256 +int oprofile_set_active(int active_domains[], unsigned int adomains);
258 #endif /* OPROF_H */
259 diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
260 --- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 2006-05-02 22:38:44.000000000 +0100
261 +++ ./drivers/oprofile/oprofile_files.c 2006-05-04 17:41:51.000000000 +0100
262 @@ -5,15 +5,21 @@
263 * @remark Read the file COPYING
264 *
265 * @author John Levon <levon@movementarian.org>
266 + *
267 + * Modified by Aravind Menon for Xen
268 + * These modifications are:
269 + * Copyright (C) 2005 Hewlett-Packard Co.
270 */
272 #include <linux/fs.h>
273 #include <linux/oprofile.h>
274 +#include <asm/uaccess.h>
275 +#include <linux/ctype.h>
277 #include "event_buffer.h"
278 #include "oprofile_stats.h"
279 #include "oprof.h"
280 -
281 +
282 unsigned long fs_buffer_size = 131072;
283 unsigned long fs_cpu_buffer_size = 8192;
284 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
285 @@ -117,11 +123,108 @@ static ssize_t dump_write(struct file *
286 static struct file_operations dump_fops = {
287 .write = dump_write,
288 };
289 -
290 +
291 +#define TMPBUFSIZE 512
292 +
293 +static unsigned int adomains = 0;
294 +static int active_domains[MAX_OPROF_DOMAINS + 1];
295 +static DEFINE_MUTEX(adom_mutex);
296 +
297 +static ssize_t adomain_write(struct file * file, char const __user * buf,
298 + size_t count, loff_t * offset)
299 +{
300 + char *tmpbuf;
301 + char *startp, *endp;
302 + int i;
303 + unsigned long val;
304 + ssize_t retval = count;
305 +
306 + if (*offset)
307 + return -EINVAL;
308 + if (count > TMPBUFSIZE - 1)
309 + return -EINVAL;
310 +
311 + if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
312 + return -ENOMEM;
313 +
314 + if (copy_from_user(tmpbuf, buf, count)) {
315 + kfree(tmpbuf);
316 + return -EFAULT;
317 + }
318 + tmpbuf[count] = 0;
319 +
320 + mutex_lock(&adom_mutex);
321 +
322 + startp = tmpbuf;
323 + /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
324 + for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
325 + val = simple_strtoul(startp, &endp, 0);
326 + if (endp == startp)
327 + break;
328 + while (ispunct(*endp) || isspace(*endp))
329 + endp++;
330 + active_domains[i] = val;
331 + if (active_domains[i] != val)
332 + /* Overflow, force error below */
333 + i = MAX_OPROF_DOMAINS + 1;
334 + startp = endp;
335 + }
336 + /* Force error on trailing junk */
337 + adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
338 +
339 + kfree(tmpbuf);
340 +
341 + if (adomains > MAX_OPROF_DOMAINS
342 + || oprofile_set_active(active_domains, adomains)) {
343 + adomains = 0;
344 + retval = -EINVAL;
345 + }
346 +
347 + mutex_unlock(&adom_mutex);
348 + return retval;
349 +}
350 +
351 +static ssize_t adomain_read(struct file * file, char __user * buf,
352 + size_t count, loff_t * offset)
353 +{
354 + char * tmpbuf;
355 + size_t len;
356 + int i;
357 + ssize_t retval;
358 +
359 + if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
360 + return -ENOMEM;
361 +
362 + mutex_lock(&adom_mutex);
363 +
364 + len = 0;
365 + for (i = 0; i < adomains; i++)
366 + len += snprintf(tmpbuf + len,
367 + len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
368 + "%u ", active_domains[i]);
369 + WARN_ON(len > TMPBUFSIZE);
370 + if (len != 0 && len <= TMPBUFSIZE)
371 + tmpbuf[len-1] = '\n';
372 +
373 + mutex_unlock(&adom_mutex);
374 +
375 + retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
376 +
377 + kfree(tmpbuf);
378 + return retval;
379 +}
380 +
381 +
382 +static struct file_operations active_domain_ops = {
383 + .read = adomain_read,
384 + .write = adomain_write,
385 +};
386 +
387 void oprofile_create_files(struct super_block * sb, struct dentry * root)
388 {
389 oprofilefs_create_file(sb, root, "enable", &enable_fops);
390 oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
391 + oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
392 oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
393 oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
394 oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
395 diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h ./include/linux/oprofile.h
396 --- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-02 22:38:44.000000000 +0100
397 +++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100
398 @@ -16,6 +16,8 @@
399 #include <linux/types.h>
400 #include <linux/spinlock.h>
401 #include <asm/atomic.h>
402 +
403 +#include <xen/interface/xenoprof.h>
405 struct super_block;
406 struct dentry;
407 @@ -27,6 +29,8 @@ struct oprofile_operations {
408 /* create any necessary configuration files in the oprofile fs.
409 * Optional. */
410 int (*create_files)(struct super_block * sb, struct dentry * root);
411 + /* setup active domains with Xen */
412 + int (*set_active)(int *active_domains, unsigned int adomains);
413 /* Do any necessary interrupt setup. Optional. */
414 int (*setup)(void);
415 /* Do any necessary interrupt shutdown. Optional. */