ia64/xen-unstable

view xen/common/perfc.c @ 11128:f2f584093379

[POWERPC] Update .hgignore
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author kfraser@localhost.localdomain
date Tue Aug 15 10:38:59 2006 +0100 (2006-08-15)
parents 6289234304f1
children 86d26e6ec89b
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/dom0_ops.h>
11 #include <asm/perfc.h>
13 #undef PERFCOUNTER
14 #undef PERFCOUNTER_CPU
15 #undef PERFCOUNTER_ARRAY
16 #undef PERFSTATUS
17 #undef PERFSTATUS_CPU
18 #undef PERFSTATUS_ARRAY
19 #define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
20 #define PERFCOUNTER_CPU( var, name ) { name, TYPE_CPU, 0 },
21 #define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
22 #define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
23 #define PERFSTATUS_CPU( var, name ) { name, TYPE_S_CPU, 0 },
24 #define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
25 static struct {
26 char *name;
27 enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
28 TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
29 } type;
30 int nr_elements;
31 } perfc_info[] = {
32 #include <xen/perfc_defn.h>
33 };
35 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
37 struct perfcounter perfcounters;
39 void perfc_printall(unsigned char key)
40 {
41 unsigned int i, j, sum;
42 s_time_t now = NOW();
43 atomic_t *counters = (atomic_t *)&perfcounters;
45 printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
46 (u32)(now>>32), (u32)now);
48 for ( i = 0; i < NR_PERFCTRS; i++ )
49 {
50 printk("%-32s ", perfc_info[i].name);
51 switch ( perfc_info[i].type )
52 {
53 case TYPE_SINGLE:
54 case TYPE_S_SINGLE:
55 printk("TOTAL[%10d]", atomic_read(&counters[0]));
56 counters += 1;
57 break;
58 case TYPE_CPU:
59 case TYPE_S_CPU:
60 sum = 0;
61 for_each_online_cpu ( j )
62 sum += atomic_read(&counters[j]);
63 printk("TOTAL[%10u]", sum);
64 if (sum)
65 {
66 for_each_online_cpu ( j )
67 printk(" CPU%02d[%10d]", j, atomic_read(&counters[j]));
68 }
69 counters += NR_CPUS;
70 break;
71 case TYPE_ARRAY:
72 case TYPE_S_ARRAY:
73 for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
74 sum += atomic_read(&counters[j]);
75 printk("TOTAL[%10u]", sum);
76 #ifdef PERF_ARRAYS
77 if (sum)
78 {
79 for ( j = 0; j < perfc_info[i].nr_elements; j++ )
80 {
81 if ( (j % 4) == 0 )
82 printk("\n ");
83 printk(" ARR%02d[%10d]", j, atomic_read(&counters[j]));
84 }
85 }
86 #endif
87 counters += j;
88 break;
89 }
90 printk("\n");
91 }
93 arch_perfc_printall();
94 }
96 void perfc_reset(unsigned char key)
97 {
98 unsigned int i, j;
99 s_time_t now = NOW();
100 atomic_t *counters = (atomic_t *)&perfcounters;
102 if ( key != '\0' )
103 printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
104 (u32)(now>>32), (u32)now);
106 /* leave STATUS counters alone -- don't reset */
108 for ( i = 0; i < NR_PERFCTRS; i++ )
109 {
110 switch ( perfc_info[i].type )
111 {
112 case TYPE_SINGLE:
113 atomic_set(&counters[0],0);
114 case TYPE_S_SINGLE:
115 counters += 1;
116 break;
117 case TYPE_CPU:
118 for ( j = 0; j < NR_CPUS; j++ )
119 atomic_set(&counters[j],0);
120 case TYPE_S_CPU:
121 counters += NR_CPUS;
122 break;
123 case TYPE_ARRAY:
124 for ( j = 0; j < perfc_info[i].nr_elements; j++ )
125 atomic_set(&counters[j],0);
126 case TYPE_S_ARRAY:
127 counters += perfc_info[i].nr_elements;
128 break;
129 }
130 }
132 arch_perfc_reset ();
133 }
135 static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
136 static dom0_perfc_val_t *perfc_vals;
137 static int perfc_nbr_vals;
138 static int perfc_init = 0;
139 static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc,
140 XEN_GUEST_HANDLE(dom0_perfc_val_t) val)
141 {
142 unsigned int i, j;
143 unsigned int v = 0;
144 atomic_t *counters = (atomic_t *)&perfcounters;
146 if ( guest_handle_is_null(desc) )
147 return 0;
149 /* We only copy the name and array-size information once. */
150 if ( !perfc_init )
151 {
152 for ( i = 0; i < NR_PERFCTRS; i++ )
153 {
154 strncpy(perfc_d[i].name, perfc_info[i].name,
155 sizeof(perfc_d[i].name));
156 perfc_d[i].name[sizeof(perfc_d[i].name)-1] = '\0';
158 switch ( perfc_info[i].type )
159 {
160 case TYPE_SINGLE:
161 case TYPE_S_SINGLE:
162 perfc_d[i].nr_vals = 1;
163 break;
164 case TYPE_CPU:
165 case TYPE_S_CPU:
166 perfc_d[i].nr_vals = num_online_cpus();
167 break;
168 case TYPE_ARRAY:
169 case TYPE_S_ARRAY:
170 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
171 break;
172 }
173 perfc_nbr_vals += perfc_d[i].nr_vals;
174 }
175 perfc_vals = xmalloc_array(dom0_perfc_val_t, perfc_nbr_vals);
176 perfc_init = 1;
177 }
178 if (perfc_vals == NULL)
179 return -ENOMEM;
181 /* Architecture may fill counters from hardware. */
182 arch_perfc_gather();
184 /* We gather the counts together every time. */
185 for ( i = 0; i < NR_PERFCTRS; i++ )
186 {
187 switch ( perfc_info[i].type )
188 {
189 case TYPE_SINGLE:
190 case TYPE_S_SINGLE:
191 perfc_vals[v++] = atomic_read(&counters[0]);
192 counters += 1;
193 break;
194 case TYPE_CPU:
195 case TYPE_S_CPU:
196 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
197 perfc_vals[v++] = atomic_read(&counters[j]);
198 counters += NR_CPUS;
199 break;
200 case TYPE_ARRAY:
201 case TYPE_S_ARRAY:
202 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
203 perfc_vals[v++] = atomic_read(&counters[j]);
204 counters += perfc_info[i].nr_elements;
205 break;
206 }
207 }
208 BUG_ON(v != perfc_nbr_vals);
210 if (copy_to_guest(desc, (dom0_perfc_desc_t *)perfc_d, NR_PERFCTRS))
211 return -EFAULT;
212 if (copy_to_guest(val, perfc_vals, perfc_nbr_vals))
213 return -EFAULT;
214 return 0;
215 }
217 /* Dom0 control of perf counters */
218 int perfc_control(dom0_perfccontrol_t *pc)
219 {
220 static DEFINE_SPINLOCK(lock);
221 u32 op = pc->op;
222 int rc;
224 spin_lock(&lock);
226 switch ( op )
227 {
228 case DOM0_PERFCCONTROL_OP_RESET:
229 perfc_copy_info(pc->desc, pc->val);
230 perfc_reset(0);
231 rc = 0;
232 break;
234 case DOM0_PERFCCONTROL_OP_QUERY:
235 perfc_copy_info(pc->desc, pc->val);
236 rc = 0;
237 break;
239 default:
240 rc = -EINVAL;
241 break;
242 }
244 spin_unlock(&lock);
246 pc->nr_counters = NR_PERFCTRS;
247 pc->nr_vals = perfc_nbr_vals;
249 return rc;
250 }
252 /*
253 * Local variables:
254 * mode: C
255 * c-set-style: "BSD"
256 * c-basic-offset: 4
257 * tab-width: 4
258 * indent-tabs-mode: nil
259 * End:
260 */