diff options
Diffstat (limited to 'Documentation/accounting')
-rw-r--r-- | Documentation/accounting/getdelays.c | 66 | ||||
-rw-r--r-- | Documentation/accounting/taskstats.txt | 10 |
2 files changed, 52 insertions, 24 deletions
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index b11792abd6b..e9126e794ed 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c @@ -7,6 +7,8 @@ * Copyright (C) Balbir Singh, IBM Corp. 2006 * Copyright (c) Jay Lan, SGI. 2006 * + * Compile with + * gcc -I/usr/src/linux/include getdelays.c -o getdelays */ #include <stdio.h> @@ -35,13 +37,20 @@ #define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN)) #define NLA_PAYLOAD(len) (len - NLA_HDRLEN) -#define err(code, fmt, arg...) do { printf(fmt, ##arg); exit(code); } while (0) -int done = 0; -int rcvbufsz=0; - - char name[100]; -int dbg=0, print_delays=0; +#define err(code, fmt, arg...) \ + do { \ + fprintf(stderr, fmt, ##arg); \ + exit(code); \ + } while (0) + +int done; +int rcvbufsz; +char name[100]; +int dbg; +int print_delays; +int print_io_accounting; __u64 stime, utime; + #define PRINTF(fmt, arg...) { \ if (dbg) { \ printf(fmt, ##arg); \ @@ -49,7 +58,7 @@ __u64 stime, utime; } /* Maximum size of response requested or message sent */ -#define MAX_MSG_SIZE 256 +#define MAX_MSG_SIZE 1024 /* Maximum number of cpus expected to be specified in a cpumask */ #define MAX_CPUS 32 /* Maximum length of pathname to log file */ @@ -78,8 +87,9 @@ static int create_nl_socket(int protocol) if (rcvbufsz) if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbufsz, sizeof(rcvbufsz)) < 0) { - printf("Unable to set socket rcv buf size to %d\n", - rcvbufsz); + fprintf(stderr, "Unable to set socket rcv buf size " + "to %d\n", + rcvbufsz); return -1; } @@ -186,6 +196,15 @@ void print_delayacct(struct taskstats *t) "count", "delay total", t->swapin_count, t->swapin_delay_total); } +void print_ioacct(struct taskstats *t) +{ + printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n", + t->ac_comm, + (unsigned long long)t->read_bytes, + (unsigned long long)t->write_bytes, + (unsigned long long)t->cancelled_write_bytes); +} + int main(int argc, char *argv[]) { int c, rc, rep_len, aggr_len, len2, cmd_type; @@ -208,7 +227,7 @@ int main(int argc, char *argv[]) struct msgtemplate msg; while (1) { - c = getopt(argc, argv, "dw:r:m:t:p:v:l"); + c = getopt(argc, argv, "diw:r:m:t:p:v:l"); if (c < 0) break; @@ -217,6 +236,10 @@ int main(int argc, char *argv[]) printf("print delayacct stats ON\n"); print_delays = 1; break; + case 'i': + printf("printing IO accounting\n"); + print_io_accounting = 1; + break; case 'w': strncpy(logfile, optarg, MAX_FILENAME); printf("write to file %s\n", logfile); @@ -238,14 +261,12 @@ int main(int argc, char *argv[]) if (!tid) err(1, "Invalid tgid\n"); cmd_type = TASKSTATS_CMD_ATTR_TGID; - print_delays = 1; break; case 'p': tid = atoi(optarg); if (!tid) err(1, "Invalid pid\n"); cmd_type = TASKSTATS_CMD_ATTR_PID; - print_delays = 1; break; case 'v': printf("debug on\n"); @@ -277,7 +298,7 @@ int main(int argc, char *argv[]) mypid = getpid(); id = get_family_id(nl_sd); if (!id) { - printf("Error getting family id, errno %d", errno); + fprintf(stderr, "Error getting family id, errno %d\n", errno); goto err; } PRINTF("family id %d\n", id); @@ -288,7 +309,7 @@ int main(int argc, char *argv[]) &cpumask, strlen(cpumask) + 1); PRINTF("Sent register cpumask, retval %d\n", rc); if (rc < 0) { - printf("error sending register cpumask\n"); + fprintf(stderr, "error sending register cpumask\n"); goto err; } } @@ -298,7 +319,7 @@ int main(int argc, char *argv[]) cmd_type, &tid, sizeof(__u32)); PRINTF("Sent pid/tgid, retval %d\n", rc); if (rc < 0) { - printf("error sending tid/tgid cmd\n"); + fprintf(stderr, "error sending tid/tgid cmd\n"); goto done; } } @@ -310,13 +331,15 @@ int main(int argc, char *argv[]) PRINTF("received %d bytes\n", rep_len); if (rep_len < 0) { - printf("nonfatal reply error: errno %d\n", errno); + fprintf(stderr, "nonfatal reply error: errno %d\n", + errno); continue; } if (msg.n.nlmsg_type == NLMSG_ERROR || !NLMSG_OK((&msg.n), rep_len)) { struct nlmsgerr *err = NLMSG_DATA(&msg); - printf("fatal reply error, errno %d\n", err->error); + fprintf(stderr, "fatal reply error, errno %d\n", + err->error); goto done; } @@ -356,6 +379,8 @@ int main(int argc, char *argv[]) count++; if (print_delays) print_delayacct((struct taskstats *) NLA_DATA(na)); + if (print_io_accounting) + print_ioacct((struct taskstats *) NLA_DATA(na)); if (fd) { if (write(fd, NLA_DATA(na), na->nla_len) < 0) { err(1,"write error\n"); @@ -365,7 +390,9 @@ int main(int argc, char *argv[]) goto done; break; default: - printf("Unknown nested nla_type %d\n", na->nla_type); + fprintf(stderr, "Unknown nested" + " nla_type %d\n", + na->nla_type); break; } len2 += NLA_ALIGN(na->nla_len); @@ -374,7 +401,8 @@ int main(int argc, char *argv[]) break; default: - printf("Unknown nla_type %d\n", na->nla_type); + fprintf(stderr, "Unknown nla_type %d\n", + na->nla_type); break; } na = (struct nlattr *) (GENLMSG_DATA(&msg) + len); diff --git a/Documentation/accounting/taskstats.txt b/Documentation/accounting/taskstats.txt index 92ebf29e904..ff06b738bb8 100644 --- a/Documentation/accounting/taskstats.txt +++ b/Documentation/accounting/taskstats.txt @@ -96,9 +96,9 @@ a) TASKSTATS_TYPE_AGGR_PID/TGID : attribute containing no payload but indicates a pid/tgid will be followed by some stats. b) TASKSTATS_TYPE_PID/TGID: attribute whose payload is the pid/tgid whose stats -is being returned. +are being returned. -c) TASKSTATS_TYPE_STATS: attribute with a struct taskstsats as payload. The +c) TASKSTATS_TYPE_STATS: attribute with a struct taskstats as payload. The same structure is used for both per-pid and per-tgid stats. 3. New message sent by kernel whenever a task exits. The payload consists of a @@ -122,12 +122,12 @@ of atomicity). However, maintaining per-process, in addition to per-task stats, within the kernel has space and time overheads. To address this, the taskstats code -accumalates each exiting task's statistics into a process-wide data structure. -When the last task of a process exits, the process level data accumalated also +accumulates each exiting task's statistics into a process-wide data structure. +When the last task of a process exits, the process level data accumulated also gets sent to userspace (along with the per-task data). When a user queries to get per-tgid data, the sum of all other live threads in -the group is added up and added to the accumalated total for previously exited +the group is added up and added to the accumulated total for previously exited threads of the same thread group. Extending taskstats |