Sat Oct 15 12:14:00 2016 UTC ()
reduce the affinity column to just 5 chars for compact list


(jdolecek)
diff -r1.4 -r1.5 src/usr.sbin/intrctl/intrctl.c

cvs diff -r1.4 -r1.5 src/usr.sbin/intrctl/intrctl.c (switch to unified diff)

--- src/usr.sbin/intrctl/intrctl.c 2016/10/15 12:06:27 1.4
+++ src/usr.sbin/intrctl/intrctl.c 2016/10/15 12:14:00 1.5
@@ -1,342 +1,342 @@ @@ -1,342 +1,342 @@
1/* $NetBSD: intrctl.c,v 1.4 2016/10/15 12:06:27 jdolecek Exp $ */ 1/* $NetBSD: intrctl.c,v 1.5 2016/10/15 12:14:00 jdolecek Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2015 Internet Initiative Japan Inc. 4 * Copyright (c) 2015 Internet Initiative Japan Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__RCSID("$NetBSD: intrctl.c,v 1.4 2016/10/15 12:06:27 jdolecek Exp $"); 30__RCSID("$NetBSD: intrctl.c,v 1.5 2016/10/15 12:14:00 jdolecek Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/sysctl.h> 33#include <sys/sysctl.h>
34#include <sys/intrio.h> 34#include <sys/intrio.h>
35#include <sys/types.h> 35#include <sys/types.h>
36 36
37#include <err.h> 37#include <err.h>
38#include <errno.h> 38#include <errno.h>
39#include <fcntl.h> 39#include <fcntl.h>
40#include <limits.h> 40#include <limits.h>
41#include <paths.h> 41#include <paths.h>
42#include <sched.h> 42#include <sched.h>
43#include <stdint.h> 43#include <stdint.h>
44#include <stdio.h> 44#include <stdio.h>
45#include <stdlib.h> 45#include <stdlib.h>
46#include <string.h> 46#include <string.h>
47#include <unistd.h> 47#include <unistd.h>
48 48
49#include "intrctl_io.h" 49#include "intrctl_io.h"
50 50
51__dead static void usage(void); 51__dead static void usage(void);
52 52
53int verbose; 53int verbose;
54 54
55static void intrctl_list(int, char **); 55static void intrctl_list(int, char **);
56static void intrctl_affinity(int, char **); 56static void intrctl_affinity(int, char **);
57static void intrctl_intr(int, char **); 57static void intrctl_intr(int, char **);
58static void intrctl_nointr(int, char **); 58static void intrctl_nointr(int, char **);
59 59
60static struct cmdtab { 60static struct cmdtab {
61 const char *label; 61 const char *label;
62 void (*func)(int, char **); 62 void (*func)(int, char **);
63} const intrctl_cmdtab[] = { 63} const intrctl_cmdtab[] = {
64 { "list", intrctl_list }, 64 { "list", intrctl_list },
65 { "affinity", intrctl_affinity }, 65 { "affinity", intrctl_affinity },
66 { "intr", intrctl_intr }, 66 { "intr", intrctl_intr },
67 { "nointr", intrctl_nointr }, 67 { "nointr", intrctl_nointr },
68 { NULL, NULL }, 68 { NULL, NULL },
69}; 69};
70 70
71int 71int
72main(int argc, char **argv) 72main(int argc, char **argv)
73{ 73{
74 const struct cmdtab *ct; 74 const struct cmdtab *ct;
75 char *cmdname; 75 char *cmdname;
76 76
77 if (argc < 2) 77 if (argc < 2)
78 usage(); 78 usage();
79 79
80 cmdname = argv[1]; 80 cmdname = argv[1];
81 argv += 1; 81 argv += 1;
82 argc -= 1; 82 argc -= 1;
83 83
84 for (ct = intrctl_cmdtab; ct->label != NULL; ct++) { 84 for (ct = intrctl_cmdtab; ct->label != NULL; ct++) {
85 if (strcmp(cmdname, ct->label) == 0) { 85 if (strcmp(cmdname, ct->label) == 0) {
86 break; 86 break;
87 } 87 }
88 } 88 }
89 if (ct->label == NULL) 89 if (ct->label == NULL)
90 errx(EXIT_FAILURE, "unknown command ``%s''", cmdname); 90 errx(EXIT_FAILURE, "unknown command ``%s''", cmdname);
91 91
92 (*ct->func)(argc, argv); 92 (*ct->func)(argc, argv);
93 exit(EXIT_SUCCESS); 93 exit(EXIT_SUCCESS);
94 /* NOTREACHED */ 94 /* NOTREACHED */
95} 95}
96 96
97static void 97static void
98usage(void) 98usage(void)
99{ 99{
100 const char *progname = getprogname(); 100 const char *progname = getprogname();
101 101
102 fprintf(stderr, "usage: %s list [-c]\n", progname); 102 fprintf(stderr, "usage: %s list [-c]\n", progname);
103 fprintf(stderr, " %s affinity -i interrupt_name -c cpu_index\n", progname); 103 fprintf(stderr, " %s affinity -i interrupt_name -c cpu_index\n", progname);
104 fprintf(stderr, " %s intr -c cpu_index\n", progname); 104 fprintf(stderr, " %s intr -c cpu_index\n", progname);
105 fprintf(stderr, " %s nointr -c cpu_index\n", progname); 105 fprintf(stderr, " %s nointr -c cpu_index\n", progname);
106 exit(EXIT_FAILURE); 106 exit(EXIT_FAILURE);
107 /* NOTREACHED */ 107 /* NOTREACHED */
108} 108}
109 109
110static int intrctl_io_alloc_retry_count = 4; 110static int intrctl_io_alloc_retry_count = 4;
111 111
112static void 112static void
113intrctl_list(int argc, char **argv) 113intrctl_list(int argc, char **argv)
114{ 114{
115 char buf[64]; 115 char buf[64];
116 struct intrio_list_line *illine; 116 struct intrio_list_line *illine;
117 int i, ncpus, *cpucol; 117 int i, ncpus, *cpucol;
118 void *handle; 118 void *handle;
119 size_t intridlen; 119 size_t intridlen;
120 int compact = 0; 120 int compact = 0;
121 char ch; 121 char ch;
122 122
123 while ((ch = getopt(argc, argv, "c")) != -1) { 123 while ((ch = getopt(argc, argv, "c")) != -1) {
124 switch (ch) { 124 switch (ch) {
125 case 'c': 125 case 'c':
126 compact = 1; 126 compact = 1;
127 break; 127 break;
128 default: 128 default:
129 usage(); 129 usage();
130 } 130 }
131 } 131 }
132 132
133 handle = intrctl_io_alloc(intrctl_io_alloc_retry_count); 133 handle = intrctl_io_alloc(intrctl_io_alloc_retry_count);
134 if (handle == NULL) 134 if (handle == NULL)
135 err(EXIT_FAILURE, "intrctl_io_alloc"); 135 err(EXIT_FAILURE, "intrctl_io_alloc");
136 136
137 /* calc columns */ 137 /* calc columns */
138 ncpus = intrctl_io_ncpus(handle); 138 ncpus = intrctl_io_ncpus(handle);
139 intridlen = strlen("interrupt id"); 139 intridlen = strlen("interrupt id");
140 for (illine = intrctl_io_firstline(handle); illine != NULL; 140 for (illine = intrctl_io_firstline(handle); illine != NULL;
141 illine = intrctl_io_nextline(handle, illine)) { 141 illine = intrctl_io_nextline(handle, illine)) {
142 size_t len = strlen(illine->ill_intrid); 142 size_t len = strlen(illine->ill_intrid);
143 if (intridlen < len) 143 if (intridlen < len)
144 intridlen = len; 144 intridlen = len;
145 } 145 }
146 146
147 cpucol = malloc(sizeof(*cpucol) * (size_t)ncpus); 147 cpucol = malloc(sizeof(*cpucol) * (size_t)ncpus);
148 if (cpucol == NULL) 148 if (cpucol == NULL)
149 err(EXIT_FAILURE, "malloc"); 149 err(EXIT_FAILURE, "malloc");
150 for (i = 0; i < ncpus; i++) { 150 for (i = 0; i < ncpus; i++) {
151 snprintf(buf, sizeof(buf), "CPU%u", i); 151 snprintf(buf, sizeof(buf), "CPU%u", i);
152 cpucol[i] = strlen(buf); 152 cpucol[i] = strlen(buf);
153 } 153 }
154 for (illine = intrctl_io_firstline(handle); illine != NULL; 154 for (illine = intrctl_io_firstline(handle); illine != NULL;
155 illine = intrctl_io_nextline(handle, illine)) { 155 illine = intrctl_io_nextline(handle, illine)) {
156 for (i = 0; i < ncpus; i++) { 156 for (i = 0; i < ncpus; i++) {
157 int len; 157 int len;
158 snprintf(buf, sizeof(buf), "%" PRIu64, 158 snprintf(buf, sizeof(buf), "%" PRIu64,
159 illine->ill_cpu[i].illc_count); 159 illine->ill_cpu[i].illc_count);
160 len = (int)strlen(buf); 160 len = (int)strlen(buf);
161 if (cpucol[i] < len) 161 if (cpucol[i] < len)
162 cpucol[i] = len; 162 cpucol[i] = len;
163 } 163 }
164 } 164 }
165 165
166 /* header */ 166 /* header */
167 printf("%-*s", (int)intridlen, "interrupt id"); 167 printf("%-*s", (int)intridlen, "interrupt id");
168 if (compact) { 168 if (compact) {
169 printf(" %20s ", "total"); 169 printf(" %20s ", "total");
170 printf(" %20s ", "affinity"); 170 printf(" %5s ", "aff");
171 } else { 171 } else {
172 for (i = 0; i < ncpus; i++) { 172 for (i = 0; i < ncpus; i++) {
173 snprintf(buf, sizeof(buf), "CPU%u", i); 173 snprintf(buf, sizeof(buf), "CPU%u", i);
174 printf("%*s ", cpucol[i], buf); 174 printf("%*s ", cpucol[i], buf);
175 } 175 }
176 } 176 }
177 printf("device name(s)\n"); 177 printf("device name(s)\n");
178 178
179 /* body */ 179 /* body */
180 for (illine = intrctl_io_firstline(handle); illine != NULL; 180 for (illine = intrctl_io_firstline(handle); illine != NULL;
181 illine = intrctl_io_nextline(handle, illine)) { 181 illine = intrctl_io_nextline(handle, illine)) {
182 struct intrio_list_line_cpu *illc; 182 struct intrio_list_line_cpu *illc;
183 183
184 printf("%-*s ", (int)intridlen, illine->ill_intrid); 184 printf("%-*s ", (int)intridlen, illine->ill_intrid);
185 if (compact) { 185 if (compact) {
186 uint64_t total = 0; 186 uint64_t total = 0;
187 char *affinity, *oaffinity = NULL; 187 char *affinity, *oaffinity = NULL;
188 for (i = 0; i < ncpus; i++) { 188 for (i = 0; i < ncpus; i++) {
189 illc = &illine->ill_cpu[i]; 189 illc = &illine->ill_cpu[i];
190 total += illc->illc_count; 190 total += illc->illc_count;
191 if (illc->illc_assigned) { 191 if (illc->illc_assigned) {
192 asprintf(&affinity, "%s%s%d", 192 asprintf(&affinity, "%s%s%d",
193 oaffinity ? oaffinity : "", 193 oaffinity ? oaffinity : "",
194 oaffinity ? ", " : "", 194 oaffinity ? ", " : "",
195 i); 195 i);
196 if (oaffinity) 196 if (oaffinity)
197 free(oaffinity); 197 free(oaffinity);
198 oaffinity = affinity; 198 oaffinity = affinity;
199 } 199 }
200 } 200 }
201 printf("%20" PRIu64 " ", total); 201 printf("%20" PRIu64 " ", total);
202 printf("%20s ", affinity ? affinity : "none"); 202 printf("%5s ", affinity ? affinity : "none");
203 free(affinity); 203 free(affinity);
204 } else { 204 } else {
205 for (i = 0; i < ncpus; i++) { 205 for (i = 0; i < ncpus; i++) {
206 illc = &illine->ill_cpu[i]; 206 illc = &illine->ill_cpu[i];
207 printf("%*" PRIu64 "%c ", cpucol[i], illc->illc_count, 207 printf("%*" PRIu64 "%c ", cpucol[i], illc->illc_count,
208 illc->illc_assigned ? '*' : ' '); 208 illc->illc_assigned ? '*' : ' ');
209 } 209 }
210 } 210 }
211 printf("%s\n", illine->ill_xname); 211 printf("%s\n", illine->ill_xname);
212 } 212 }
213 213
214 free(cpucol); 214 free(cpucol);
215 intrctl_io_free(handle); 215 intrctl_io_free(handle);
216} 216}
217 217
218static void 218static void
219intrctl_affinity(int argc, char **argv) 219intrctl_affinity(int argc, char **argv)
220{ 220{
221 struct intrio_set iset; 221 struct intrio_set iset;
222 cpuset_t *cpuset; 222 cpuset_t *cpuset;
223 unsigned long index; 223 unsigned long index;
224 int ch, error; 224 int ch, error;
225 225
226 index = ULONG_MAX; 226 index = ULONG_MAX;
227 memset(&iset.intrid, 0, sizeof(iset.intrid)); 227 memset(&iset.intrid, 0, sizeof(iset.intrid));
228 228
229 while ((ch = getopt(argc, argv, "c:i:")) != -1) { 229 while ((ch = getopt(argc, argv, "c:i:")) != -1) {
230 switch (ch) { 230 switch (ch) {
231 case 'c': 231 case 'c':
232 index = strtoul(optarg, NULL, 10); 232 index = strtoul(optarg, NULL, 10);
233 break; 233 break;
234 case 'i': 234 case 'i':
235 if (strnlen(optarg, ARG_MAX) > INTRIDBUF) 235 if (strnlen(optarg, ARG_MAX) > INTRIDBUF)
236 usage(); 236 usage();
237 strlcpy(iset.intrid, optarg, INTRIDBUF); 237 strlcpy(iset.intrid, optarg, INTRIDBUF);
238 break; 238 break;
239 default: 239 default:
240 usage(); 240 usage();
241 } 241 }
242 } 242 }
243 243
244 if (iset.intrid[0] == '\0' || index == ULONG_MAX) 244 if (iset.intrid[0] == '\0' || index == ULONG_MAX)
245 usage(); 245 usage();
246 246
247 if (index >= (u_long)sysconf(_SC_NPROCESSORS_CONF)) 247 if (index >= (u_long)sysconf(_SC_NPROCESSORS_CONF))
248 err(EXIT_FAILURE, "invalid cpu index"); 248 err(EXIT_FAILURE, "invalid cpu index");
249 249
250 cpuset = cpuset_create(); 250 cpuset = cpuset_create();
251 if (cpuset == NULL) 251 if (cpuset == NULL)
252 err(EXIT_FAILURE, "create_cpuset()"); 252 err(EXIT_FAILURE, "create_cpuset()");
253 253
254 cpuset_zero(cpuset); 254 cpuset_zero(cpuset);
255 cpuset_set(index, cpuset); 255 cpuset_set(index, cpuset);
256 iset.cpuset = cpuset; 256 iset.cpuset = cpuset;
257 iset.cpuset_size = cpuset_size(cpuset); 257 iset.cpuset_size = cpuset_size(cpuset);
258 error = sysctlbyname("kern.intr.affinity", NULL, NULL, &iset, sizeof(iset)); 258 error = sysctlbyname("kern.intr.affinity", NULL, NULL, &iset, sizeof(iset));
259 cpuset_destroy(cpuset); 259 cpuset_destroy(cpuset);
260 if (error < 0) 260 if (error < 0)
261 err(EXIT_FAILURE, "sysctl kern.intr.affinity"); 261 err(EXIT_FAILURE, "sysctl kern.intr.affinity");
262} 262}
263 263
264static void 264static void
265intrctl_intr(int argc, char **argv) 265intrctl_intr(int argc, char **argv)
266{ 266{
267 struct intrio_set iset; 267 struct intrio_set iset;
268 cpuset_t *cpuset; 268 cpuset_t *cpuset;
269 unsigned long index; 269 unsigned long index;
270 int ch, error; 270 int ch, error;
271 271
272 index = ULONG_MAX; 272 index = ULONG_MAX;
273 273
274 while ((ch = getopt(argc, argv, "c:")) != -1) { 274 while ((ch = getopt(argc, argv, "c:")) != -1) {
275 switch (ch) { 275 switch (ch) {
276 case 'c': 276 case 'c':
277 index = strtoul(optarg, NULL, 10); 277 index = strtoul(optarg, NULL, 10);
278 break; 278 break;
279 default: 279 default:
280 usage(); 280 usage();
281 } 281 }
282 } 282 }
283 283
284 if (index == ULONG_MAX) 284 if (index == ULONG_MAX)
285 usage(); 285 usage();
286 286
287 if (index >= (u_long)sysconf(_SC_NPROCESSORS_CONF)) 287 if (index >= (u_long)sysconf(_SC_NPROCESSORS_CONF))
288 err(EXIT_FAILURE, "invalid cpu index"); 288 err(EXIT_FAILURE, "invalid cpu index");
289 289
290 cpuset = cpuset_create(); 290 cpuset = cpuset_create();
291 if (cpuset == NULL) 291 if (cpuset == NULL)
292 err(EXIT_FAILURE, "create_cpuset()"); 292 err(EXIT_FAILURE, "create_cpuset()");
293 293
294 cpuset_zero(cpuset); 294 cpuset_zero(cpuset);
295 cpuset_set(index, cpuset); 295 cpuset_set(index, cpuset);
296 iset.cpuset = cpuset; 296 iset.cpuset = cpuset;
297 iset.cpuset_size = cpuset_size(cpuset); 297 iset.cpuset_size = cpuset_size(cpuset);
298 error = sysctlbyname("kern.intr.intr", NULL, NULL, &iset, sizeof(iset)); 298 error = sysctlbyname("kern.intr.intr", NULL, NULL, &iset, sizeof(iset));
299 cpuset_destroy(cpuset); 299 cpuset_destroy(cpuset);
300 if (error < 0) 300 if (error < 0)
301 err(EXIT_FAILURE, "sysctl kern.intr.intr"); 301 err(EXIT_FAILURE, "sysctl kern.intr.intr");
302} 302}
303 303
304static void 304static void
305intrctl_nointr(int argc, char **argv) 305intrctl_nointr(int argc, char **argv)
306{ 306{
307 struct intrio_set iset; 307 struct intrio_set iset;
308 cpuset_t *cpuset; 308 cpuset_t *cpuset;
309 unsigned long index; 309 unsigned long index;
310 int ch, error; 310 int ch, error;
311 311
312 index = ULONG_MAX; 312 index = ULONG_MAX;
313 313
314 while ((ch = getopt(argc, argv, "c:")) != -1) { 314 while ((ch = getopt(argc, argv, "c:")) != -1) {
315 switch (ch) { 315 switch (ch) {
316 case 'c': 316 case 'c':
317 index = strtoul(optarg, NULL, 10); 317 index = strtoul(optarg, NULL, 10);
318 break; 318 break;
319 default: 319 default:
320 usage(); 320 usage();
321 } 321 }
322 } 322 }
323 323
324 if (index == ULONG_MAX) 324 if (index == ULONG_MAX)
325 usage(); 325 usage();
326 326
327 if (index >= (u_long)sysconf(_SC_NPROCESSORS_CONF)) 327 if (index >= (u_long)sysconf(_SC_NPROCESSORS_CONF))
328 err(EXIT_FAILURE, "invalid cpu index"); 328 err(EXIT_FAILURE, "invalid cpu index");
329 329
330 cpuset = cpuset_create(); 330 cpuset = cpuset_create();
331 if (cpuset == NULL) 331 if (cpuset == NULL)
332 err(EXIT_FAILURE, "create_cpuset()"); 332 err(EXIT_FAILURE, "create_cpuset()");
333 333
334 cpuset_zero(cpuset); 334 cpuset_zero(cpuset);
335 cpuset_set(index, cpuset); 335 cpuset_set(index, cpuset);
336 iset.cpuset = cpuset; 336 iset.cpuset = cpuset;
337 iset.cpuset_size = cpuset_size(cpuset); 337 iset.cpuset_size = cpuset_size(cpuset);
338 error = sysctlbyname("kern.intr.nointr", NULL, NULL, &iset, sizeof(iset)); 338 error = sysctlbyname("kern.intr.nointr", NULL, NULL, &iset, sizeof(iset));
339 cpuset_destroy(cpuset); 339 cpuset_destroy(cpuset);
340 if (error < 0) 340 if (error < 0)
341 err(EXIT_FAILURE, "sysctl kern.intr.nointr"); 341 err(EXIT_FAILURE, "sysctl kern.intr.nointr");
342} 342}