aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/accounting/getdelays.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/accounting/getdelays.c')
-rw-r--r--Documentation/accounting/getdelays.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index 6e25c2659e0a..f6318f6d7baf 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -21,6 +21,7 @@
21#include <sys/types.h> 21#include <sys/types.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/socket.h> 23#include <sys/socket.h>
24#include <sys/wait.h>
24#include <signal.h> 25#include <signal.h>
25 26
26#include <linux/genetlink.h> 27#include <linux/genetlink.h>
@@ -176,6 +177,8 @@ static int get_family_id(int sd)
176 rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY, 177 rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
177 CTRL_ATTR_FAMILY_NAME, (void *)name, 178 CTRL_ATTR_FAMILY_NAME, (void *)name,
178 strlen(TASKSTATS_GENL_NAME)+1); 179 strlen(TASKSTATS_GENL_NAME)+1);
180 if (rc < 0)
181 return 0; /* sendto() failure? */
179 182
180 rep_len = recv(sd, &ans, sizeof(ans), 0); 183 rep_len = recv(sd, &ans, sizeof(ans), 0);
181 if (ans.n.nlmsg_type == NLMSG_ERROR || 184 if (ans.n.nlmsg_type == NLMSG_ERROR ||
@@ -190,30 +193,37 @@ static int get_family_id(int sd)
190 return id; 193 return id;
191} 194}
192 195
196#define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))
197
193static void print_delayacct(struct taskstats *t) 198static void print_delayacct(struct taskstats *t)
194{ 199{
195 printf("\n\nCPU %15s%15s%15s%15s\n" 200 printf("\n\nCPU %15s%15s%15s%15s%15s\n"
196 " %15llu%15llu%15llu%15llu\n" 201 " %15llu%15llu%15llu%15llu%15.3fms\n"
197 "IO %15s%15s\n" 202 "IO %15s%15s%15s\n"
198 " %15llu%15llu\n" 203 " %15llu%15llu%15llums\n"
199 "SWAP %15s%15s\n" 204 "SWAP %15s%15s%15s\n"
200 " %15llu%15llu\n" 205 " %15llu%15llu%15llums\n"
201 "RECLAIM %12s%15s\n" 206 "RECLAIM %12s%15s%15s\n"
202 " %15llu%15llu\n", 207 " %15llu%15llu%15llums\n",
203 "count", "real total", "virtual total", "delay total", 208 "count", "real total", "virtual total",
209 "delay total", "delay average",
204 (unsigned long long)t->cpu_count, 210 (unsigned long long)t->cpu_count,
205 (unsigned long long)t->cpu_run_real_total, 211 (unsigned long long)t->cpu_run_real_total,
206 (unsigned long long)t->cpu_run_virtual_total, 212 (unsigned long long)t->cpu_run_virtual_total,
207 (unsigned long long)t->cpu_delay_total, 213 (unsigned long long)t->cpu_delay_total,
208 "count", "delay total", 214 average_ms((double)t->cpu_delay_total, t->cpu_count),
215 "count", "delay total", "delay average",
209 (unsigned long long)t->blkio_count, 216 (unsigned long long)t->blkio_count,
210 (unsigned long long)t->blkio_delay_total, 217 (unsigned long long)t->blkio_delay_total,
211 "count", "delay total", 218 average_ms(t->blkio_delay_total, t->blkio_count),
219 "count", "delay total", "delay average",
212 (unsigned long long)t->swapin_count, 220 (unsigned long long)t->swapin_count,
213 (unsigned long long)t->swapin_delay_total, 221 (unsigned long long)t->swapin_delay_total,
214 "count", "delay total", 222 average_ms(t->swapin_delay_total, t->swapin_count),
223 "count", "delay total", "delay average",
215 (unsigned long long)t->freepages_count, 224 (unsigned long long)t->freepages_count,
216 (unsigned long long)t->freepages_delay_total); 225 (unsigned long long)t->freepages_delay_total,
226 average_ms(t->freepages_delay_total, t->freepages_count));
217} 227}
218 228
219static void task_context_switch_counts(struct taskstats *t) 229static void task_context_switch_counts(struct taskstats *t)
@@ -266,11 +276,13 @@ int main(int argc, char *argv[])
266 int containerset = 0; 276 int containerset = 0;
267 char containerpath[1024]; 277 char containerpath[1024];
268 int cfd = 0; 278 int cfd = 0;
279 int forking = 0;
280 sigset_t sigset;
269 281
270 struct msgtemplate msg; 282 struct msgtemplate msg;
271 283
272 while (1) { 284 while (!forking) {
273 c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:"); 285 c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:");
274 if (c < 0) 286 if (c < 0)
275 break; 287 break;
276 288
@@ -319,6 +331,28 @@ int main(int argc, char *argv[])
319 err(1, "Invalid pid\n"); 331 err(1, "Invalid pid\n");
320 cmd_type = TASKSTATS_CMD_ATTR_PID; 332 cmd_type = TASKSTATS_CMD_ATTR_PID;
321 break; 333 break;
334 case 'c':
335
336 /* Block SIGCHLD for sigwait() later */
337 if (sigemptyset(&sigset) == -1)
338 err(1, "Failed to empty sigset");
339 if (sigaddset(&sigset, SIGCHLD))
340 err(1, "Failed to set sigchld in sigset");
341 sigprocmask(SIG_BLOCK, &sigset, NULL);
342
343 /* fork/exec a child */
344 tid = fork();
345 if (tid < 0)
346 err(1, "Fork failed\n");
347 if (tid == 0)
348 if (execvp(argv[optind - 1],
349 &argv[optind - 1]) < 0)
350 exit(-1);
351
352 /* Set the command type and avoid further processing */
353 cmd_type = TASKSTATS_CMD_ATTR_PID;
354 forking = 1;
355 break;
322 case 'v': 356 case 'v':
323 printf("debug on\n"); 357 printf("debug on\n");
324 dbg = 1; 358 dbg = 1;
@@ -370,6 +404,15 @@ int main(int argc, char *argv[])
370 goto err; 404 goto err;
371 } 405 }
372 406
407 /*
408 * If we forked a child, wait for it to exit. Cannot use waitpid()
409 * as all the delicious data would be reaped as part of the wait
410 */
411 if (tid && forking) {
412 int sig_received;
413 sigwait(&sigset, &sig_received);
414 }
415
373 if (tid) { 416 if (tid) {
374 rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, 417 rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
375 cmd_type, &tid, sizeof(__u32)); 418 cmd_type, &tid, sizeof(__u32));
@@ -399,8 +442,6 @@ int main(int argc, char *argv[])
399 } 442 }
400 443
401 do { 444 do {
402 int i;
403
404 rep_len = recv(nl_sd, &msg, sizeof(msg), 0); 445 rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
405 PRINTF("received %d bytes\n", rep_len); 446 PRINTF("received %d bytes\n", rep_len);
406 447
@@ -425,7 +466,6 @@ int main(int argc, char *argv[])
425 466
426 na = (struct nlattr *) GENLMSG_DATA(&msg); 467 na = (struct nlattr *) GENLMSG_DATA(&msg);
427 len = 0; 468 len = 0;
428 i = 0;
429 while (len < rep_len) { 469 while (len < rep_len) {
430 len += NLA_ALIGN(na->nla_len); 470 len += NLA_ALIGN(na->nla_len);
431 switch (na->nla_type) { 471 switch (na->nla_type) {
@@ -482,6 +522,7 @@ int main(int argc, char *argv[])
482 default: 522 default:
483 fprintf(stderr, "Unknown nla_type %d\n", 523 fprintf(stderr, "Unknown nla_type %d\n",
484 na->nla_type); 524 na->nla_type);
525 case TASKSTATS_TYPE_NULL:
485 break; 526 break;
486 } 527 }
487 na = (struct nlattr *) (GENLMSG_DATA(&msg) + len); 528 na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);