direct-io.hg

view xen/common/perfc.c @ 5517:10e9028c8e3d

bitkeeper revision 1.1718.1.10 (42b7b19aqOS_1M8I4pIOFjiTPYWV-g)

Merge bk://xenbits.xensource.com/xen-unstable.bk
into spot.cl.cam.ac.uk:C:/Documents and Settings/iap10/xen-unstable.bk
author iap10@spot.cl.cam.ac.uk
date Tue Jun 21 06:20:10 2005 +0000 (2005-06-21)
parents de3abc161c24
children 424166f4f3cf 8864f0be80c6 f51fe43c5d1c 6783e59e1c45 8799d14bef77
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 <public/dom0_ops.h>
9 #include <asm/uaccess.h>
11 #undef PERFCOUNTER
12 #undef PERFCOUNTER_CPU
13 #undef PERFCOUNTER_ARRAY
14 #undef PERFSTATUS
15 #undef PERFSTATUS_CPU
16 #undef PERFSTATUS_ARRAY
17 #define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
18 #define PERFCOUNTER_CPU( var, name ) { name, TYPE_CPU, 0 },
19 #define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
20 #define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
21 #define PERFSTATUS_CPU( var, name ) { name, TYPE_S_CPU, 0 },
22 #define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
23 static struct {
24 char *name;
25 enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
26 TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
27 } type;
28 int nr_elements;
29 } perfc_info[] = {
30 #include <xen/perfc_defn.h>
31 };
33 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
35 struct perfcounter perfcounters;
37 void perfc_printall(unsigned char key)
38 {
39 int i, j, sum;
40 s_time_t now = NOW();
41 atomic_t *counters = (atomic_t *)&perfcounters;
43 printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
44 (u32)(now>>32), (u32)now);
46 for ( i = 0; i < NR_PERFCTRS; i++ )
47 {
48 printk("%-32s ", perfc_info[i].name);
49 switch ( perfc_info[i].type )
50 {
51 case TYPE_SINGLE:
52 case TYPE_S_SINGLE:
53 printk("TOTAL[%10d]", atomic_read(&counters[0]));
54 counters += 1;
55 break;
56 case TYPE_CPU:
57 case TYPE_S_CPU:
58 sum = 0;
59 for_each_online_cpu ( j )
60 sum += atomic_read(&counters[j]);
61 printk("TOTAL[%10d] ", sum);
62 for_each_online_cpu ( j )
63 printk("CPU%02d[%10d] ", j, atomic_read(&counters[j]));
64 counters += NR_CPUS;
65 break;
66 case TYPE_ARRAY:
67 case TYPE_S_ARRAY:
68 for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
69 sum += atomic_read(&counters[j]);
70 printk("TOTAL[%10d] ", sum);
71 #ifdef PERF_ARRAYS
72 for ( j = 0; j < perfc_info[i].nr_elements; j++ )
73 {
74 if ( (j != 0) && ((j % 4) == 0) )
75 printk("\n ");
76 printk("ARR%02d[%10d] ", j, atomic_read(&counters[j]));
77 }
78 #endif
79 counters += j;
80 break;
81 }
82 printk("\n");
83 }
84 }
86 void perfc_reset(unsigned char key)
87 {
88 int i, j;
89 s_time_t now = NOW();
90 atomic_t *counters = (atomic_t *)&perfcounters;
92 if ( key != '\0' )
93 printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
94 (u32)(now>>32), (u32)now);
96 /* leave STATUS counters alone -- don't reset */
98 for ( i = 0; i < NR_PERFCTRS; i++ )
99 {
100 switch ( perfc_info[i].type )
101 {
102 case TYPE_SINGLE:
103 atomic_set(&counters[0],0);
104 case TYPE_S_SINGLE:
105 counters += 1;
106 break;
107 case TYPE_CPU:
108 for ( j = 0; j < NR_CPUS; j++ )
109 atomic_set(&counters[j],0);
110 case TYPE_S_CPU:
111 counters += NR_CPUS;
112 break;
113 case TYPE_ARRAY:
114 for ( j = 0; j < NR_CPUS; j++ )
115 atomic_set(&counters[j],0);
116 case TYPE_S_ARRAY:
117 counters += perfc_info[i].nr_elements;
118 break;
119 }
120 }
121 }
123 static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
124 static int perfc_init = 0;
125 static int perfc_copy_info(dom0_perfc_desc_t *desc)
126 {
127 unsigned int i, j;
128 atomic_t *counters = (atomic_t *)&perfcounters;
130 if ( desc == NULL )
131 return 0;
133 /* We only copy the name and array-size information once. */
134 if ( !perfc_init )
135 {
136 for ( i = 0; i < NR_PERFCTRS; i++ )
137 {
138 strncpy(perfc_d[i].name, perfc_info[i].name,
139 sizeof(perfc_d[i].name));
140 perfc_d[i].name[sizeof(perfc_d[i].name)-1] = '\0';
142 switch ( perfc_info[i].type )
143 {
144 case TYPE_SINGLE:
145 case TYPE_S_SINGLE:
146 perfc_d[i].nr_vals = 1;
147 break;
148 case TYPE_CPU:
149 case TYPE_S_CPU:
150 perfc_d[i].nr_vals = num_online_cpus();
151 break;
152 case TYPE_ARRAY:
153 case TYPE_S_ARRAY:
154 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
155 break;
156 }
158 if ( perfc_d[i].nr_vals > ARRAY_SIZE(perfc_d[i].vals) )
159 perfc_d[i].nr_vals = ARRAY_SIZE(perfc_d[i].vals);
160 }
162 perfc_init = 1;
163 }
165 /* We gather the counts together every time. */
166 for ( i = 0; i < NR_PERFCTRS; i++ )
167 {
168 switch ( perfc_info[i].type )
169 {
170 case TYPE_SINGLE:
171 case TYPE_S_SINGLE:
172 perfc_d[i].vals[0] = atomic_read(&counters[0]);
173 counters += 1;
174 break;
175 case TYPE_CPU:
176 case TYPE_S_CPU:
177 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
178 perfc_d[i].vals[j] = atomic_read(&counters[j]);
179 counters += NR_CPUS;
180 break;
181 case TYPE_ARRAY:
182 case TYPE_S_ARRAY:
183 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
184 perfc_d[i].vals[j] = atomic_read(&counters[j]);
185 counters += perfc_info[i].nr_elements;
186 break;
187 }
188 }
190 return (copy_to_user(desc, perfc_d, NR_PERFCTRS * sizeof(*desc)) ?
191 -EFAULT : 0);
192 }
194 /* Dom0 control of perf counters */
195 int perfc_control(dom0_perfccontrol_t *pc)
196 {
197 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
198 u32 op = pc->op;
199 int rc;
201 pc->nr_counters = NR_PERFCTRS;
203 spin_lock(&lock);
205 switch ( op )
206 {
207 case DOM0_PERFCCONTROL_OP_RESET:
208 perfc_copy_info(pc->desc);
209 perfc_reset(0);
210 rc = 0;
211 break;
213 case DOM0_PERFCCONTROL_OP_QUERY:
214 perfc_copy_info(pc->desc);
215 rc = 0;
216 break;
218 default:
219 rc = -EINVAL;
220 break;
221 }
223 spin_unlock(&lock);
225 return rc;
226 }
228 /*
229 * Local variables:
230 * mode: C
231 * c-set-style: "BSD"
232 * c-basic-offset: 4
233 * tab-width: 4
234 * indent-tabs-mode: nil
235 * End:
236 */