ia64/xen-unstable

view xen/common/perfc.c @ 6552:a9873d384da4

Merge.
author adsharma@los-vmm.sc.intel.com
date Thu Aug 25 12:24:48 2005 -0700 (2005-08-25)
parents 112d44270733 fa0754a9f64f
children dfaf788ab18c
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>
10 #include <xen/mm.h>
12 #undef PERFCOUNTER
13 #undef PERFCOUNTER_CPU
14 #undef PERFCOUNTER_ARRAY
15 #undef PERFSTATUS
16 #undef PERFSTATUS_CPU
17 #undef PERFSTATUS_ARRAY
18 #define PERFCOUNTER( var, name ) { name, TYPE_SINGLE, 0 },
19 #define PERFCOUNTER_CPU( var, name ) { name, TYPE_CPU, 0 },
20 #define PERFCOUNTER_ARRAY( var, name, size ) { name, TYPE_ARRAY, size },
21 #define PERFSTATUS( var, name ) { name, TYPE_S_SINGLE, 0 },
22 #define PERFSTATUS_CPU( var, name ) { name, TYPE_S_CPU, 0 },
23 #define PERFSTATUS_ARRAY( var, name, size ) { name, TYPE_S_ARRAY, size },
24 static struct {
25 char *name;
26 enum { TYPE_SINGLE, TYPE_CPU, TYPE_ARRAY,
27 TYPE_S_SINGLE, TYPE_S_CPU, TYPE_S_ARRAY
28 } type;
29 int nr_elements;
30 } perfc_info[] = {
31 #include <xen/perfc_defn.h>
32 };
34 #define NR_PERFCTRS (sizeof(perfc_info) / sizeof(perfc_info[0]))
36 struct perfcounter perfcounters;
38 void perfc_printall(unsigned char key)
39 {
40 int i, j, sum;
41 s_time_t now = NOW();
42 atomic_t *counters = (atomic_t *)&perfcounters;
44 printk("Xen performance counters SHOW (now = 0x%08X:%08X)\n",
45 (u32)(now>>32), (u32)now);
47 for ( i = 0; i < NR_PERFCTRS; i++ )
48 {
49 printk("%-32s ", perfc_info[i].name);
50 switch ( perfc_info[i].type )
51 {
52 case TYPE_SINGLE:
53 case TYPE_S_SINGLE:
54 printk("TOTAL[%10d]", atomic_read(&counters[0]));
55 counters += 1;
56 break;
57 case TYPE_CPU:
58 case TYPE_S_CPU:
59 sum = 0;
60 for_each_online_cpu ( j )
61 sum += atomic_read(&counters[j]);
62 printk("TOTAL[%10d] ", sum);
63 for_each_online_cpu ( j )
64 printk("CPU%02d[%10d] ", j, atomic_read(&counters[j]));
65 counters += NR_CPUS;
66 break;
67 case TYPE_ARRAY:
68 case TYPE_S_ARRAY:
69 for ( j = sum = 0; j < perfc_info[i].nr_elements; j++ )
70 sum += atomic_read(&counters[j]);
71 printk("TOTAL[%10d] ", sum);
72 #ifdef PERF_ARRAYS
73 for ( j = 0; j < perfc_info[i].nr_elements; j++ )
74 {
75 if ( (j != 0) && ((j % 4) == 0) )
76 printk("\n ");
77 printk("ARR%02d[%10d] ", j, atomic_read(&counters[j]));
78 }
79 #endif
80 counters += j;
81 break;
82 }
83 printk("\n");
84 }
86 #ifdef PERF_ARRAYS
87 ptwr_eip_stat_print();
88 #endif
89 }
91 void perfc_reset(unsigned char key)
92 {
93 int i, j;
94 s_time_t now = NOW();
95 atomic_t *counters = (atomic_t *)&perfcounters;
97 if ( key != '\0' )
98 printk("Xen performance counters RESET (now = 0x%08X:%08X)\n",
99 (u32)(now>>32), (u32)now);
101 /* leave STATUS counters alone -- don't reset */
103 for ( i = 0; i < NR_PERFCTRS; i++ )
104 {
105 switch ( perfc_info[i].type )
106 {
107 case TYPE_SINGLE:
108 atomic_set(&counters[0],0);
109 case TYPE_S_SINGLE:
110 counters += 1;
111 break;
112 case TYPE_CPU:
113 for ( j = 0; j < NR_CPUS; j++ )
114 atomic_set(&counters[j],0);
115 case TYPE_S_CPU:
116 counters += NR_CPUS;
117 break;
118 case TYPE_ARRAY:
119 for ( j = 0; j < NR_CPUS; j++ )
120 atomic_set(&counters[j],0);
121 case TYPE_S_ARRAY:
122 counters += perfc_info[i].nr_elements;
123 break;
124 }
125 }
127 #ifdef PERF_ARRAYS
128 ptwr_eip_stat_reset();
129 #endif
130 }
132 static dom0_perfc_desc_t perfc_d[NR_PERFCTRS];
133 static int perfc_init = 0;
134 static int perfc_copy_info(dom0_perfc_desc_t *desc)
135 {
136 unsigned int i, j;
137 atomic_t *counters = (atomic_t *)&perfcounters;
139 if ( desc == NULL )
140 return 0;
142 /* We only copy the name and array-size information once. */
143 if ( !perfc_init )
144 {
145 for ( i = 0; i < NR_PERFCTRS; i++ )
146 {
147 strncpy(perfc_d[i].name, perfc_info[i].name,
148 sizeof(perfc_d[i].name));
149 perfc_d[i].name[sizeof(perfc_d[i].name)-1] = '\0';
151 switch ( perfc_info[i].type )
152 {
153 case TYPE_SINGLE:
154 case TYPE_S_SINGLE:
155 perfc_d[i].nr_vals = 1;
156 break;
157 case TYPE_CPU:
158 case TYPE_S_CPU:
159 perfc_d[i].nr_vals = num_online_cpus();
160 break;
161 case TYPE_ARRAY:
162 case TYPE_S_ARRAY:
163 perfc_d[i].nr_vals = perfc_info[i].nr_elements;
164 break;
165 }
167 if ( perfc_d[i].nr_vals > ARRAY_SIZE(perfc_d[i].vals) )
168 perfc_d[i].nr_vals = ARRAY_SIZE(perfc_d[i].vals);
169 }
171 perfc_init = 1;
172 }
174 /* We gather the counts together every time. */
175 for ( i = 0; i < NR_PERFCTRS; i++ )
176 {
177 switch ( perfc_info[i].type )
178 {
179 case TYPE_SINGLE:
180 case TYPE_S_SINGLE:
181 perfc_d[i].vals[0] = atomic_read(&counters[0]);
182 counters += 1;
183 break;
184 case TYPE_CPU:
185 case TYPE_S_CPU:
186 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
187 perfc_d[i].vals[j] = atomic_read(&counters[j]);
188 counters += NR_CPUS;
189 break;
190 case TYPE_ARRAY:
191 case TYPE_S_ARRAY:
192 for ( j = 0; j < perfc_d[i].nr_vals; j++ )
193 perfc_d[i].vals[j] = atomic_read(&counters[j]);
194 counters += perfc_info[i].nr_elements;
195 break;
196 }
197 }
199 return (copy_to_user(desc, perfc_d, NR_PERFCTRS * sizeof(*desc)) ?
200 -EFAULT : 0);
201 }
203 /* Dom0 control of perf counters */
204 int perfc_control(dom0_perfccontrol_t *pc)
205 {
206 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
207 u32 op = pc->op;
208 int rc;
210 pc->nr_counters = NR_PERFCTRS;
212 spin_lock(&lock);
214 switch ( op )
215 {
216 case DOM0_PERFCCONTROL_OP_RESET:
217 perfc_copy_info(pc->desc);
218 perfc_reset(0);
219 rc = 0;
220 break;
222 case DOM0_PERFCCONTROL_OP_QUERY:
223 perfc_copy_info(pc->desc);
224 rc = 0;
225 break;
227 default:
228 rc = -EINVAL;
229 break;
230 }
232 spin_unlock(&lock);
234 return rc;
235 }
237 /*
238 * Local variables:
239 * mode: C
240 * c-set-style: "BSD"
241 * c-basic-offset: 4
242 * tab-width: 4
243 * indent-tabs-mode: nil
244 * End:
245 */