Print this page
11493 aggr needs support for multiple pseudo rx groups
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/modules/mac/mac.c
+++ new/usr/src/cmd/mdb/common/modules/mac/mac.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright 2018 Joyent, Inc.
24 25 */
25 26
26 27 #include <sys/mdb_modapi.h>
27 28 #include <sys/types.h>
28 29 #include <inet/ip.h>
29 30 #include <inet/ip6.h>
30 31
31 32 #include <sys/mac.h>
32 33 #include <sys/mac_provider.h>
33 34 #include <sys/mac_client.h>
34 35 #include <sys/mac_client_impl.h>
35 36 #include <sys/mac_flow_impl.h>
36 37 #include <sys/mac_soft_ring.h>
37 38 #include <sys/mac_stat.h>
38 39
39 40 #define STRSIZE 64
40 41 #define MAC_RX_SRS_SIZE (MAX_RINGS_PER_GROUP * sizeof (uintptr_t))
41 42
42 43 #define LAYERED_WALKER_FOR_FLOW "flow_entry_cache"
43 44 #define LAYERED_WALKER_FOR_SRS "mac_srs_cache"
44 45 #define LAYERED_WALKER_FOR_RING "mac_ring_cache"
45 46 #define LAYERED_WALKER_FOR_GROUP "mac_impl_cache"
46 47
47 48 /* arguments passed to mac_flow dee-command */
48 49 #define MAC_FLOW_NONE 0x01
49 50 #define MAC_FLOW_ATTR 0x02
50 51 #define MAC_FLOW_PROP 0x04
51 52 #define MAC_FLOW_RX 0x08
52 53 #define MAC_FLOW_TX 0x10
53 54 #define MAC_FLOW_USER 0x20
54 55 #define MAC_FLOW_STATS 0x40
55 56 #define MAC_FLOW_MISC 0x80
56 57
57 58 /* arguments passed to mac_srs dee-command */
58 59 #define MAC_SRS_NONE 0x00
59 60 #define MAC_SRS_RX 0x01
60 61 #define MAC_SRS_TX 0x02
61 62 #define MAC_SRS_STAT 0x04
62 63 #define MAC_SRS_CPU 0x08
63 64 #define MAC_SRS_VERBOSE 0x10
64 65 #define MAC_SRS_INTR 0x20
65 66 #define MAC_SRS_RXSTAT (MAC_SRS_RX|MAC_SRS_STAT)
66 67 #define MAC_SRS_TXSTAT (MAC_SRS_TX|MAC_SRS_STAT)
67 68 #define MAC_SRS_RXCPU (MAC_SRS_RX|MAC_SRS_CPU)
68 69 #define MAC_SRS_TXCPU (MAC_SRS_TX|MAC_SRS_CPU)
69 70 #define MAC_SRS_RXCPUVERBOSE (MAC_SRS_RXCPU|MAC_SRS_VERBOSE)
70 71 #define MAC_SRS_TXCPUVERBOSE (MAC_SRS_TXCPU|MAC_SRS_VERBOSE)
71 72 #define MAC_SRS_RXINTR (MAC_SRS_RX|MAC_SRS_INTR)
72 73 #define MAC_SRS_TXINTR (MAC_SRS_TX|MAC_SRS_INTR)
73 74
74 75 /* arguments passed to mac_group dcmd */
75 76 #define MAC_GROUP_NONE 0x00
76 77 #define MAC_GROUP_RX 0x01
77 78 #define MAC_GROUP_TX 0x02
78 79 #define MAC_GROUP_UNINIT 0x04
79 80
80 81 static char *
81 82 mac_flow_proto2str(uint8_t protocol)
82 83 {
83 84 switch (protocol) {
84 85 case IPPROTO_TCP:
85 86 return ("tcp");
86 87 case IPPROTO_UDP:
87 88 return ("udp");
88 89 case IPPROTO_SCTP:
89 90 return ("sctp");
90 91 case IPPROTO_ICMP:
91 92 return ("icmp");
92 93 case IPPROTO_ICMPV6:
93 94 return ("icmpv6");
94 95 default:
95 96 return ("--");
96 97 }
97 98 }
98 99
99 100 static char *
100 101 mac_flow_priority2str(mac_priority_level_t prio)
101 102 {
102 103 switch (prio) {
103 104 case MPL_LOW:
104 105 return ("low");
105 106 case MPL_MEDIUM:
106 107 return ("medium");
107 108 case MPL_HIGH:
108 109 return ("high");
109 110 case MPL_RESET:
110 111 return ("reset");
111 112 default:
112 113 return ("--");
113 114 }
114 115 }
115 116
116 117 /*
117 118 * Convert bandwidth in bps to a string in Mbps.
118 119 */
119 120 static char *
120 121 mac_flow_bw2str(uint64_t bw, char *buf, ssize_t len)
121 122 {
122 123 int kbps, mbps;
123 124
124 125 kbps = (bw % 1000000)/1000;
125 126 mbps = bw/1000000;
126 127 if ((mbps == 0) && (kbps != 0))
127 128 mdb_snprintf(buf, len, "0.%03u", kbps);
128 129 else
129 130 mdb_snprintf(buf, len, "%5u", mbps);
130 131 return (buf);
131 132 }
132 133
133 134 static void
134 135 mac_flow_print_header(uint_t args)
135 136 {
136 137 switch (args) {
137 138 case MAC_FLOW_NONE:
138 139 mdb_printf("%?s %-20s %4s %?s %?s %-16s\n",
139 140 "", "", "LINK", "", "", "MIP");
140 141 mdb_printf("%<u>%?s %-20s %4s %?s %?s %-16s%</u>\n",
141 142 "ADDR", "FLOW NAME", "ID", "MCIP", "MIP", "NAME");
142 143 break;
143 144 case MAC_FLOW_ATTR:
144 145 mdb_printf("%<u>%?s %-32s %-7s %6s "
145 146 "%-9s %s%</u>\n",
146 147 "ADDR", "FLOW NAME", "PROTO", "PORT",
147 148 "DSFLD:MSK", "IPADDR");
148 149 break;
149 150 case MAC_FLOW_PROP:
150 151 mdb_printf("%<u>%?s %-32s %8s %9s%</u>\n",
151 152 "ADDR", "FLOW NAME", "MAXBW(M)", "PRIORITY");
152 153 break;
153 154 case MAC_FLOW_MISC:
154 155 mdb_printf("%<u>%?s %-24s %10s %10s "
155 156 "%20s %4s%</u>\n",
156 157 "ADDR", "FLOW NAME", "TYPE", "FLAGS",
157 158 "MATCH_FN", "ZONE");
158 159 break;
159 160 case MAC_FLOW_RX:
160 161 mdb_printf("%?s %-24s %3s %s\n", "", "", "SRS", "RX");
161 162 mdb_printf("%<u>%?s %-24s %3s %s%</u>\n",
162 163 "ADDR", "FLOW NAME", "CNT", "SRS");
163 164 break;
164 165 case MAC_FLOW_TX:
165 166 mdb_printf("%<u>%?s %-32s %?s %</u>\n",
166 167 "ADDR", "FLOW NAME", "TX_SRS");
167 168 break;
168 169 case MAC_FLOW_STATS:
169 170 mdb_printf("%<u>%?s %-32s %16s %16s%</u>\n",
170 171 "ADDR", "FLOW NAME", "RBYTES", "OBYTES");
171 172 break;
172 173 }
173 174 }
174 175
175 176 /*
176 177 * Display selected fields of the flow_entry_t structure
177 178 */
178 179 static int
179 180 mac_flow_dcmd_output(uintptr_t addr, uint_t flags, uint_t args)
180 181 {
181 182 static const mdb_bitmask_t flow_type_bits[] = {
182 183 {"P", FLOW_PRIMARY_MAC, FLOW_PRIMARY_MAC},
183 184 {"V", FLOW_VNIC_MAC, FLOW_VNIC_MAC},
184 185 {"M", FLOW_MCAST, FLOW_MCAST},
185 186 {"O", FLOW_OTHER, FLOW_OTHER},
186 187 {"U", FLOW_USER, FLOW_USER},
187 188 {"V", FLOW_VNIC, FLOW_VNIC},
188 189 {"NS", FLOW_NO_STATS, FLOW_NO_STATS},
189 190 { NULL, 0, 0 }
190 191 };
191 192 #define FLOW_MAX_TYPE (sizeof (flow_type_bits) / sizeof (mdb_bitmask_t))
192 193
193 194 static const mdb_bitmask_t flow_flag_bits[] = {
194 195 {"Q", FE_QUIESCE, FE_QUIESCE},
195 196 {"W", FE_WAITER, FE_WAITER},
196 197 {"T", FE_FLOW_TAB, FE_FLOW_TAB},
197 198 {"G", FE_G_FLOW_HASH, FE_G_FLOW_HASH},
198 199 {"I", FE_INCIPIENT, FE_INCIPIENT},
199 200 {"C", FE_CONDEMNED, FE_CONDEMNED},
200 201 {"NU", FE_UF_NO_DATAPATH, FE_UF_NO_DATAPATH},
201 202 {"NC", FE_MC_NO_DATAPATH, FE_MC_NO_DATAPATH},
202 203 { NULL, 0, 0 }
203 204 };
204 205 #define FLOW_MAX_FLAGS (sizeof (flow_flag_bits) / sizeof (mdb_bitmask_t))
205 206 flow_entry_t fe;
206 207 mac_client_impl_t mcip;
207 208 mac_impl_t mip;
208 209
209 210 if (mdb_vread(&fe, sizeof (fe), addr) == -1) {
210 211 mdb_warn("failed to read struct flow_entry_s at %p", addr);
211 212 return (DCMD_ERR);
212 213 }
213 214 if (args & MAC_FLOW_USER) {
214 215 args &= ~MAC_FLOW_USER;
215 216 if (fe.fe_type & FLOW_MCAST) {
216 217 if (DCMD_HDRSPEC(flags))
217 218 mac_flow_print_header(args);
218 219 return (DCMD_OK);
219 220 }
220 221 }
221 222 if (DCMD_HDRSPEC(flags))
222 223 mac_flow_print_header(args);
223 224 bzero(&mcip, sizeof (mcip));
224 225 bzero(&mip, sizeof (mip));
225 226 if (fe.fe_mcip != NULL && mdb_vread(&mcip, sizeof (mcip),
226 227 (uintptr_t)fe.fe_mcip) == sizeof (mcip)) {
227 228 (void) mdb_vread(&mip, sizeof (mip), (uintptr_t)mcip.mci_mip);
228 229 }
229 230 switch (args) {
230 231 case MAC_FLOW_NONE: {
231 232 mdb_printf("%?p %-20s %4d %?p "
232 233 "%?p %-16s\n",
233 234 addr, fe.fe_flow_name, fe.fe_link_id, fe.fe_mcip,
234 235 mcip.mci_mip, mip.mi_name);
235 236 break;
236 237 }
237 238 case MAC_FLOW_ATTR: {
238 239 struct in_addr in4;
239 240 uintptr_t desc_addr;
240 241 flow_desc_t fdesc;
241 242
242 243 desc_addr = addr + OFFSETOF(flow_entry_t, fe_flow_desc);
243 244 if (mdb_vread(&fdesc, sizeof (fdesc), desc_addr) == -1) {
244 245 mdb_warn("failed to read struct flow_description at %p",
245 246 desc_addr);
246 247 return (DCMD_ERR);
247 248 }
248 249 mdb_printf("%?p %-32s "
249 250 "%-7s %6d "
250 251 "%4d:%-4d ",
251 252 addr, fe.fe_flow_name,
252 253 mac_flow_proto2str(fdesc.fd_protocol), fdesc.fd_local_port,
253 254 fdesc.fd_dsfield, fdesc.fd_dsfield_mask);
254 255 if (fdesc.fd_ipversion == IPV4_VERSION) {
255 256 IN6_V4MAPPED_TO_INADDR(&fdesc.fd_local_addr, &in4);
256 257 mdb_printf("%I", in4.s_addr);
257 258 } else if (fdesc.fd_ipversion == IPV6_VERSION) {
258 259 mdb_printf("%N", &fdesc.fd_local_addr);
259 260 } else {
260 261 mdb_printf("%s", "--");
261 262 }
262 263 mdb_printf("\n");
263 264 break;
264 265 }
265 266 case MAC_FLOW_PROP: {
266 267 uintptr_t prop_addr;
267 268 char bwstr[STRSIZE];
268 269 mac_resource_props_t fprop;
269 270
270 271 prop_addr = addr + OFFSETOF(flow_entry_t, fe_resource_props);
271 272 if (mdb_vread(&fprop, sizeof (fprop), prop_addr) == -1) {
272 273 mdb_warn("failed to read struct mac_resoource_props "
273 274 "at %p", prop_addr);
274 275 return (DCMD_ERR);
275 276 }
276 277 mdb_printf("%?p %-32s "
277 278 "%8s %9s\n",
278 279 addr, fe.fe_flow_name,
279 280 mac_flow_bw2str(fprop.mrp_maxbw, bwstr, STRSIZE),
280 281 mac_flow_priority2str(fprop.mrp_priority));
281 282 break;
282 283 }
283 284 case MAC_FLOW_MISC: {
284 285 char flow_flags[2 * FLOW_MAX_FLAGS];
285 286 char flow_type[2 * FLOW_MAX_TYPE];
286 287 GElf_Sym sym;
287 288 char func_name[MDB_SYM_NAMLEN] = "";
288 289 uintptr_t func, match_addr;
289 290
290 291 match_addr = addr + OFFSETOF(flow_entry_t, fe_match);
291 292 (void) mdb_vread(&func, sizeof (func), match_addr);
292 293 (void) mdb_lookup_by_addr(func, MDB_SYM_EXACT, func_name,
293 294 MDB_SYM_NAMLEN, &sym);
294 295 mdb_snprintf(flow_flags, 2 * FLOW_MAX_FLAGS, "%hb",
295 296 fe.fe_flags, flow_flag_bits);
296 297 mdb_snprintf(flow_type, 2 * FLOW_MAX_TYPE, "%hb",
297 298 fe.fe_type, flow_type_bits);
298 299 mdb_printf("%?p %-24s %10s %10s %20s\n",
299 300 addr, fe.fe_flow_name, flow_type, flow_flags, func_name);
300 301 break;
301 302 }
302 303 case MAC_FLOW_RX: {
303 304 uintptr_t rxaddr, rx_srs[MAX_RINGS_PER_GROUP] = {0};
304 305 int i;
305 306
306 307 rxaddr = addr + OFFSETOF(flow_entry_t, fe_rx_srs);
307 308 (void) mdb_vread(rx_srs, MAC_RX_SRS_SIZE, rxaddr);
308 309 mdb_printf("%?p %-24s %3d ",
309 310 addr, fe.fe_flow_name, fe.fe_rx_srs_cnt);
310 311 for (i = 0; i < MAX_RINGS_PER_GROUP; i++) {
311 312 if (rx_srs[i] == 0)
312 313 continue;
313 314 mdb_printf("%p ", rx_srs[i]);
314 315 }
315 316 mdb_printf("\n");
316 317 break;
317 318 }
318 319 case MAC_FLOW_TX: {
319 320 uintptr_t tx_srs = 0, txaddr;
320 321
321 322 txaddr = addr + OFFSETOF(flow_entry_t, fe_tx_srs);
322 323 (void) mdb_vread(&tx_srs, sizeof (uintptr_t), txaddr);
323 324 mdb_printf("%?p %-32s %?p\n",
324 325 addr, fe.fe_flow_name, fe.fe_tx_srs);
325 326 break;
326 327 }
327 328 case MAC_FLOW_STATS: {
328 329 uint64_t totibytes = 0;
329 330 uint64_t totobytes = 0;
330 331 mac_soft_ring_set_t *mac_srs;
331 332 mac_rx_stats_t mac_rx_stat;
332 333 mac_tx_stats_t mac_tx_stat;
333 334 int i;
334 335
335 336 /*
336 337 * Sum bytes for all Rx SRS.
337 338 */
338 339 for (i = 0; i < fe.fe_rx_srs_cnt; i++) {
339 340 mac_srs = (mac_soft_ring_set_t *)(fe.fe_rx_srs[i]);
340 341 if (mdb_vread(&mac_rx_stat, sizeof (mac_rx_stats_t),
341 342 (uintptr_t)&mac_srs->srs_rx.sr_stat) == -1) {
342 343 mdb_warn("failed to read mac_rx_stats_t at %p",
343 344 &mac_srs->srs_rx.sr_stat);
344 345 return (DCMD_ERR);
345 346 }
346 347
347 348 totibytes += mac_rx_stat.mrs_intrbytes +
348 349 mac_rx_stat.mrs_pollbytes +
349 350 mac_rx_stat.mrs_lclbytes;
350 351 }
351 352
352 353 /*
353 354 * Sum bytes for Tx SRS.
354 355 */
355 356 mac_srs = (mac_soft_ring_set_t *)(fe.fe_tx_srs);
356 357 if (mac_srs != NULL) {
357 358 if (mdb_vread(&mac_tx_stat, sizeof (mac_tx_stats_t),
358 359 (uintptr_t)&mac_srs->srs_tx.st_stat) == -1) {
359 360 mdb_warn("failed to read max_tx_stats_t at %p",
360 361 &mac_srs->srs_tx.st_stat);
361 362 return (DCMD_ERR);
362 363 }
363 364
364 365 totobytes = mac_tx_stat.mts_obytes;
365 366 }
366 367
367 368 mdb_printf("%?p %-32s %16llu %16llu\n",
368 369 addr, fe.fe_flow_name, totibytes, totobytes);
369 370
370 371 break;
371 372 }
372 373 }
373 374 return (DCMD_OK);
374 375 }
375 376
376 377 /*
377 378 * Parse the arguments passed to the dcmd and print all or one flow_entry_t
378 379 * structures
379 380 */
380 381 static int
381 382 mac_flow_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
382 383 {
383 384 uint_t args = 0;
384 385
385 386 if (!(flags & DCMD_ADDRSPEC)) {
386 387 if (mdb_walk_dcmd("mac_flow", "mac_flow", argc, argv) == -1) {
387 388 mdb_warn("failed to walk 'mac_flow'");
388 389 return (DCMD_ERR);
389 390 }
390 391 return (DCMD_OK);
391 392 }
392 393 if ((mdb_getopts(argc, argv,
393 394 'a', MDB_OPT_SETBITS, MAC_FLOW_ATTR, &args,
394 395 'p', MDB_OPT_SETBITS, MAC_FLOW_PROP, &args,
395 396 'm', MDB_OPT_SETBITS, MAC_FLOW_MISC, &args,
396 397 'r', MDB_OPT_SETBITS, MAC_FLOW_RX, &args,
397 398 't', MDB_OPT_SETBITS, MAC_FLOW_TX, &args,
398 399 's', MDB_OPT_SETBITS, MAC_FLOW_STATS, &args,
399 400 'u', MDB_OPT_SETBITS, MAC_FLOW_USER, &args,
400 401 NULL) != argc)) {
401 402 return (DCMD_USAGE);
402 403 }
403 404 if (argc > 2 || (argc == 2 && !(args & MAC_FLOW_USER)))
404 405 return (DCMD_USAGE);
405 406 /*
406 407 * If no arguments was specified or just "-u" was specified then
407 408 * we default to printing basic information of flows.
408 409 */
409 410 if (args == 0 || args == MAC_FLOW_USER)
410 411 args |= MAC_FLOW_NONE;
411 412
412 413 return (mac_flow_dcmd_output(addr, flags, args));
413 414 }
414 415
415 416 static void
416 417 mac_flow_help(void)
417 418 {
418 419 mdb_printf("If an address is specified, then flow_entry structure at "
419 420 "that address is printed. Otherwise all the flows in the system "
420 421 "are printed.\n");
421 422 mdb_printf("Options:\n"
422 423 "\t-u\tdisplay user defined link & vnic flows.\n"
423 424 "\t-a\tdisplay flow attributes\n"
424 425 "\t-p\tdisplay flow properties\n"
425 426 "\t-r\tdisplay rx side information\n"
426 427 "\t-t\tdisplay tx side information\n"
427 428 "\t-s\tdisplay flow statistics\n"
428 429 "\t-m\tdisplay miscellaneous flow information\n\n");
429 430 mdb_printf("%<u>Interpreting Flow type and Flow flags output.%</u>\n");
430 431 mdb_printf("Flow Types:\n");
431 432 mdb_printf("\t P --> FLOW_PRIMARY_MAC\n");
432 433 mdb_printf("\t V --> FLOW_VNIC_MAC\n");
433 434 mdb_printf("\t M --> FLOW_MCAST\n");
434 435 mdb_printf("\t O --> FLOW_OTHER\n");
435 436 mdb_printf("\t U --> FLOW_USER\n");
436 437 mdb_printf("\t NS --> FLOW_NO_STATS\n\n");
437 438 mdb_printf("Flow Flags:\n");
438 439 mdb_printf("\t Q --> FE_QUIESCE\n");
439 440 mdb_printf("\t W --> FE_WAITER\n");
440 441 mdb_printf("\t T --> FE_FLOW_TAB\n");
441 442 mdb_printf("\t G --> FE_G_FLOW_HASH\n");
442 443 mdb_printf("\t I --> FE_INCIPIENT\n");
443 444 mdb_printf("\t C --> FE_CONDEMNED\n");
444 445 mdb_printf("\t NU --> FE_UF_NO_DATAPATH\n");
445 446 mdb_printf("\t NC --> FE_MC_NO_DATAPATH\n");
446 447 }
447 448
448 449 /*
449 450 * called once by the debugger when the mac_flow walk begins.
450 451 */
451 452 static int
452 453 mac_flow_walk_init(mdb_walk_state_t *wsp)
453 454 {
454 455 if (mdb_layered_walk(LAYERED_WALKER_FOR_FLOW, wsp) == -1) {
455 456 mdb_warn("failed to walk 'mac_flow'");
456 457 return (WALK_ERR);
457 458 }
458 459 return (WALK_NEXT);
459 460 }
460 461
461 462 /*
462 463 * Common walker step funciton for flow_entry_t, mac_soft_ring_set_t and
463 464 * mac_ring_t.
464 465 *
465 466 * Steps through each flow_entry_t and calls the callback function. If the
466 467 * user executed ::walk mac_flow, it just prints the address or if the user
467 468 * executed ::mac_flow it displays selected fields of flow_entry_t structure
468 469 * by calling "mac_flow_dcmd"
469 470 */
470 471 static int
471 472 mac_common_walk_step(mdb_walk_state_t *wsp)
472 473 {
473 474 int status;
474 475
475 476 if (wsp->walk_addr == 0)
476 477 return (WALK_DONE);
477 478
478 479 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
479 480 wsp->walk_cbdata);
480 481
481 482 return (status);
482 483 }
483 484
484 485 static char *
485 486 mac_srs_txmode2str(mac_tx_srs_mode_t mode)
486 487 {
487 488 switch (mode) {
488 489 case SRS_TX_DEFAULT:
489 490 return ("DEF");
490 491 case SRS_TX_SERIALIZE:
491 492 return ("SER");
492 493 case SRS_TX_FANOUT:
493 494 return ("FO");
494 495 case SRS_TX_BW:
495 496 return ("BW");
496 497 case SRS_TX_BW_FANOUT:
497 498 return ("BWFO");
498 499 case SRS_TX_AGGR:
499 500 return ("AG");
500 501 case SRS_TX_BW_AGGR:
501 502 return ("BWAG");
502 503 }
503 504 return ("--");
504 505 }
505 506
506 507 static void
507 508 mac_srs_help(void)
508 509 {
509 510 mdb_printf("If an address is specified, then mac_soft_ring_set "
510 511 "structure at that address is printed. Otherwise all the "
511 512 "SRS in the system are printed.\n");
512 513 mdb_printf("Options:\n"
513 514 "\t-r\tdisplay recieve side SRS structures\n"
514 515 "\t-t\tdisplay transmit side SRS structures\n"
515 516 "\t-s\tdisplay statistics for RX or TX side\n"
516 517 "\t-c\tdisplay CPU binding for RX or TX side\n"
517 518 "\t-v\tverbose flag for CPU binding to list cpus\n"
518 519 "\t-i\tdisplay mac_ring_t and interrupt information\n"
519 520 "Note: use -r or -t (to specify RX or TX side respectively) along "
520 521 "with -c or -s\n");
521 522 mdb_printf("\n%<u>Interpreting TX Modes%</u>\n");
522 523 mdb_printf("\t DEF --> Default\n");
523 524 mdb_printf("\t SER --> Serialize\n");
524 525 mdb_printf("\t FO --> Fanout\n");
525 526 mdb_printf("\t BW --> Bandwidth\n");
526 527 mdb_printf("\tBWFO --> Bandwidth Fanout\n");
527 528 mdb_printf("\t AG --> Aggr\n");
528 529 mdb_printf("\tBWAG --> Bandwidth Aggr\n");
529 530 }
530 531
531 532 /*
532 533 * In verbose mode "::mac_srs -rcv or ::mac_srs -tcv", we print the CPUs
533 534 * assigned to a link and CPUS assigned to the soft rings.
534 535 * 'len' is used for formatting the output and represents the number of
535 536 * spaces between CPU list and Fanout CPU list in the output.
536 537 */
537 538 static boolean_t
538 539 mac_srs_print_cpu(int *i, uint32_t cnt, uint32_t *cpu_list, int *len)
539 540 {
540 541 int num = 0;
541 542
542 543 if (*i == 0)
543 544 mdb_printf("(");
544 545 else
545 546 mdb_printf(" ");
546 547 while (*i < cnt) {
547 548 /* We print 6 CPU's at a time to keep display within 80 cols */
548 549 if (((num + 1) % 7) == 0) {
549 550 if (len != NULL)
550 551 *len = 2;
551 552 return (B_FALSE);
552 553 }
553 554 mdb_printf("%02x%c", cpu_list[*i], ((*i == cnt - 1)?')':','));
554 555 ++*i;
555 556 ++num;
556 557 }
557 558 if (len != NULL)
558 559 *len = (7 - num) * 3;
559 560 return (B_TRUE);
560 561 }
561 562
562 563 static int
563 564 mac_srs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
564 565 {
565 566 uint_t args = MAC_SRS_NONE;
566 567 mac_soft_ring_set_t srs;
567 568 mac_client_impl_t mci;
568 569
569 570 if (!(flags & DCMD_ADDRSPEC)) {
570 571 if (mdb_walk_dcmd("mac_srs", "mac_srs", argc, argv) == -1) {
571 572 mdb_warn("failed to walk 'mac_srs'");
572 573 return (DCMD_ERR);
573 574 }
574 575 return (DCMD_OK);
575 576 }
576 577 if (mdb_getopts(argc, argv,
577 578 'r', MDB_OPT_SETBITS, MAC_SRS_RX, &args,
578 579 't', MDB_OPT_SETBITS, MAC_SRS_TX, &args,
579 580 'c', MDB_OPT_SETBITS, MAC_SRS_CPU, &args,
580 581 'v', MDB_OPT_SETBITS, MAC_SRS_VERBOSE, &args,
581 582 'i', MDB_OPT_SETBITS, MAC_SRS_INTR, &args,
582 583 's', MDB_OPT_SETBITS, MAC_SRS_STAT, &args,
583 584 NULL) != argc) {
584 585 return (DCMD_USAGE);
585 586 }
586 587
587 588 if (argc > 2)
588 589 return (DCMD_USAGE);
589 590
590 591 if (mdb_vread(&srs, sizeof (srs), addr) == -1) {
591 592 mdb_warn("failed to read struct mac_soft_ring_set_s at %p",
592 593 addr);
593 594 return (DCMD_ERR);
594 595 }
595 596 if (mdb_vread(&mci, sizeof (mci), (uintptr_t)srs.srs_mcip) == -1) {
596 597 mdb_warn("failed to read struct mac_client_impl_t at %p "
597 598 "for SRS %p", srs.srs_mcip, addr);
598 599 return (DCMD_ERR);
599 600 }
600 601
601 602 switch (args) {
602 603 case MAC_SRS_RX: {
603 604 if (DCMD_HDRSPEC(flags)) {
604 605 mdb_printf("%?s %-20s %-8s %-8s %8s "
605 606 "%8s %3s\n",
606 607 "", "", "", "", "MBLK",
607 608 "Q", "SR");
608 609 mdb_printf("%<u>%?s %-20s %-8s %-8s %8s "
609 610 "%8s %3s%</u>\n",
610 611 "ADDR", "LINK_NAME", "STATE", "TYPE", "CNT",
611 612 "BYTES", "CNT");
612 613 }
613 614 if (srs.srs_type & SRST_TX)
614 615 return (DCMD_OK);
615 616 mdb_printf("%?p %-20s %08x %08x "
616 617 "%8d %8d %3d\n",
617 618 addr, mci.mci_name, srs.srs_state, srs.srs_type,
618 619 srs.srs_count, srs.srs_size, srs.srs_soft_ring_count);
619 620 break;
620 621 }
621 622 case MAC_SRS_TX: {
622 623 if (DCMD_HDRSPEC(flags)) {
623 624 mdb_printf("%?s %-16s %-4s %-8s "
624 625 "%-8s %8s %8s %3s\n",
625 626 "", "", "TX", "",
626 627 "", "MBLK", "Q", "SR");
627 628 mdb_printf("%<u>%?s %-16s %-4s %-8s "
628 629 "%-8s %8s %8s %3s%</u>\n",
629 630 "ADDR", "LINK_NAME", "MODE", "STATE",
630 631 "TYPE", "CNT", "BYTES", "CNT");
631 632 }
632 633 if (!(srs.srs_type & SRST_TX))
633 634 return (DCMD_OK);
634 635
635 636 mdb_printf("%?p %-16s %-4s "
636 637 "%08x %08x %8d %8d %3d\n",
637 638 addr, mci.mci_name, mac_srs_txmode2str(srs.srs_tx.st_mode),
638 639 srs.srs_state, srs.srs_type, srs.srs_count, srs.srs_size,
639 640 srs.srs_tx_ring_count);
640 641 break;
641 642 }
642 643 case MAC_SRS_RXCPU: {
643 644 mac_cpus_t mc = srs.srs_cpu;
644 645
645 646 if (DCMD_HDRSPEC(flags)) {
646 647 mdb_printf("%?s %-20s %-4s %-4s "
647 648 "%-6s %-4s %-7s\n",
648 649 "", "", "NUM", "POLL",
649 650 "WORKER", "INTR", "FANOUT");
650 651 mdb_printf("%<u>%?s %-20s %-4s %-4s "
651 652 "%-6s %-4s %-7s%</u>\n",
652 653 "ADDR", "LINK_NAME", "CPUS", "CPU",
653 654 "CPU", "CPU", "CPU_CNT");
654 655 }
655 656 if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))
656 657 return (DCMD_OK);
657 658 mdb_printf("%?p %-20s %-4d %-4d "
658 659 "%-6d %-4d %-7d\n",
659 660 addr, mci.mci_name, mc.mc_ncpus, mc.mc_rx_pollid,
660 661 mc.mc_rx_workerid, mc.mc_rx_intr_cpu, mc.mc_rx_fanout_cnt);
661 662 break;
662 663
663 664 }
664 665 case MAC_SRS_TXCPU: {
665 666 mac_cpus_t mc = srs.srs_cpu;
666 667 mac_soft_ring_t *s_ringp, s_ring;
667 668 boolean_t first = B_TRUE;
668 669 int i;
669 670
670 671 if (DCMD_HDRSPEC(flags)) {
671 672 mdb_printf("%?s %-12s %?s %8s %8s %8s\n",
672 673 "", "", "SOFT", "WORKER", "INTR", "RETARGETED");
673 674 mdb_printf("%<u>%?s %-12s %?s %8s %8s %8s%</u>\n",
674 675 "ADDR", "LINK_NAME", "RING", "CPU", "CPU", "CPU");
675 676 }
676 677 if (!(srs.srs_type & SRST_TX))
677 678 return (DCMD_OK);
678 679
679 680 mdb_printf("%?p %-12s ", addr, mci.mci_name);
680 681
681 682 /*
682 683 * Case of no soft rings, print the info from
683 684 * mac_srs_tx_t.
684 685 */
685 686 if (srs.srs_tx_ring_count == 0) {
686 687 mdb_printf("%?p %8d %8d %8d\n",
687 688 0, mc.mc_tx_fanout_cpus[0],
688 689 mc.mc_tx_intr_cpu[0],
689 690 mc.mc_tx_retargeted_cpu[0]);
690 691 break;
691 692 }
692 693
693 694 for (s_ringp = srs.srs_soft_ring_head, i = 0; s_ringp != NULL;
694 695 s_ringp = s_ring.s_ring_next, i++) {
695 696 (void) mdb_vread(&s_ring, sizeof (s_ring),
696 697 (uintptr_t)s_ringp);
697 698 if (first) {
698 699 mdb_printf("%?p %8d %8d %8d\n",
699 700 s_ringp, mc.mc_tx_fanout_cpus[i],
700 701 mc.mc_tx_intr_cpu[i],
701 702 mc.mc_tx_retargeted_cpu[i]);
702 703 first = B_FALSE;
703 704 continue;
704 705 }
705 706 mdb_printf("%?s %-12s %?p %8d %8d %8d\n",
706 707 "", "", s_ringp, mc.mc_tx_fanout_cpus[i],
707 708 mc.mc_tx_intr_cpu[i], mc.mc_tx_retargeted_cpu[i]);
708 709 }
709 710 break;
710 711 }
711 712 case MAC_SRS_TXINTR: {
712 713 mac_cpus_t mc = srs.srs_cpu;
713 714 mac_soft_ring_t *s_ringp, s_ring;
714 715 mac_ring_t *m_ringp, m_ring;
715 716 boolean_t first = B_TRUE;
716 717 int i;
717 718
718 719 if (DCMD_HDRSPEC(flags)) {
719 720 mdb_printf("%?s %-12s %?s %8s %?s %6s %6s\n",
720 721 "", "", "SOFT", "WORKER", "MAC", "", "INTR");
721 722 mdb_printf("%<u>%?s %-12s %?s %8s %?s %6s %6s%</u>\n",
722 723 "ADDR", "LINK_NAME", "RING", "CPU", "RING",
723 724 "SHARED", "CPU");
724 725 }
725 726 if (!(srs.srs_type & SRST_TX))
726 727 return (DCMD_OK);
727 728
728 729 mdb_printf("%?p %-12s ", addr, mci.mci_name);
729 730
730 731 /*
731 732 * Case of no soft rings, print the info from
732 733 * mac_srs_tx_t.
733 734 */
734 735 if (srs.srs_tx_ring_count == 0) {
735 736 m_ringp = srs.srs_tx.st_arg2;
736 737 if (m_ringp != NULL) {
737 738 (void) mdb_vread(&m_ring, sizeof (m_ring),
738 739 (uintptr_t)m_ringp);
739 740 mdb_printf("%?p %8d %?p %6d %6d\n",
740 741 0, mc.mc_tx_fanout_cpus[0], m_ringp,
741 742 m_ring.mr_info.mri_intr.mi_ddi_shared,
742 743 mc.mc_tx_retargeted_cpu[0]);
743 744 } else {
744 745 mdb_printf("%?p %8d %?p %6d %6d\n",
745 746 0, mc.mc_tx_fanout_cpus[0], 0,
746 747 0, mc.mc_tx_retargeted_cpu[0]);
747 748 }
748 749 break;
749 750 }
750 751
751 752 for (s_ringp = srs.srs_soft_ring_head, i = 0; s_ringp != NULL;
752 753 s_ringp = s_ring.s_ring_next, i++) {
753 754 (void) mdb_vread(&s_ring, sizeof (s_ring),
754 755 (uintptr_t)s_ringp);
755 756 m_ringp = s_ring.s_ring_tx_arg2;
756 757 (void) mdb_vread(&m_ring, sizeof (m_ring),
757 758 (uintptr_t)m_ringp);
758 759 if (first) {
759 760 mdb_printf("%?p %8d %?p %6d %6d\n",
760 761 s_ringp, mc.mc_tx_fanout_cpus[i],
761 762 m_ringp,
762 763 m_ring.mr_info.mri_intr.mi_ddi_shared,
763 764 mc.mc_tx_retargeted_cpu[i]);
764 765 first = B_FALSE;
765 766 continue;
766 767 }
767 768 mdb_printf("%?s %-12s %?p %8d %?p %6d %6d\n",
768 769 "", "", s_ringp, mc.mc_tx_fanout_cpus[i],
769 770 m_ringp, m_ring.mr_info.mri_intr.mi_ddi_shared,
770 771 mc.mc_tx_retargeted_cpu[i]);
771 772 }
772 773 break;
773 774 }
774 775 case MAC_SRS_RXINTR: {
775 776 mac_cpus_t mc = srs.srs_cpu;
776 777 mac_ring_t *m_ringp, m_ring;
777 778
778 779 if (DCMD_HDRSPEC(flags)) {
779 780 mdb_printf("%?s %-12s %?s %8s %6s %6s\n",
780 781 "", "", "MAC", "", "POLL", "INTR");
781 782 mdb_printf("%<u>%?s %-12s %?s %8s %6s %6s%</u>\n",
782 783 "ADDR", "LINK_NAME", "RING", "SHARED", "CPU",
783 784 "CPU");
784 785 }
785 786 if ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX))
786 787 return (DCMD_OK);
787 788
788 789 mdb_printf("%?p %-12s ", addr, mci.mci_name);
789 790
790 791 m_ringp = srs.srs_ring;
791 792 if (m_ringp != NULL) {
792 793 (void) mdb_vread(&m_ring, sizeof (m_ring),
793 794 (uintptr_t)m_ringp);
794 795 mdb_printf("%?p %8d %6d %6d\n",
795 796 m_ringp, m_ring.mr_info.mri_intr.mi_ddi_shared,
796 797 mc.mc_rx_pollid, mc.mc_rx_intr_cpu);
797 798 } else {
798 799 mdb_printf("%?p %8d %6d %6d\n",
799 800 0, 0, mc.mc_rx_pollid, mc.mc_rx_intr_cpu);
800 801 }
801 802 break;
802 803 }
803 804 case MAC_SRS_RXCPUVERBOSE:
804 805 case MAC_SRS_TXCPUVERBOSE: {
805 806 mac_cpus_t mc = srs.srs_cpu;
806 807 int cpu_index = 0, fanout_index = 0, len = 0;
807 808 boolean_t cpu_done = B_FALSE, fanout_done = B_FALSE;
808 809
809 810 if (DCMD_HDRSPEC(flags)) {
810 811 mdb_printf("%?s %-20s %-20s %-20s\n",
811 812 "", "", "CPU_COUNT", "FANOUT_CPU_COUNT");
812 813 mdb_printf("%<u>%?s %-20s "
813 814 "%-20s %-20s%</u>\n",
814 815 "ADDR", "LINK_NAME",
815 816 "(CPU_LIST)", "(CPU_LIST)");
816 817 }
817 818 if (((args & MAC_SRS_TX) && !(srs.srs_type & SRST_TX)) ||
818 819 ((args & MAC_SRS_RX) && (srs.srs_type & SRST_TX)))
819 820 return (DCMD_OK);
820 821 mdb_printf("%?p %-20s %-20d %-20d\n", addr, mci.mci_name,
821 822 mc.mc_ncpus, mc.mc_rx_fanout_cnt);
822 823 if (mc.mc_ncpus == 0 && mc.mc_rx_fanout_cnt == 0)
823 824 break;
824 825 /* print all cpus and cpus for soft rings */
825 826 while (!cpu_done || !fanout_done) {
826 827 boolean_t old_value = cpu_done;
827 828
828 829 if (!cpu_done) {
829 830 mdb_printf("%?s %20s ", "", "");
830 831 cpu_done = mac_srs_print_cpu(&cpu_index,
831 832 mc.mc_ncpus, mc.mc_cpus, &len);
832 833 }
833 834 if (!fanout_done) {
834 835 if (old_value)
835 836 mdb_printf("%?s %-40s", "", "");
836 837 else
837 838 mdb_printf("%*s", len, "");
838 839 fanout_done = mac_srs_print_cpu(&fanout_index,
839 840 mc.mc_rx_fanout_cnt,
840 841 mc.mc_rx_fanout_cpus, NULL);
841 842 }
842 843 mdb_printf("\n");
843 844 }
844 845 break;
845 846 }
846 847 case MAC_SRS_RXSTAT: {
847 848 mac_rx_stats_t *mac_rx_stat = &srs.srs_rx.sr_stat;
848 849
849 850 if (DCMD_HDRSPEC(flags)) {
850 851 mdb_printf("%?s %-16s %8s %8s "
851 852 "%8s %8s %8s\n",
852 853 "", "", "INTR", "POLL",
853 854 "CHAIN", "CHAIN", "CHAIN");
854 855 mdb_printf("%<u>%?s %-16s %8s %8s "
855 856 "%8s %8s %8s%</u>\n",
856 857 "ADDR", "LINK_NAME", "COUNT", "COUNT",
857 858 "<10", "10-50", ">50");
858 859 }
859 860 if (srs.srs_type & SRST_TX)
860 861 return (DCMD_OK);
861 862 mdb_printf("%?p %-16s %8d "
862 863 "%8d %8d "
863 864 "%8d %8d\n",
864 865 addr, mci.mci_name, mac_rx_stat->mrs_intrcnt,
865 866 mac_rx_stat->mrs_pollcnt, mac_rx_stat->mrs_chaincntundr10,
866 867 mac_rx_stat->mrs_chaincnt10to50,
867 868 mac_rx_stat->mrs_chaincntover50);
868 869 break;
869 870 }
870 871 case MAC_SRS_TXSTAT: {
871 872 mac_tx_stats_t *mac_tx_stat = &srs.srs_tx.st_stat;
872 873 mac_soft_ring_t *s_ringp, s_ring;
873 874 boolean_t first = B_TRUE;
874 875
875 876 if (DCMD_HDRSPEC(flags)) {
876 877 mdb_printf("%?s %-20s %?s %8s %8s %8s\n",
877 878 "", "", "SOFT", "DROP", "BLOCK", "UNBLOCK");
878 879 mdb_printf("%<u>%?s %-20s %?s %8s %8s %8s%</u>\n",
879 880 "ADDR", "LINK_NAME", "RING", "COUNT", "COUNT",
880 881 "COUNT");
881 882 }
882 883 if (!(srs.srs_type & SRST_TX))
883 884 return (DCMD_OK);
884 885
885 886 mdb_printf("%?p %-20s ", addr, mci.mci_name);
886 887
887 888 /*
888 889 * Case of no soft rings, print the info from
889 890 * mac_srs_tx_t.
890 891 */
891 892 if (srs.srs_tx_ring_count == 0) {
892 893 mdb_printf("%?p %8d %8d %8d\n",
893 894 0, mac_tx_stat->mts_sdrops,
894 895 mac_tx_stat->mts_blockcnt,
895 896 mac_tx_stat->mts_unblockcnt);
896 897 break;
897 898 }
898 899
899 900 for (s_ringp = srs.srs_soft_ring_head; s_ringp != NULL;
900 901 s_ringp = s_ring.s_ring_next) {
901 902 (void) mdb_vread(&s_ring, sizeof (s_ring),
902 903 (uintptr_t)s_ringp);
903 904 mac_tx_stat = &s_ring.s_st_stat;
904 905 if (first) {
905 906 mdb_printf("%?p %8d %8d %8d\n",
906 907 s_ringp, mac_tx_stat->mts_sdrops,
907 908 mac_tx_stat->mts_blockcnt,
908 909 mac_tx_stat->mts_unblockcnt);
909 910 first = B_FALSE;
910 911 continue;
911 912 }
912 913 mdb_printf("%?s %-20s %?p %8d %8d %8d\n",
913 914 "", "", s_ringp, mac_tx_stat->mts_sdrops,
914 915 mac_tx_stat->mts_blockcnt,
915 916 mac_tx_stat->mts_unblockcnt);
916 917 }
917 918 break;
918 919 }
919 920 case MAC_SRS_NONE: {
920 921 if (DCMD_HDRSPEC(flags)) {
921 922 mdb_printf("%<u>%?s %-20s %?s %?s %-3s%</u>\n",
922 923 "ADDR", "LINK_NAME", "FLENT", "HW RING", "DIR");
923 924 }
924 925 mdb_printf("%?p %-20s %?p %?p "
925 926 "%-3s ",
926 927 addr, mci.mci_name, srs.srs_flent, srs.srs_ring,
927 928 (srs.srs_type & SRST_TX ? "TX" : "RX"));
928 929 break;
929 930 }
930 931 default:
931 932 return (DCMD_USAGE);
932 933 }
933 934 return (DCMD_OK);
934 935 }
935 936
936 937 static int
937 938 mac_srs_walk_init(mdb_walk_state_t *wsp)
938 939 {
939 940 if (mdb_layered_walk(LAYERED_WALKER_FOR_SRS, wsp) == -1) {
940 941 mdb_warn("failed to walk 'mac_srs'");
941 942 return (WALK_ERR);
942 943 }
943 944 return (WALK_NEXT);
944 945 }
945 946
946 947 static char *
947 948 mac_ring_state2str(mac_ring_state_t state)
948 949 {
949 950 switch (state) {
950 951 case MR_FREE:
951 952 return ("free");
952 953 case MR_NEWLY_ADDED:
953 954 return ("new");
954 955 case MR_INUSE:
955 956 return ("inuse");
956 957 }
957 958 return ("--");
958 959 }
959 960
↓ open down ↓ |
926 lines elided |
↑ open up ↑ |
960 961 static char *
961 962 mac_ring_classify2str(mac_classify_type_t classify)
962 963 {
963 964 switch (classify) {
964 965 case MAC_NO_CLASSIFIER:
965 966 return ("no");
966 967 case MAC_SW_CLASSIFIER:
967 968 return ("sw");
968 969 case MAC_HW_CLASSIFIER:
969 970 return ("hw");
971 + case MAC_PASSTHRU_CLASSIFIER:
972 + return ("pass");
970 973 }
971 974 return ("--");
972 975 }
973 976
974 977 static int
975 978 mac_ring_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
976 979 {
977 980 mac_ring_t ring;
978 981 mac_group_t group;
979 982 flow_entry_t flent;
980 983 mac_soft_ring_set_t srs;
981 984
982 985 if (!(flags & DCMD_ADDRSPEC)) {
983 986 if (mdb_walk_dcmd("mac_ring", "mac_ring", argc, argv) == -1) {
984 987 mdb_warn("failed to walk 'mac_ring'");
985 988 return (DCMD_ERR);
986 989 }
987 990 return (DCMD_OK);
988 991 }
989 992 if (mdb_vread(&ring, sizeof (ring), addr) == -1) {
990 993 mdb_warn("failed to read struct mac_ring_s at %p", addr);
991 994 return (DCMD_ERR);
992 995 }
993 996 bzero(&flent, sizeof (flent));
994 997 if (mdb_vread(&srs, sizeof (srs), (uintptr_t)ring.mr_srs) != -1) {
995 998 (void) mdb_vread(&flent, sizeof (flent),
996 999 (uintptr_t)srs.srs_flent);
997 1000 }
998 1001 (void) mdb_vread(&group, sizeof (group), (uintptr_t)ring.mr_gh);
999 1002 if (DCMD_HDRSPEC(flags)) {
1000 1003 mdb_printf("%<u>%?s %4s %5s %4s %?s "
1001 1004 "%5s %?s %?s %s %</u>\n",
1002 1005 "ADDR", "TYPE", "STATE", "FLAG", "GROUP",
1003 1006 "CLASS", "MIP", "SRS", "FLOW NAME");
1004 1007 }
1005 1008 mdb_printf("%?p %-4s "
1006 1009 "%5s %04x "
1007 1010 "%?p %-5s "
1008 1011 "%?p %?p %s\n",
1009 1012 addr, ((ring.mr_type == 1)? "RX" : "TX"),
1010 1013 mac_ring_state2str(ring.mr_state), ring.mr_flag,
1011 1014 ring.mr_gh, mac_ring_classify2str(ring.mr_classify_type),
1012 1015 group.mrg_mh, ring.mr_srs, flent.fe_flow_name);
1013 1016 return (DCMD_OK);
1014 1017 }
1015 1018
1016 1019 static int
1017 1020 mac_ring_walk_init(mdb_walk_state_t *wsp)
1018 1021 {
1019 1022 if (mdb_layered_walk(LAYERED_WALKER_FOR_RING, wsp) == -1) {
1020 1023 mdb_warn("failed to walk `mac_ring`");
1021 1024 return (WALK_ERR);
1022 1025 }
1023 1026 return (WALK_NEXT);
1024 1027 }
1025 1028
1026 1029 static void
1027 1030 mac_ring_help(void)
1028 1031 {
1029 1032 mdb_printf("If an address is specified, then mac_ring_t "
1030 1033 "structure at that address is printed. Otherwise all the "
1031 1034 "hardware rings in the system are printed.\n");
1032 1035 }
1033 1036
1034 1037 /*
1035 1038 * To walk groups we have to have our own somewhat-complicated state machine. We
1036 1039 * basically start by walking the mac_impl_t walker as all groups are stored off
1037 1040 * of the various mac_impl_t in the system. The tx and rx rings are kept
1038 1041 * separately. So we'll need to walk through all the rx rings and then all of
1039 1042 * the tx rings.
1040 1043 */
1041 1044 static int
1042 1045 mac_group_walk_init(mdb_walk_state_t *wsp)
1043 1046 {
1044 1047 int ret;
1045 1048
1046 1049 if (wsp->walk_addr != 0) {
1047 1050 mdb_warn("non-global walks are not supported\n");
1048 1051 return (WALK_ERR);
1049 1052 }
1050 1053
1051 1054 if ((ret = mdb_layered_walk(LAYERED_WALKER_FOR_GROUP, wsp)) == -1) {
1052 1055 mdb_warn("couldn't walk '%s'", LAYERED_WALKER_FOR_GROUP);
1053 1056 return (ret);
1054 1057 }
1055 1058
1056 1059 return (WALK_NEXT);
1057 1060 }
1058 1061
1059 1062 static int
1060 1063 mac_group_walk_step(mdb_walk_state_t *wsp)
1061 1064 {
1062 1065 int ret;
1063 1066 mac_impl_t mi;
1064 1067 mac_group_t mg;
1065 1068 uintptr_t mgp;
1066 1069
1067 1070 /*
1068 1071 * Nothing to do if we can't find the layer above us. But the kmem
1069 1072 * walkers are a bit unsporting, they don't actually read in the data
1070 1073 * for us.
1071 1074 */
1072 1075 if (wsp->walk_addr == 0)
1073 1076 return (WALK_DONE);
1074 1077
1075 1078 if (mdb_vread(&mi, sizeof (mac_impl_t), wsp->walk_addr) == -1) {
1076 1079 mdb_warn("failed to read mac_impl_t at %p", wsp->walk_addr);
1077 1080 return (DCMD_ERR);
1078 1081 }
1079 1082
1080 1083 /*
1081 1084 * First go for rx groups, then tx groups.
1082 1085 */
1083 1086 mgp = (uintptr_t)mi.mi_rx_groups;
1084 1087 while (mgp != 0) {
1085 1088 if (mdb_vread(&mg, sizeof (mac_group_t), mgp) == -1) {
1086 1089 mdb_warn("failed to read mac_group_t at %p", mgp);
1087 1090 return (WALK_ERR);
1088 1091 }
1089 1092
1090 1093 ret = wsp->walk_callback(mgp, &mg, wsp->walk_cbdata);
1091 1094 if (ret != WALK_NEXT)
1092 1095 return (ret);
1093 1096 mgp = (uintptr_t)mg.mrg_next;
1094 1097 }
1095 1098
1096 1099 mgp = (uintptr_t)mi.mi_tx_groups;
1097 1100 while (mgp != 0) {
1098 1101 if (mdb_vread(&mg, sizeof (mac_group_t), mgp) == -1) {
1099 1102 mdb_warn("failed to read mac_group_t at %p", mgp);
1100 1103 return (WALK_ERR);
1101 1104 }
1102 1105
1103 1106 ret = wsp->walk_callback(mgp, &mg, wsp->walk_cbdata);
1104 1107 if (ret != WALK_NEXT)
1105 1108 return (ret);
1106 1109 mgp = (uintptr_t)mg.mrg_next;
1107 1110 }
1108 1111
1109 1112 return (WALK_NEXT);
1110 1113 }
1111 1114
1112 1115 static int
1113 1116 mac_group_count_clients(mac_group_t *mgp)
1114 1117 {
1115 1118 int clients = 0;
1116 1119 uintptr_t mcp = (uintptr_t)mgp->mrg_clients;
1117 1120
1118 1121 while (mcp != 0) {
1119 1122 mac_grp_client_t c;
1120 1123
1121 1124 if (mdb_vread(&c, sizeof (c), mcp) == -1) {
1122 1125 mdb_warn("failed to read mac_grp_client_t at %p", mcp);
1123 1126 return (-1);
1124 1127 }
1125 1128 clients++;
1126 1129 mcp = (uintptr_t)c.mgc_next;
1127 1130 }
1128 1131
1129 1132 return (clients);
1130 1133 }
1131 1134
1132 1135 static const char *
1133 1136 mac_group_type(mac_group_t *mgp)
1134 1137 {
1135 1138 const char *ret;
1136 1139
1137 1140 switch (mgp->mrg_type) {
1138 1141 case MAC_RING_TYPE_RX:
1139 1142 ret = "RECEIVE";
1140 1143 break;
1141 1144 case MAC_RING_TYPE_TX:
1142 1145 ret = "TRANSMIT";
1143 1146 break;
1144 1147 default:
1145 1148 ret = "UNKNOWN";
1146 1149 break;
1147 1150 }
1148 1151
1149 1152 return (ret);
1150 1153 }
1151 1154
1152 1155 static const char *
1153 1156 mac_group_state(mac_group_t *mgp)
1154 1157 {
1155 1158 const char *ret;
1156 1159
1157 1160 switch (mgp->mrg_state) {
1158 1161 case MAC_GROUP_STATE_UNINIT:
1159 1162 ret = "UNINT";
1160 1163 break;
1161 1164 case MAC_GROUP_STATE_REGISTERED:
1162 1165 ret = "REGISTERED";
1163 1166 break;
1164 1167 case MAC_GROUP_STATE_RESERVED:
1165 1168 ret = "RESERVED";
1166 1169 break;
1167 1170 case MAC_GROUP_STATE_SHARED:
1168 1171 ret = "SHARED";
1169 1172 break;
1170 1173 default:
1171 1174 ret = "UNKNOWN";
1172 1175 break;
1173 1176 }
1174 1177
1175 1178 return (ret);
1176 1179 }
1177 1180
1178 1181 static int
1179 1182 mac_group_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1180 1183 {
1181 1184 uint_t args = MAC_SRS_NONE;
1182 1185 mac_group_t mg;
1183 1186 int clients;
1184 1187
1185 1188 if (!(flags & DCMD_ADDRSPEC)) {
1186 1189 if (mdb_walk_dcmd("mac_group", "mac_group", argc, argv) == -1) {
1187 1190 mdb_warn("failed to walk 'mac_group'");
1188 1191 return (DCMD_ERR);
1189 1192 }
1190 1193
1191 1194 return (DCMD_OK);
1192 1195 }
1193 1196
1194 1197 if (mdb_getopts(argc, argv,
1195 1198 'r', MDB_OPT_SETBITS, MAC_GROUP_RX, &args,
1196 1199 't', MDB_OPT_SETBITS, MAC_GROUP_TX, &args,
1197 1200 'u', MDB_OPT_SETBITS, MAC_GROUP_UNINIT, &args,
1198 1201 NULL) != argc)
1199 1202 return (DCMD_USAGE);
1200 1203
1201 1204 if (mdb_vread(&mg, sizeof (mac_group_t), addr) == -1) {
1202 1205 mdb_warn("failed to read mac_group_t at %p", addr);
1203 1206 return (DCMD_ERR);
1204 1207 }
1205 1208
1206 1209 if (DCMD_HDRSPEC(flags) && !(flags & DCMD_PIPE_OUT)) {
1207 1210 mdb_printf("%<u>%-?s %-8s %-10s %6s %8s %-?s%</u>\n",
1208 1211 "ADDR", "TYPE", "STATE", "NRINGS", "NCLIENTS", "RINGS");
1209 1212 }
1210 1213
1211 1214 if ((args & MAC_GROUP_RX) != 0 && mg.mrg_type != MAC_RING_TYPE_RX)
1212 1215 return (DCMD_OK);
1213 1216 if ((args & MAC_GROUP_TX) != 0 && mg.mrg_type != MAC_RING_TYPE_TX)
1214 1217 return (DCMD_OK);
1215 1218
1216 1219 /*
1217 1220 * By default, don't show uninitialized groups. They're not very
1218 1221 * interesting. They have no rings and no clients.
1219 1222 */
1220 1223 if (mg.mrg_state == MAC_GROUP_STATE_UNINIT &&
1221 1224 (args & MAC_GROUP_UNINIT) == 0)
1222 1225 return (DCMD_OK);
1223 1226
1224 1227 if (flags & DCMD_PIPE_OUT) {
1225 1228 mdb_printf("%lr\n", addr);
1226 1229 return (DCMD_OK);
1227 1230 }
1228 1231
1229 1232 clients = mac_group_count_clients(&mg);
1230 1233 mdb_printf("%?p %-8s %-10s %6d %8d %?p\n", addr, mac_group_type(&mg),
1231 1234 mac_group_state(&mg), mg.mrg_cur_count, clients, mg.mrg_rings);
1232 1235
1233 1236 return (DCMD_OK);
1234 1237 }
1235 1238
1236 1239 /* Supported dee-commands */
1237 1240 static const mdb_dcmd_t dcmds[] = {
1238 1241 {"mac_flow", "?[-u] [-aprtsm]", "display Flow Entry structures",
1239 1242 mac_flow_dcmd, mac_flow_help},
1240 1243 {"mac_group", "?[-rtu]", "display MAC Ring Groups", mac_group_dcmd,
1241 1244 NULL },
1242 1245 {"mac_srs", "?[ -r[i|s|c[v]] | -t[i|s|c[v]] ]",
1243 1246 "display MAC Soft Ring Set" " structures", mac_srs_dcmd,
1244 1247 mac_srs_help},
1245 1248 {"mac_ring", "?", "display MAC ring (hardware) structures",
1246 1249 mac_ring_dcmd, mac_ring_help},
1247 1250 { NULL }
1248 1251 };
1249 1252
1250 1253 /* Supported walkers */
1251 1254 static const mdb_walker_t walkers[] = {
1252 1255 {"mac_flow", "walk list of flow entry structures", mac_flow_walk_init,
1253 1256 mac_common_walk_step, NULL, NULL},
1254 1257 {"mac_group", "walk list of ring group structures", mac_group_walk_init,
1255 1258 mac_group_walk_step, NULL, NULL},
1256 1259 {"mac_srs", "walk list of mac soft ring set structures",
1257 1260 mac_srs_walk_init, mac_common_walk_step, NULL, NULL},
1258 1261 {"mac_ring", "walk list of mac ring structures", mac_ring_walk_init,
1259 1262 mac_common_walk_step, NULL, NULL},
1260 1263 { NULL }
1261 1264 };
1262 1265
1263 1266 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
1264 1267
1265 1268 const mdb_modinfo_t *
1266 1269 _mdb_init(void)
1267 1270 {
1268 1271 return (&modinfo);
1269 1272 }
↓ open down ↓ |
290 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX