Print this page
MFV: illumos-joyent@757454db6669c1186f60bc625510c1b67217aae6
OS-7082 i40e: blown assert in i40e_tx_cleanup_ring()
OS-7086 i40e: add mdb dcmd to dump info on tx descriptor rings
OS-7101 i40e: add kstat to track TX DMA bind failures
Reviewed by: Ryan Zezeski <rpz@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
Author: Rob Johnston <rob.johnston@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/mdb/intel/modules/i40e/i40e.c
+++ new/usr/src/cmd/mdb/intel/modules/i40e/i40e.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2016 Joyent, Inc.
13 + * Copyright 2018 Joyent, Inc.
14 14 */
15 15
16 +#include <mdb/mdb_ctf.h>
16 17 #include <sys/mdb_modapi.h>
17 18 #include "i40e_sw.h"
18 19
19 20 #define RSRC_MAX 0x13
20 21 static const char *i40e_switch_rsrc_names[] = {
21 22 "VEBs",
22 23 "VSIs",
23 24 "Perfect Match MAC Addresses",
24 25 "S-Tags",
25 26 "Reserved",
26 27 "Multicast Hash Entries",
27 28 "Reserved",
28 29 "VLANs",
29 30 "VSI Lists",
30 31 "Reserved",
31 32 "VLAN Stat pools",
32 33 "Mirror rules",
33 34 "Queue sets",
34 35 "Inner VLAN Forwarding",
35 36 "Reserved",
36 37 "Inner MACs",
37 38 "IPs",
38 39 "GRE/VN1 Keys",
39 40 "VN2 Keys",
40 41 "Tunnelling Ports"
41 42 };
42 43
43 44 /*
44 45 * i40e mdb dcmds
45 46 */
46 47 /* ARGSUSED */
47 48 static int
48 49 i40e_switch_rsrcs_dcmd(uintptr_t addr, uint_t flags, int argc,
49 50 const mdb_arg_t *argv)
50 51 {
51 52 i40e_t i40e;
52 53 int i;
53 54
54 55 if (!(flags & DCMD_ADDRSPEC)) {
55 56 mdb_warn("::i40e_switch_rsrcs does not operate globally\n");
56 57 return (DCMD_USAGE);
57 58 }
58 59
59 60 if (mdb_vread(&i40e, sizeof (i40e_t), addr) != sizeof (i40e_t)) {
60 61 mdb_warn("failed to read i40e_t at %p", addr);
61 62 return (DCMD_ERR);
62 63 }
63 64
64 65 mdb_printf("%-28s %-12s %-8s %-8s %s\n", "TYPE", "GUARANTEE",
65 66 "TOTAL", "USED", "UNALLOCED");
66 67
67 68 for (i = 0; i < i40e.i40e_switch_rsrc_actual; i++) {
68 69 i40e_switch_rsrc_t rsrc;
69 70 uintptr_t raddr = (uintptr_t)i40e.i40e_switch_rsrcs +
70 71 i * sizeof (i40e_switch_rsrc_t);
71 72 const char *name;
72 73
73 74 if (mdb_vread(&rsrc, sizeof (i40e_switch_rsrc_t), raddr) !=
74 75 sizeof (i40e_switch_rsrc_t)) {
75 76 mdb_warn("failed to read i40e_switch_rsrc_t %d at %p",
76 77 i, raddr);
77 78 return (DCMD_ERR);
78 79 }
79 80
80 81 if (rsrc.resource_type <= RSRC_MAX) {
81 82 name = i40e_switch_rsrc_names[rsrc.resource_type];
82 83 } else {
83 84 char *buf;
84 85 size_t s = mdb_snprintf(NULL, 0, "Unknown type (%d)",
85 86 rsrc.resource_type);
86 87 buf = mdb_alloc(s + 1, UM_GC | UM_SLEEP);
87 88 (void) mdb_snprintf(buf, s + 1, "Unknown type (%d)",
88 89 rsrc.resource_type);
89 90 name = buf;
|
↓ open down ↓ |
64 lines elided |
↑ open up ↑ |
90 91 }
91 92
92 93 mdb_printf("%-28s %-12d %-8d %-8d %d\n", name,
93 94 LE_16(rsrc.guaranteed), LE_16(rsrc.total), LE_16(rsrc.used),
94 95 LE_16(rsrc.total_unalloced));
95 96 }
96 97
97 98 return (DCMD_OK);
98 99 }
99 100
101 +typedef struct mdb_i40e_trqpair {
102 + uint32_t itrq_tx_ring_size;
103 + uint32_t itrq_desc_free;
104 + uint32_t *itrq_desc_wbhead;
105 + uint32_t itrq_desc_head;
106 + uint32_t itrq_desc_tail;
107 + i40e_tx_desc_t *itrq_desc_ring;
108 + i40e_tx_control_block_t **itrq_tcb_work_list;
109 +} mdb_i40e_trqpair_t;
110 +
111 +static void
112 +i40e_tx_ring_help()
113 +{
114 + mdb_printf(
115 + "\t -a dump all ring entries\n"
116 + "\t or\n"
117 + "\t combine -b [start index] with -e [end index] to specify a \n"
118 + "\t range of ring entries to print\n");
119 +}
120 +
121 +static int
122 +i40e_tx_ring_dcmd(uintptr_t addr, uint_t flags, int argc,
123 + const mdb_arg_t *argv)
124 +{
125 + mdb_i40e_trqpair_t trq;
126 + i40e_tx_desc_t *descring;
127 + i40e_tx_control_block_t **wklist;
128 + uint32_t wbhead;
129 + size_t ringsz, wklistsz;
130 + boolean_t opt_a = B_FALSE;
131 + char *opt_b = NULL, *opt_e = NULL;
132 + uint64_t begin = UINT64_MAX, end = UINT64_MAX;
133 +
134 + if (!(flags & DCMD_ADDRSPEC)) {
135 + mdb_warn("::i40e_tx_ring does not operate globally\n");
136 + return (DCMD_USAGE);
137 + }
138 +
139 + if (mdb_getopts(argc, argv,
140 + 'a', MDB_OPT_SETBITS, B_TRUE, &opt_a,
141 + 'b', MDB_OPT_STR, &opt_b,
142 + 'e', MDB_OPT_STR, &opt_e, NULL) != argc)
143 + return (DCMD_USAGE);
144 +
145 + /*
146 + * Verify that a legal combination of -a/-b/-e were used.
147 + */
148 + if (opt_a && (opt_b != NULL || opt_e != NULL)) {
149 + mdb_warn("-a and -b/-e are mutually exclusive\n");
150 + return (DCMD_USAGE);
151 + }
152 + if (argc > 0 && ! opt_a && (opt_b == NULL || opt_e == NULL)) {
153 + mdb_warn("-b/-e must both be specified\n");
154 + return (DCMD_USAGE);
155 + }
156 +
157 + if (mdb_ctf_vread(&trq, "i40e_trqpair_t", "mdb_i40e_trqpair_t", addr,
158 + 0) == -1) {
159 + mdb_warn("failed to read i40e_trqpair_t at %p", addr);
160 + return (DCMD_ERR);
161 + }
162 +
163 + if (opt_b != NULL)
164 + begin = mdb_strtoull(opt_b);
165 + if (opt_e != NULL)
166 + end = mdb_strtoull(opt_e);
167 + if (opt_a) {
168 + begin = 0;
169 + end = trq.itrq_tx_ring_size - 1;
170 + }
171 +
172 + /*
173 + * Verify that the requested range of ring entries makes sense.
174 + */
175 + if (argc > 0 && (end < begin || begin >= trq.itrq_tx_ring_size ||
176 + end >= trq.itrq_tx_ring_size)) {
177 + mdb_warn("invalid range specified\n");
178 + return (DCMD_USAGE);
179 + }
180 +
181 + if (mdb_vread(&wbhead, sizeof (uint32_t),
182 + (uintptr_t)trq.itrq_desc_wbhead) != sizeof (uint32_t)) {
183 + mdb_warn("failed to read trq.itrq_desc_wbhead");
184 + return (DCMD_ERR);
185 + }
186 + mdb_printf("%-20s%d\n", "Ring Size:", trq.itrq_tx_ring_size);
187 + mdb_printf("%-20s%d\n", "Free Descriptors:", trq.itrq_desc_free);
188 + mdb_printf("%-20s%d\n", "Writeback Head:", wbhead);
189 + mdb_printf("%-20s%d\n", "Head:", trq.itrq_desc_head);
190 + mdb_printf("%-20s%d\n", "Tail:", trq.itrq_desc_tail);
191 +
192 + /*
193 + * No arguments were specified, so we're done.
194 + */
195 + if (argc == 0)
196 + return (DCMD_OK);
197 +
198 + /*
199 + * Allocate memory and read in the entire TX descriptor ring and
200 + * TCB work list.
201 + */
202 + ringsz = sizeof (i40e_tx_desc_t) * trq.itrq_tx_ring_size;
203 + descring = mdb_alloc(ringsz, UM_SLEEP);
204 + if (mdb_vread(descring, ringsz, (uintptr_t)trq.itrq_desc_ring) !=
205 + ringsz) {
206 + mdb_warn("Failed to read in TX decriptor ring\n");
207 + mdb_free(descring, ringsz);
208 + return (DCMD_ERR);
209 + }
210 + wklistsz = sizeof (i40e_tx_control_block_t *) * trq.itrq_tx_ring_size;
211 + wklist = mdb_alloc(wklistsz, UM_SLEEP);
212 + if (mdb_vread(wklist, wklistsz, (uintptr_t)trq.itrq_tcb_work_list) !=
213 + wklistsz) {
214 + mdb_warn("Failed to read in TX TCB work list\n");
215 + mdb_free(descring, ringsz);
216 + mdb_free(wklist, wklistsz);
217 + return (DCMD_ERR);
218 + }
219 +
220 + mdb_printf("\n%-10s %-10s %-16s %-16s %-10s\n", "Index", "Desc Type",
221 + "Desc Ptr", "TCB Ptr", "Other");
222 + for (uint64_t i = begin; i <= end; i++) {
223 + const char *dtype;
224 + char dother[17];
225 + i40e_tx_desc_t *dptr;
226 + i40e_tx_control_block_t *tcbptr;
227 + uint64_t ctob;
228 +
229 + dptr = &descring[i];
230 + tcbptr = wklist[i];
231 + ctob = LE_64(dptr->cmd_type_offset_bsz);
232 + if (ctob == 0) {
233 + dtype = "FREE";
234 + } else {
235 + switch (ctob & I40E_TXD_QW1_DTYPE_MASK) {
236 + case (I40E_TX_DESC_DTYPE_CONTEXT):
237 + dtype = "CONTEXT";
238 + break;
239 + case (I40E_TX_DESC_DTYPE_DATA):
240 + dtype = "DATA";
241 + break;
242 + case (I40E_TX_DESC_DTYPE_FILTER_PROG):
243 + dtype = "FILTER";
244 + break;
245 + default:
246 + dtype = "UNKNOWN";
247 + }
248 + }
249 + dother[0] = '\0';
250 + if (i == wbhead)
251 + (void) strcat(dother, "WBHEAD");
252 +
253 + if (i == trq.itrq_desc_head)
254 + (void) strcat(dother,
255 + strlen(dother) > 0 ? " HEAD" : "HEAD");
256 +
257 + if (i == trq.itrq_desc_tail)
258 + (void) strcat(dother,
259 + strlen(dother) > 0 ? " TAIL" : "TAIL");
260 +
261 + mdb_printf("%-10d %-10s %-16p %-16p %-10s\n", i, dtype, dptr,
262 + tcbptr, dother);
263 + }
264 +
265 + mdb_free(descring, ringsz);
266 + mdb_free(wklist, wklistsz);
267 + return (DCMD_OK);
268 +}
269 +
100 270 static const mdb_dcmd_t i40e_dcmds[] = {
101 271 { "i40e_switch_rsrcs", NULL, "print switch resources",
102 272 i40e_switch_rsrcs_dcmd, NULL },
273 + { "i40e_tx_ring", "[-a] -b [start index] -e [end index]\n",
274 + "dump TX descriptor ring state", i40e_tx_ring_dcmd,
275 + i40e_tx_ring_help },
103 276 { NULL }
104 277 };
105 278
106 279 static const mdb_modinfo_t i40e_modinfo = {
107 280 MDB_API_VERSION, i40e_dcmds, NULL
108 281 };
109 282
110 283 const mdb_modinfo_t *
111 284 _mdb_init(void)
112 285 {
113 286 return (&i40e_modinfo);
114 287 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX