1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (C) 2004 - Rolf Neugebauer - Intel Research Cambridge
4 ****************************************************************************
5 *
6 * File: xenperf.c
7 * Author: Rolf Neugebauer (rolf.neugebauer@intel.com)
8 * Date: Nov 2004
9 *
10 * Description:
11 */
12
13 #include <xenctrl.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sys/mman.h>
17 #include <errno.h>
18 #include <string.h>
19
20 #define X(name) [__HYPERVISOR_##name] = #name
21 static const char *const hypercall_name_table[64] =
22 {
23 X(set_trap_table),
24 X(mmu_update),
25 X(set_gdt),
26 X(stack_switch),
27 X(set_callbacks),
28 X(fpu_taskswitch),
29 X(sched_op_compat),
30 X(platform_op),
31 X(set_debugreg),
32 X(get_debugreg),
33 X(update_descriptor),
34 X(memory_op),
35 X(multicall),
36 X(update_va_mapping),
37 X(set_timer_op),
38 X(event_channel_op_compat),
39 X(xen_version),
40 X(console_io),
41 X(physdev_op_compat),
42 X(grant_table_op),
43 X(vm_assist),
44 X(update_va_mapping_otherdomain),
45 X(iret),
46 X(vcpu_op),
47 X(set_segment_base),
48 X(mmuext_op),
49 X(xsm_op),
50 X(nmi_op),
51 X(sched_op),
52 X(callback_op),
53 X(xenoprof_op),
54 X(event_channel_op),
55 X(physdev_op),
56 X(hvm_op),
57 X(sysctl),
58 X(domctl),
59 X(kexec_op),
60 X(tmem_op),
61 X(argo_op),
62 X(xenpmu_op),
63 X(dm_op),
64 X(hypfs_op),
65 #if defined(__i386__) || defined(__x86_64__)
66 X(mca),
67 [__HYPERVISOR_arch_1] = "paging-domctl-continuation",
68 #else
69 X(arch_0),
70 X(arch_1),
71 #endif
72 X(arch_2),
73 X(arch_3),
74 X(arch_4),
75 X(arch_5),
76 X(arch_6),
77 X(arch_7),
78 };
79 #undef X
80
main(int argc,char * argv[])81 int main(int argc, char *argv[])
82 {
83 int i, j;
84 xc_interface *xc_handle;
85 DECLARE_HYPERCALL_BUFFER(xc_perfc_desc_t, pcd);
86 DECLARE_HYPERCALL_BUFFER(xc_perfc_val_t, pcv);
87 xc_perfc_val_t *val;
88 int num_desc, num_val;
89 unsigned int reset = 0, full = 0, pretty = 0;
90 char hypercall_name[36];
91
92 if ( argc > 1 )
93 {
94 char *p = argv[1];
95 if ( p[0] == '-' )
96 {
97 switch ( p[1] )
98 {
99 case 'f':
100 full = 1;
101 break;
102 case 'p':
103 full = 1;
104 pretty = 1;
105 break;
106 case 'r':
107 reset = 1;
108 break;
109 default:
110 goto error;
111 }
112 }
113 else
114 {
115 error:
116 printf("%s: [-r]\n", argv[0]);
117 printf("no args: print digested counters\n");
118 printf(" -f : print full arrays/histograms\n");
119 printf(" -p : print full arrays/histograms in pretty format\n");
120 printf(" -r : reset counters\n");
121 return 0;
122 }
123 }
124
125 if ( (xc_handle = xc_interface_open(0,0,0)) == 0 )
126 {
127 fprintf(stderr, "Error opening xc interface: %d (%s)\n",
128 errno, strerror(errno));
129 return 1;
130 }
131
132 if ( reset )
133 {
134 if ( xc_perfc_reset(xc_handle) != 0 )
135 {
136 fprintf(stderr, "Error resetting performance counters: %d (%s)\n",
137 errno, strerror(errno));
138 return 1;
139 }
140
141 return 0;
142 }
143
144 if ( xc_perfc_query_number(xc_handle, &num_desc, &num_val) != 0 )
145 {
146 fprintf(stderr, "Error getting number of perf counters: %d (%s)\n",
147 errno, strerror(errno));
148 return 1;
149 }
150
151 pcd = xc_hypercall_buffer_alloc(xc_handle, pcd, sizeof(*pcd) * num_desc);
152 pcv = xc_hypercall_buffer_alloc(xc_handle, pcv, sizeof(*pcv) * num_val);
153
154 if ( pcd == NULL || pcv == NULL)
155 {
156 fprintf(stderr, "Could not allocate buffers: %d (%s)\n",
157 errno, strerror(errno));
158 exit(-1);
159 }
160
161 if ( xc_perfc_query(xc_handle, HYPERCALL_BUFFER(pcd), HYPERCALL_BUFFER(pcv)) != 0 )
162 {
163 fprintf(stderr, "Error getting perf counter: %d (%s)\n",
164 errno, strerror(errno));
165 return 1;
166 }
167
168 val = pcv;
169 for ( i = 0; i < num_desc; i++ )
170 {
171 unsigned long long sum = 0;
172
173 printf ("%-35s ", pcd[i].name);
174
175 for ( j = 0; j < pcd[i].nr_vals; j++ )
176 sum += val[j];
177 printf("T=%10llu ", sum);
178
179 if ( sum && (full || (pcd[i].nr_vals <= 4)) )
180 {
181 if ( pretty && (strcmp(pcd[i].name, "hypercalls") == 0) )
182 {
183 printf("\n");
184 for( j = 0; j < pcd[i].nr_vals; j++ )
185 {
186 if ( val[j] == 0 )
187 continue;
188 if ( (j < 64) && hypercall_name_table[j] )
189 strncpy(hypercall_name, hypercall_name_table[j],
190 sizeof(hypercall_name));
191 else
192 snprintf(hypercall_name, sizeof(hypercall_name), "[%d]", j);
193 hypercall_name[sizeof(hypercall_name)-1]='\0';
194 printf("%-35s ", hypercall_name);
195 printf("%12u\n", (unsigned int)val[j]);
196 }
197 }
198 else
199 {
200 for ( j = 0; j < pcd[i].nr_vals; j++ )
201 printf(" %10u", (unsigned int)val[j]);
202 printf("\n");
203 }
204 }
205 else
206 {
207 printf("\n");
208 }
209
210 val += pcd[i].nr_vals;
211 }
212
213 xc_hypercall_buffer_free(xc_handle, pcd);
214 xc_hypercall_buffer_free(xc_handle, pcv);
215 return 0;
216 }
217