ia64/xen-unstable

view tools/misc/xen-tmem-list-parse.c @ 19648:f0e2df69a8eb

x86 hvm: Allow cross-vendor migration

Intercept #UD and emulate SYSCALL/SYSENTER/SYSEXIT as necessary.

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 26 15:01:36 2009 +0100 (2009-05-26)
parents f210a633571c
children 4294a04b24bc
line source
1 /*
2 * Parse output from tmem-list and reformat to human-readable
3 *
4 * NOTE: NEVER delete a parse call as this file documents backwards
5 * compatibility for older versions of tmem-list and we don't want to
6 * accidentally reuse an old tag
7 *
8 * Copyright (c) 2009, Dan Magenheimer, Oracle Corp.
9 */
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <string.h>
15 #define BUFSIZE 4096
16 #define PAGE_SIZE 4096
18 unsigned long long parse(char *s,char *match)
19 {
20 char *s1 = strstr(s,match);
21 unsigned long long ret;
23 if ( s1 == NULL )
24 return 0LL;
25 s1 += 2;
26 if ( *s1++ != ':' )
27 return 0LL;
28 sscanf(s1,"%llu",&ret);
29 return ret;
30 }
32 unsigned long long parse2(char *s,char *match1, char *match2)
33 {
34 char match[3];
35 match[0] = *match1;
36 match[1] = *match2;
37 match[2] = '\0';
38 return parse(s,match);
39 }
41 void parse_string(char *s,char *match, char *buf, int len)
42 {
43 char *s1 = strstr(s,match);
44 int i;
46 if ( s1 == NULL )
47 return;
48 s1 += 2;
49 if ( *s1++ != ':' )
50 return;
51 for ( i = 0; i < len; i++ )
52 *buf++ = *s1++;
53 }
55 void parse_sharers(char *s, char *match, char *buf, int len)
56 {
57 char *s1 = strstr(s,match);
58 char *b = buf;
60 if ( s1 == NULL )
61 return;
62 while ( s1 )
63 {
64 s1 += 2;
65 if (*s1++ != ':')
66 return;
67 while (*s1 <= '0' && *s1 <= '9')
68 *b++ = *s1++;
69 *b++ = ',';
70 s1 = strstr(s1,match);
71 }
72 if ( b != buf )
73 *--b = '\0';
74 }
76 void parse_global(char *s)
77 {
78 unsigned long long total_ops = parse(s,"Tt");
79 unsigned long long errored_ops = parse(s,"Te");
80 unsigned long long failed_copies = parse(s,"Cf");
81 unsigned long long alloc_failed = parse(s,"Af");
82 unsigned long long alloc_page_failed = parse(s,"Pf");
83 unsigned long long avail_pages = parse(s,"Ta");
84 unsigned long long low_on_memory = parse(s,"Lm");
85 unsigned long long evicted_pgs = parse(s,"Et");
86 unsigned long long evict_attempts = parse(s,"Ea");
87 unsigned long long relinq_pgs = parse(s,"Rt");
88 unsigned long long relinq_attempts = parse(s,"Ra");
89 unsigned long long max_evicts_per_relinq = parse(s,"Rx");
90 unsigned long long total_flush_pool = parse(s,"Fp");
91 unsigned long long global_eph_count = parse(s,"Ec");
92 unsigned long long global_eph_max = parse(s,"Em");
93 unsigned long long obj_count = parse(s,"Oc");
94 unsigned long long obj_max = parse(s,"Om");
95 unsigned long long rtree_node_count = parse(s,"Nc");
96 unsigned long long rtree_node_max = parse(s,"Nm");
97 unsigned long long pgp_count = parse(s,"Pc");
98 unsigned long long pgp_max = parse(s,"Pm");
100 printf("total tmem ops=%llu (errors=%llu) -- tmem pages avail=%llu\n",
101 total_ops, errored_ops, avail_pages);
102 printf("datastructs: objs=%llu (max=%llu) pgps=%llu (max=%llu) "
103 "nodes=%llu (max=%llu)\n",
104 obj_count, obj_max, pgp_count, pgp_max,
105 rtree_node_count, rtree_node_max);
106 printf("misc: failed_copies=%llu alloc_failed=%llu alloc_page_failed=%llu "
107 "low_mem=%llu evicted=%llu/%llu relinq=%llu/%llu, "
108 "max_evicts_per_relinq=%llu, flush_pools=%llu, "
109 "eph_count=%llu, eph_max=%llu\n",
110 failed_copies, alloc_failed, alloc_page_failed, low_on_memory,
111 evicted_pgs, evict_attempts, relinq_pgs, relinq_attempts,
112 max_evicts_per_relinq, total_flush_pool,
113 global_eph_count, global_eph_max);
114 }
116 #define PARSE_CYC_COUNTER(s,x,prefix) unsigned long long \
117 x##_count = parse2(s,prefix,"n"), \
118 x##_sum_cycles = parse2(s,prefix,"t"), \
119 x##_max_cycles = parse2(s,prefix,"x"), \
120 x##_min_cycles = parse2(s,prefix,"m")
121 #define PRINTF_CYC_COUNTER(x,text) \
122 if (x##_count) printf(text" avg=%llu, max=%llu, " \
123 "min=%llu, samples=%llu\n", \
124 x##_sum_cycles ? (x##_sum_cycles/x##_count) : 0, \
125 x##_max_cycles, x##_min_cycles, x##_count)
127 void parse_time_stats(char *s)
128 {
129 PARSE_CYC_COUNTER(s,succ_get,"G");
130 PARSE_CYC_COUNTER(s,succ_put,"P");
131 PARSE_CYC_COUNTER(s,non_succ_get,"g");
132 PARSE_CYC_COUNTER(s,non_succ_put,"p");
133 PARSE_CYC_COUNTER(s,flush,"F");
134 PARSE_CYC_COUNTER(s,flush_obj,"O");
135 PARSE_CYC_COUNTER(s,pg_copy,"C");
136 PARSE_CYC_COUNTER(s,compress,"c");
137 PARSE_CYC_COUNTER(s,decompress,"d");
139 PRINTF_CYC_COUNTER(succ_get,"succ get cycles:");
140 PRINTF_CYC_COUNTER(succ_put,"succ put cycles:");
141 PRINTF_CYC_COUNTER(non_succ_get,"failed get cycles:");
142 PRINTF_CYC_COUNTER(non_succ_put,"failed put cycles:");
143 PRINTF_CYC_COUNTER(flush,"flush cycles:");
144 PRINTF_CYC_COUNTER(flush_obj,"flush_obj cycles:");
145 PRINTF_CYC_COUNTER(pg_copy,"page copy cycles:");
146 PRINTF_CYC_COUNTER(compress,"compression cycles:");
147 PRINTF_CYC_COUNTER(decompress,"decompression cycles:");
148 }
150 void parse_client(char *s)
151 {
152 unsigned long cli_id = parse(s,"CI");
153 unsigned long weight = parse(s,"ww");
154 unsigned long cap = parse(s,"ca");
155 unsigned long compress = parse(s,"co");
156 unsigned long frozen = parse(s,"fr");
157 unsigned long long eph_count = parse(s,"Ec");
158 unsigned long long max_eph_count = parse(s,"Em");
159 unsigned long long compressed_pages = parse(s,"cp");
160 unsigned long long compressed_sum_size = parse(s,"cb");
161 unsigned long long compress_poor = parse(s,"cn");
162 unsigned long long compress_nomem = parse(s,"cm");
164 printf("domid%lu: weight=%lu,cap=%lu,compress=%d,frozen=%d,"
165 "eph_count=%llu,max_eph=%llu,"
166 "compression ratio=%lu%% (samples=%llu,poor=%llu,nomem=%llu)\n",
167 cli_id, weight, cap, compress?1:0, frozen?1:0,
168 eph_count, max_eph_count,
169 compressed_pages ? (long)((compressed_sum_size*100LL) /
170 (compressed_pages*PAGE_SIZE)) : 0,
171 compressed_pages, compress_poor, compress_nomem);
173 }
175 void parse_pool(char *s)
176 {
177 char pool_type[3];
178 unsigned long cli_id = parse(s,"CI");
179 unsigned long pool_id = parse(s,"PI");
180 unsigned long long pgp_count = parse(s,"Pc");
181 unsigned long long max_pgp_count = parse(s,"Pm");
182 unsigned long long obj_count = parse(s,"Oc");
183 unsigned long long max_obj_count = parse(s,"Om");
184 unsigned long long objnode_count = parse(s,"Nc");
185 unsigned long long max_objnode_count = parse(s,"Nm");
186 unsigned long long good_puts = parse(s,"ps");
187 unsigned long long puts = parse(s,"pt");
188 unsigned long long no_mem_puts = parse(s,"px");
189 unsigned long long dup_puts_flushed = parse(s,"pd");
190 unsigned long long dup_puts_replaced = parse(s,"pr");
191 unsigned long long found_gets = parse(s,"gs");
192 unsigned long long gets = parse(s,"gt");
193 unsigned long long flushs_found = parse(s,"fs");
194 unsigned long long flushs = parse(s,"ft");
195 unsigned long long flush_objs_found = parse(s,"os");
196 unsigned long long flush_objs = parse(s,"ot");
198 parse_string(s,"PT",pool_type,2);
199 printf("domid%lu,id%lu[%s]:pgp=%llu(max=%llu) obj=%llu(%llu) "
200 "objnode=%llu(%llu) puts=%llu/%llu/%llu(dup=%llu/%llu) "
201 "gets=%llu/%llu(%llu%%) "
202 "flush=%llu/%llu flobj=%llu/%llu\n",
203 cli_id, pool_id, pool_type,
204 pgp_count, max_pgp_count, obj_count, max_obj_count,
205 objnode_count, max_objnode_count,
206 good_puts, puts, no_mem_puts,
207 dup_puts_flushed, dup_puts_replaced,
208 found_gets, gets,
209 gets ? (found_gets*100LL)/gets : 0,
210 flushs_found, flushs, flush_objs_found, flush_objs);
212 }
214 void parse_shared_pool(char *s)
215 {
216 char pool_type[3];
217 char buf[BUFSIZE];
218 unsigned long pool_id = parse(s,"PI");
219 unsigned long long uid0 = parse(s,"U0");
220 unsigned long long uid1 = parse(s,"U1");
221 unsigned long long pgp_count = parse(s,"Pc");
222 unsigned long long max_pgp_count = parse(s,"Pm");
223 unsigned long long obj_count = parse(s,"Oc");
224 unsigned long long max_obj_count = parse(s,"Om");
225 unsigned long long objnode_count = parse(s,"Nc");
226 unsigned long long max_objnode_count = parse(s,"Nm");
227 unsigned long long good_puts = parse(s,"ps");
228 unsigned long long puts = parse(s,"pt");
229 unsigned long long no_mem_puts = parse(s,"px");
230 unsigned long long dup_puts_flushed = parse(s,"pd");
231 unsigned long long dup_puts_replaced = parse(s,"pr");
232 unsigned long long found_gets = parse(s,"gs");
233 unsigned long long gets = parse(s,"gt");
234 unsigned long long flushs_found = parse(s,"fs");
235 unsigned long long flushs = parse(s,"ft");
236 unsigned long long flush_objs_found = parse(s,"os");
237 unsigned long long flush_objs = parse(s,"ot");
239 parse_string(s,"PT",pool_type,2);
240 parse_sharers(s,"SC",buf,BUFSIZE);
241 printf("poolid=%lu[%s] uuid=%llu.%llu, shared-by:%s: "
242 "pgp=%llu(max=%llu) obj=%llu(%llu) "
243 "objnode=%llu(%llu) puts=%llu/%llu/%llu(dup=%llu/%llu) "
244 "gets=%llu/%llu(%llu%%) "
245 "flush=%llu/%llu flobj=%llu/%llu\n",
246 pool_id, pool_type, uid0, uid1, buf,
247 pgp_count, max_pgp_count, obj_count, max_obj_count,
248 objnode_count, max_objnode_count,
249 good_puts, puts, no_mem_puts,
250 dup_puts_flushed, dup_puts_replaced,
251 found_gets, gets,
252 gets ? (found_gets*100LL)/gets : 0,
253 flushs_found, flushs, flush_objs_found, flush_objs);
254 }
256 int main(int ac, char **av)
257 {
258 char *p, c;
259 char buf[BUFSIZE];
261 while ( (p = fgets(buf,BUFSIZE,stdin)) != NULL )
262 {
263 c = *p++;
264 if ( *p++ != '=' )
265 continue;
266 switch ( c )
267 {
268 case 'G':
269 parse_global(p);
270 break;
271 case 'T':
272 parse_time_stats(p);
273 break;
274 case 'C':
275 parse_client(p);
276 break;
277 case 'P':
278 parse_pool(p);
279 break;
280 case 'S':
281 parse_shared_pool(p);
282 break;
283 default:
284 continue;
285 }
286 }
287 return 0;
288 }