direct-io.hg

view xen/common/perfc.c @ 3231:9035b6656818

bitkeeper revision 1.1159.187.48 (41adc6420WlNaaoUkvfgNxl44rpYYg)

Export Xen s/w perfctrs to DOM0 via new 'xenperf' utility.
author kaf24@scramble.cl.cam.ac.uk
date Wed Dec 01 13:25:22 2004 +0000 (2004-12-01)
parents 61a55dee09d8
children f2e12f9f7cc8
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 <public/dom0_ops.h>
8 #include <asm/uaccess.h>
10 #undef PERFCOUNTER
11 #undef PERFCOUNTER_CPU
12 #undef PERFCOUNTER_ARRAY
13 #undef PERFSTATUS
14 #undef PERFSTATUS_CPU
15 #undef PERFSTATUS_ARRAY
16 #define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
17 #define PERFCOUNTER_CPU( var, name ) { name, TYPE_CPU, 0 },
18 #define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
19 #define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
20 #define PERFSTATUS_CPU( var, name ) { name, TYPE_S_CPU, 0 },
21 #define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
22 static struct {
23 char *name;
24 enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
25 TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
26 } type;
27 int nr_elements;
28 } perfc_info[] = {
29 #include <xen/perfc_defn.h>
30 };
32 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
34 struct perfcounter_t perfcounters;
36 void perfc_printall(unsigned char key)
37 {
38 int i, j, sum;
39 s_time_t now = NOW();
40 atomic_t *counters = (atomic_t *)&perfcounters;
42 printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
43 (u32)(now>>32), (u32)now);
45 for ( i = 0; i < NR_PERFCTRS; i++ )
46 {
47 printk("%-32s ", perfc_info[i].name);
48 switch ( perfc_info[i].type )
49 {
50 case TYPE_SINGLE:
51 case TYPE_S_SINGLE:
52 printk("TOTAL[%10d]", atomic_read(&counters[0]));
53 counters += 1;
54 break;
55 case TYPE_CPU:
56 case TYPE_S_CPU:
57 for ( j = sum = 0; j < smp_num_cpus; j++ )
58 sum += atomic_read(&counters[j]);
59 printk("TOTAL[%10d] ", sum);
60 for ( j = 0; j < smp_num_cpus; j++ )
61 printk("CPU%02d[%10d] ", j, atomic_read(&counters[j]));
62 counters += NR_CPUS;
63 break;
64 case TYPE_ARRAY:
65 case TYPE_S_ARRAY:
66 for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
67 sum += atomic_read(&counters[j]);
68 printk("TOTAL[%10d] ", sum);
69 for ( j = 0; j < perfc_info[i].nr_elements; j++ )
70 printk("ARR%02d[%10d] ", j, atomic_read(&counters[j]));
71 counters += j;
72 break;
73 }
74 printk("\n");
75 }
76 }
78 void perfc_reset(unsigned char key)
79 {
80 int i, j, sum;
81 s_time_t now = NOW();
82 atomic_t *counters = (atomic_t *)&perfcounters;
84 if ( key != '\0' )
85 printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
86 (u32)(now>>32), (u32)now);
88 /* leave STATUS counters alone -- don't reset */
90 for ( i = 0; i < NR_PERFCTRS; i++ )
91 {
92 switch ( perfc_info[i].type )
93 {
94 case TYPE_SINGLE:
95 atomic_set(&counters[0],0);
96 case TYPE_S_SINGLE:
97 counters += 1;
98 break;
99 case TYPE_CPU:
100 for ( j = sum = 0; j < smp_num_cpus; j++ )
101 atomic_set(&counters[j],0);
102 case TYPE_S_CPU:
103 counters += NR_CPUS;
104 break;
105 case TYPE_ARRAY:
106 for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
107 atomic_set(&counters[j],0);
108 case TYPE_S_ARRAY:
109 counters += perfc_info[i].nr_elements;
110 break;
111 }
112 }
113 }
115 static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
116 static int perfc_init = 0;
117 static int perfc_copy_info(dom0_perfc_desc_t *desc)
118 {
119 unsigned int i, j;
120 atomic_t *counters = (atomic_t *)&perfcounters;
122 if ( desc == NULL )
123 return 0;
125 /* We only copy the name and array-size information once. */
126 if ( !perfc_init )
127 {
128 for ( i = 0; i < NR_PERFCTRS; i++ )
129 {
130 strncpy(perfc_d[i].name, perfc_info[i].name,
131 sizeof(perfc_d[i].name));
132 perfc_d[i].name[sizeof(perfc_d[i].name)-1] = '\0';
134 switch ( perfc_info[i].type )
135 {
136 case TYPE_SINGLE:
137 case TYPE_S_SINGLE:
138 perfc_d[i].nr_vals = 1;
139 break;
140 case TYPE_CPU:
141 case TYPE_S_CPU:
142 perfc_d[i].nr_vals = smp_num_cpus;
143 break;
144 case TYPE_ARRAY:
145 case TYPE_S_ARRAY:
146 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
147 break;
148 }
150 if ( perfc_d[i].nr_vals > ARRAY_SIZE(perfc_d[i].vals) )
151 perfc_d[i].nr_vals = ARRAY_SIZE(perfc_d[i].vals);
152 }
154 perfc_init = 1;
155 }
157 /* We gather the counts together every time. */
158 for ( i = 0; i < NR_PERFCTRS; i++ )
159 {
160 switch ( perfc_info[i].type )
161 {
162 case TYPE_SINGLE:
163 case TYPE_S_SINGLE:
164 perfc_d[i].vals[0] = atomic_read(&counters[0]);
165 counters += 1;
166 break;
167 case TYPE_CPU:
168 case TYPE_S_CPU:
169 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
170 perfc_d[i].vals[j] = atomic_read(&counters[j]);
171 counters += NR_CPUS;
172 break;
173 case TYPE_ARRAY:
174 case TYPE_S_ARRAY:
175 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
176 perfc_d[i].vals[j] = atomic_read(&counters[j]);
177 counters += perfc_info[i].nr_elements;
178 break;
179 }
180 }
182 return (copy_to_user(desc, perfc_d, NR_PERFCTRS * sizeof(*desc)) ?
183 -EFAULT : 0);
184 }
186 /* Dom0 control of perf counters */
187 int perfc_control(dom0_perfccontrol_t *pc)
188 {
189 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
190 u32 op = pc->op;
191 int rc;
193 pc->nr_counters = NR_PERFCTRS;
195 spin_lock(&lock);
197 switch ( op )
198 {
199 case DOM0_PERFCCONTROL_OP_RESET:
200 perfc_copy_info(pc->desc);
201 perfc_reset(0);
202 rc = 0;
203 break;
205 case DOM0_PERFCCONTROL_OP_QUERY:
206 perfc_copy_info(pc->desc);
207 rc = 0;
208 break;
210 default:
211 rc = -EINVAL;
212 break;
213 }
215 spin_unlock(&lock);
217 return rc;
218 }