2 * kernel/vserver/monitor.c
4 * Virtual Context Scheduler Monitor
6 * Copyright (C) 2006-2007 Herbert Pƶtzl
12 #include <linux/errno.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/ctype.h>
17 #include <asm/uaccess.h>
18 #include <asm/atomic.h>
19 #include <asm/unistd.h>
21 #include <linux/vserver/monitor.h>
22 #include <linux/vserver/debug_cmd.h>
25 #ifdef CONFIG_VSERVER_MONITOR
26 #define VXM_SIZE CONFIG_VSERVER_MONITOR_SIZE
34 struct _vx_mon_entry entry[VXM_SIZE+1];
38 DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer);
40 unsigned volatile int vxm_active = 1;
42 static atomic_t sequence = ATOMIC_INIT(0);
47 * requires disabled preemption */
49 struct _vx_mon_entry *vxm_advance(int cpu)
51 struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
52 struct _vx_mon_entry *entry;
55 index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE;
56 entry = &mon->entry[index];
58 entry->ev.seq = atomic_inc_return(&sequence);
59 entry->ev.jif = jiffies;
63 EXPORT_SYMBOL_GPL(vxm_advance);
66 int do_read_monitor(struct __user _vx_mon_entry *data,
67 int cpu, uint32_t *index, uint32_t *count)
70 struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
71 int end = mon->counter;
72 int start = end - VXM_SIZE + 2;
75 /* special case: get current pos */
81 /* have we lost some data? */
85 for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
86 struct _vx_mon_entry *entry =
87 &mon->entry[idx % VXM_SIZE];
89 /* send entry to userspace */
90 ret = copy_to_user (&data[pos], entry, sizeof(*entry));
94 /* save new index and count */
97 return ret ? ret : (*index < end);
100 int vc_read_monitor(uint32_t id, void __user *data)
102 struct vcmd_read_monitor_v0 vc_data;
108 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
111 ret = do_read_monitor((struct __user _vx_mon_entry *)vc_data.data,
112 id, &vc_data.index, &vc_data.count);
114 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
121 int vc_read_monitor_x32(uint32_t id, void __user *data)
123 struct vcmd_read_monitor_v0_x32 vc_data;
129 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
132 ret = do_read_monitor((struct __user _vx_mon_entry *)
133 compat_ptr(vc_data.data_ptr),
134 id, &vc_data.index, &vc_data.count);
136 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
141 #endif /* CONFIG_COMPAT */