ia64/xen-unstable

view xen/common/perfc.c @ 19835:edfdeb150f27

Fix buildsystem to detect udev > version 124

udev removed the udevinfo symlink from versions higher than 123 and
xen's build-system could not detect if udev is in place and has the
required version.

Signed-off-by: Marc-A. Dahlhaus <mad@wol.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 25 13:02:37 2009 +0100 (2009-06-25)
parents 45a44a9cbe8d
children
line source
2 #include <xen/lib.h>
3 #include <xen/smp.h>
4 #include <xen/time.h>
5 #include <xen/perfc.h>
6 #include <xen/keyhandler.h>
7 #include <xen/spinlock.h>
8 #include <xen/mm.h>
9 #include <xen/guest_access.h>
10 #include <public/sysctl.h>
11 #include <asm/perfc.h>
13 #define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
14 #define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
15 #define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
16 #define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
17 static const struct {
18 const char *name;
19 enum { TYPE_SINGLE, TYPE_ARRAY,
20 TYPE_S_SINGLE, TYPE_S_ARRAY
21 } type;
22 unsigned int nr_elements;
23 } perfc_info[] = {
24 #include <xen/perfc_defn.h>
25 };
27 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
29 DEFINE_PER_CPU(perfc_t[NUM_PERFCOUNTERS], perfcounters);
31 void perfc_printall(unsigned char key)
32 {
33 unsigned int i, j;
34 s_time_t now = NOW();
36 printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
37 (u32)(now>>32), (u32)now);
39 for ( i = j = 0; i < NR_PERFCTRS; i++ )
40 {
41 unsigned int k, cpu;
42 unsigned long long sum = 0;
44 printk("%-32s ", perfc_info[i].name);
45 switch ( perfc_info[i].type )
46 {
47 case TYPE_SINGLE:
48 case TYPE_S_SINGLE:
49 for_each_online_cpu ( cpu )
50 sum += per_cpu(perfcounters, cpu)[j];
51 if ( perfc_info[i].type == TYPE_S_SINGLE )
52 sum = (perfc_t) sum;
53 printk("TOTAL[%12Lu]", sum);
54 if ( sum )
55 {
56 k = 0;
57 for_each_online_cpu ( cpu )
58 {
59 if ( k > 0 && (k % 4) == 0 )
60 printk("\n%46s", "");
61 printk(" CPU%02u[%10"PRIperfc"u]", cpu, per_cpu(perfcounters, cpu)[j]);
62 ++k;
63 }
64 }
65 ++j;
66 break;
67 case TYPE_ARRAY:
68 case TYPE_S_ARRAY:
69 for_each_online_cpu ( cpu )
70 {
71 perfc_t *counters = per_cpu(perfcounters, cpu) + j;
73 for ( k = 0; k < perfc_info[i].nr_elements; k++ )
74 sum += counters[k];
75 }
76 if ( perfc_info[i].type == TYPE_S_ARRAY )
77 sum = (perfc_t) sum;
78 printk("TOTAL[%12Lu]", sum);
79 if (sum)
80 {
81 #ifdef PERF_ARRAYS
82 for ( k = 0; k < perfc_info[i].nr_elements; k++ )
83 {
84 sum = 0;
85 for_each_online_cpu ( cpu )
86 sum += per_cpu(perfcounters, cpu)[j + k];
87 if ( perfc_info[i].type == TYPE_S_ARRAY )
88 sum = (perfc_t) sum;
89 if ( (k % 4) == 0 )
90 printk("\n%16s", "");
91 printk(" ARR%02u[%10Lu]", k, sum);
92 }
93 #else
94 k = 0;
95 for_each_online_cpu ( cpu )
96 {
97 perfc_t *counters = per_cpu(perfcounters, cpu) + j;
98 unsigned int n;
100 sum = 0;
101 for ( n = 0; n < perfc_info[i].nr_elements; n++ )
102 sum += counters[n];
103 if ( perfc_info[i].type == TYPE_S_ARRAY )
104 sum = (perfc_t) sum;
105 if ( k > 0 && (k % 4) == 0 )
106 printk("\n%46s", "");
107 printk(" CPU%02u[%10Lu]", cpu, sum);
108 ++k;
109 }
110 #endif
111 }
112 j += perfc_info[i].nr_elements;
113 break;
114 }
115 printk("\n");
116 }
118 arch_perfc_printall();
119 }
121 void perfc_reset(unsigned char key)
122 {
123 unsigned int i, j;
124 s_time_t now = NOW();
126 if ( key != '\0' )
127 printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
128 (u32)(now>>32), (u32)now);
130 /* leave STATUS counters alone -- don't reset */
132 for ( i = j = 0; i < NR_PERFCTRS; i++ )
133 {
134 unsigned int cpu;
136 switch ( perfc_info[i].type )
137 {
138 case TYPE_SINGLE:
139 for_each_cpu ( cpu )
140 per_cpu(perfcounters, cpu)[j] = 0;
141 case TYPE_S_SINGLE:
142 ++j;
143 break;
144 case TYPE_ARRAY:
145 for_each_cpu ( cpu )
146 memset(per_cpu(perfcounters, cpu) + j, 0,
147 perfc_info[i].nr_elements * sizeof(perfc_t));
148 case TYPE_S_ARRAY:
149 j += perfc_info[i].nr_elements;
150 break;
151 }
152 }
154 arch_perfc_reset();
155 }
157 static xen_sysctl_perfc_desc_t perfc_d[NR_PERFCTRS];
158 static xen_sysctl_perfc_val_t *perfc_vals;
159 static unsigned int perfc_nbr_vals;
160 static int perfc_init = 0;
161 static int perfc_copy_info(XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc,
162 XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val)
163 {
164 unsigned int i, j, v;
166 /* We only copy the name and array-size information once. */
167 if ( !perfc_init )
168 {
169 for ( i = 0; i < NR_PERFCTRS; i++ )
170 {
171 safe_strcpy(perfc_d[i].name, perfc_info[i].name);
173 switch ( perfc_info[i].type )
174 {
175 case TYPE_SINGLE:
176 case TYPE_S_SINGLE:
177 perfc_d[i].nr_vals = num_possible_cpus();
178 break;
179 case TYPE_ARRAY:
180 case TYPE_S_ARRAY:
181 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
182 break;
183 }
184 perfc_nbr_vals += perfc_d[i].nr_vals;
185 }
186 perfc_vals = xmalloc_array(xen_sysctl_perfc_val_t, perfc_nbr_vals);
187 perfc_init = 1;
188 }
190 if ( guest_handle_is_null(desc) )
191 return 0;
193 if ( perfc_vals == NULL )
194 return -ENOMEM;
196 /* Architecture may fill counters from hardware. */
197 arch_perfc_gather();
199 /* We gather the counts together every time. */
200 for ( i = j = v = 0; i < NR_PERFCTRS; i++ )
201 {
202 unsigned int cpu;
204 switch ( perfc_info[i].type )
205 {
206 case TYPE_SINGLE:
207 case TYPE_S_SINGLE:
208 for_each_cpu ( cpu )
209 perfc_vals[v++] = per_cpu(perfcounters, cpu)[j];
210 ++j;
211 break;
212 case TYPE_ARRAY:
213 case TYPE_S_ARRAY:
214 memset(perfc_vals + v, 0, perfc_d[i].nr_vals * sizeof(*perfc_vals));
215 for_each_cpu ( cpu )
216 {
217 perfc_t *counters = per_cpu(perfcounters, cpu) + j;
218 unsigned int k;
220 for ( k = 0; k < perfc_d[i].nr_vals; k++ )
221 perfc_vals[v + k] += counters[k];
222 }
223 v += perfc_d[i].nr_vals;
224 j += perfc_info[i].nr_elements;
225 break;
226 }
227 }
228 BUG_ON(v != perfc_nbr_vals);
230 if ( copy_to_guest(desc, perfc_d, NR_PERFCTRS) )
231 return -EFAULT;
232 if ( copy_to_guest(val, perfc_vals, perfc_nbr_vals) )
233 return -EFAULT;
234 return 0;
235 }
237 /* Dom0 control of perf counters */
238 int perfc_control(xen_sysctl_perfc_op_t *pc)
239 {
240 static DEFINE_SPINLOCK(lock);
241 int rc;
243 spin_lock(&lock);
245 switch ( pc->cmd )
246 {
247 case XEN_SYSCTL_PERFCOP_reset:
248 rc = perfc_copy_info(pc->desc, pc->val);
249 perfc_reset(0);
250 break;
252 case XEN_SYSCTL_PERFCOP_query:
253 rc = perfc_copy_info(pc->desc, pc->val);
254 break;
256 default:
257 rc = -EINVAL;
258 break;
259 }
261 spin_unlock(&lock);
263 pc->nr_counters = NR_PERFCTRS;
264 pc->nr_vals = perfc_nbr_vals;
266 return rc;
267 }
269 /*
270 * Local variables:
271 * mode: C
272 * c-set-style: "BSD"
273 * c-basic-offset: 4
274 * tab-width: 4
275 * indent-tabs-mode: nil
276 * End:
277 */