Print this page
10052 "dladm show-ether" should pick one kstat snapshot and stick with it
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gergo Doma <domag02@gmail.com>
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdladm/common/libdlstat.c
+++ new/usr/src/lib/libdladm/common/libdlstat.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
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
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
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 24 */
25 25
26 +/*
27 + * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
28 + */
29 +
26 30 #include <stddef.h>
27 31 #include <stdio.h>
28 32 #include <stdlib.h>
29 33 #include <strings.h>
30 34 #include <err.h>
31 35 #include <errno.h>
32 36 #include <fcntl.h>
33 37 #include <kstat.h>
34 38 #include <limits.h>
35 39 #include <unistd.h>
36 40 #include <signal.h>
37 41 #include <sys/dld.h>
38 42 #include <sys/ddi.h>
39 43
40 44 #include <libdllink.h>
41 45 #include <libdlflow.h>
42 46 #include <libdlstat.h>
43 47 #include <libdlaggr.h>
44 48
45 49 struct flowlist {
46 50 char flowname[MAXFLOWNAMELEN];
47 51 char linkname[MAXLINKNAMELEN];
48 52 datalink_id_t linkid;
49 53 int fd;
50 54 uint64_t ifspeed;
51 55 boolean_t first;
52 56 boolean_t display;
53 57 pktsum_t prevstats;
54 58 pktsum_t diffstats;
55 59 };
56 60
57 61 pktsum_t totalstats;
58 62 struct flowlist *stattable = NULL;
59 63
60 64 #define STATGROWSIZE 16
61 65
62 66 /* Exported functions */
63 67
64 68 /*
65 69 * dladm_kstat_lookup() is a modified version of kstat_lookup which
66 70 * adds the class as a selector.
67 71 */
68 72 kstat_t *
69 73 dladm_kstat_lookup(kstat_ctl_t *kcp, const char *module, int instance,
70 74 const char *name, const char *class)
71 75 {
72 76 kstat_t *ksp = NULL;
73 77
74 78 for (ksp = kcp->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
75 79 if ((module == NULL || strcmp(ksp->ks_module, module) == 0) &&
76 80 (instance == -1 || ksp->ks_instance == instance) &&
77 81 (name == NULL || strcmp(ksp->ks_name, name) == 0) &&
78 82 (class == NULL || strcmp(ksp->ks_class, class) == 0))
79 83 return (ksp);
80 84 }
81 85
82 86 errno = ENOENT;
83 87 return (NULL);
84 88 }
85 89
86 90 /*
87 91 * dladm_get_stats() populates the supplied pktsum_t structure with
88 92 * the input and output packet and byte kstats from the kstat_t
89 93 * found with dladm_kstat_lookup.
90 94 */
91 95 void
92 96 dladm_get_stats(kstat_ctl_t *kcp, kstat_t *ksp, pktsum_t *stats)
93 97 {
94 98
95 99 if (kstat_read(kcp, ksp, NULL) == -1)
96 100 return;
97 101
98 102 stats->snaptime = gethrtime();
99 103
100 104 if (dladm_kstat_value(ksp, "ipackets64", KSTAT_DATA_UINT64,
101 105 &stats->ipackets) < 0) {
102 106 if (dladm_kstat_value(ksp, "ipackets", KSTAT_DATA_UINT64,
103 107 &stats->ipackets) < 0)
104 108 return;
105 109 }
106 110
107 111 if (dladm_kstat_value(ksp, "opackets64", KSTAT_DATA_UINT64,
108 112 &stats->opackets) < 0) {
109 113 if (dladm_kstat_value(ksp, "opackets", KSTAT_DATA_UINT64,
110 114 &stats->opackets) < 0)
111 115 return;
112 116 }
113 117
114 118 if (dladm_kstat_value(ksp, "rbytes64", KSTAT_DATA_UINT64,
115 119 &stats->rbytes) < 0) {
116 120 if (dladm_kstat_value(ksp, "rbytes", KSTAT_DATA_UINT64,
117 121 &stats->rbytes) < 0)
118 122 return;
119 123 }
120 124
121 125 if (dladm_kstat_value(ksp, "obytes64", KSTAT_DATA_UINT64,
122 126 &stats->obytes) < 0) {
123 127 if (dladm_kstat_value(ksp, "obytes", KSTAT_DATA_UINT64,
124 128 &stats->obytes) < 0)
125 129 return;
126 130 }
127 131
128 132 if (dladm_kstat_value(ksp, "ierrors", KSTAT_DATA_UINT32,
129 133 &stats->ierrors) < 0) {
130 134 if (dladm_kstat_value(ksp, "ierrors", KSTAT_DATA_UINT64,
131 135 &stats->ierrors) < 0)
132 136 return;
133 137 }
134 138
135 139 if (dladm_kstat_value(ksp, "oerrors", KSTAT_DATA_UINT32,
136 140 &stats->oerrors) < 0) {
137 141 if (dladm_kstat_value(ksp, "oerrors", KSTAT_DATA_UINT64,
138 142 &stats->oerrors) < 0)
139 143 return;
140 144 }
141 145 }
142 146
143 147 int
144 148 dladm_kstat_value(kstat_t *ksp, const char *name, uint8_t type, void *buf)
145 149 {
146 150 kstat_named_t *knp;
147 151
148 152 if ((knp = kstat_data_lookup(ksp, (char *)name)) == NULL)
149 153 return (-1);
150 154
151 155 if (knp->data_type != type)
152 156 return (-1);
153 157
154 158 switch (type) {
155 159 case KSTAT_DATA_UINT64:
156 160 *(uint64_t *)buf = knp->value.ui64;
157 161 break;
158 162 case KSTAT_DATA_UINT32:
159 163 *(uint32_t *)buf = knp->value.ui32;
160 164 break;
161 165 default:
↓ open down ↓ |
126 lines elided |
↑ open up ↑ |
162 166 return (-1);
163 167 }
164 168
165 169 return (0);
166 170 }
167 171
168 172 dladm_status_t
169 173 dladm_get_single_mac_stat(dladm_handle_t handle, datalink_id_t linkid,
170 174 const char *name, uint8_t type, void *val)
171 175 {
172 - kstat_ctl_t *kcp;
173 176 char module[DLPI_LINKNAME_MAX];
174 177 uint_t instance;
175 178 char link[DLPI_LINKNAME_MAX];
176 179 dladm_status_t status;
177 180 uint32_t flags, media;
178 181 kstat_t *ksp;
179 182 dladm_phys_attr_t dpap;
180 183
181 184 if ((status = dladm_datalink_id2info(handle, linkid, &flags, NULL,
182 185 &media, link, DLPI_LINKNAME_MAX)) != DLADM_STATUS_OK)
183 186 return (status);
184 187
185 188 if (media != DL_ETHER)
186 189 return (DLADM_STATUS_LINKINVAL);
187 190
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
188 191 status = dladm_phys_info(handle, linkid, &dpap, DLADM_OPT_PERSIST);
189 192
190 193 if (status != DLADM_STATUS_OK)
191 194 return (status);
192 195
193 196 status = dladm_parselink(dpap.dp_dev, module, &instance);
194 197
195 198 if (status != DLADM_STATUS_OK)
196 199 return (status);
197 200
198 - if ((kcp = kstat_open()) == NULL) {
199 - warn("kstat_open operation failed");
200 - return (-1);
201 - }
202 -
203 201 /*
204 202 * The kstat query could fail if the underlying MAC
205 203 * driver was already detached.
206 204 */
207 - if ((ksp = kstat_lookup(kcp, module, instance, "mac")) == NULL &&
208 - (ksp = kstat_lookup(kcp, module, instance, NULL)) == NULL)
205 + if (dladm_dld_kcp(handle) == NULL) {
206 + warn("kstat_open operation failed");
207 + return (-1);
208 + }
209 +
210 + if ((ksp = kstat_lookup(dladm_dld_kcp(handle), module, instance,
211 + "mac")) == NULL &&
212 + (ksp = kstat_lookup(dladm_dld_kcp(handle), module, instance,
213 + NULL)) == NULL)
209 214 goto bail;
210 215
211 - if (kstat_read(kcp, ksp, NULL) == -1)
216 + if (kstat_read(dladm_dld_kcp(handle), ksp, NULL) == -1)
212 217 goto bail;
213 218
214 219 if (dladm_kstat_value(ksp, name, type, val) < 0)
215 220 goto bail;
216 221
217 - (void) kstat_close(kcp);
218 222 return (DLADM_STATUS_OK);
219 223
220 224 bail:
221 - (void) kstat_close(kcp);
222 225 return (dladm_errno2status(errno));
223 226 }
224 227
225 228 /* Compute sum of 2 pktsums (s1 = s2 + s3) */
226 229 void
227 230 dladm_stats_total(pktsum_t *s1, pktsum_t *s2, pktsum_t *s3)
228 231 {
229 232 s1->rbytes = s2->rbytes + s3->rbytes;
230 233 s1->ipackets = s2->ipackets + s3->ipackets;
231 234 s1->ierrors = s2->ierrors + s3->ierrors;
232 235 s1->obytes = s2->obytes + s3->obytes;
233 236 s1->opackets = s2->opackets + s3->opackets;
234 237 s1->oerrors = s2->oerrors + s3->oerrors;
235 238 s1->snaptime = s2->snaptime;
236 239 }
237 240
238 241 #define DIFF_STAT(s2, s3) ((s2) > (s3) ? ((s2) - (s3)) : 0)
239 242
240 243
241 244 /* Compute differences between 2 pktsums (s1 = s2 - s3) */
242 245 void
243 246 dladm_stats_diff(pktsum_t *s1, pktsum_t *s2, pktsum_t *s3)
244 247 {
245 248 s1->rbytes = DIFF_STAT(s2->rbytes, s3->rbytes);
246 249 s1->ipackets = DIFF_STAT(s2->ipackets, s3->ipackets);
247 250 s1->ierrors = DIFF_STAT(s2->ierrors, s3->ierrors);
248 251 s1->obytes = DIFF_STAT(s2->obytes, s3->obytes);
249 252 s1->opackets = DIFF_STAT(s2->opackets, s3->opackets);
250 253 s1->oerrors = DIFF_STAT(s2->oerrors, s3->oerrors);
251 254 s1->snaptime = DIFF_STAT(s2->snaptime, s3->snaptime);
252 255 }
253 256
254 257 #define DLSTAT_MAC_RX_SWLANE "mac_rx_swlane"
255 258 #define DLSTAT_MAC_RX_HWLANE "mac_rx_hwlane"
256 259 #define DLSTAT_MAC_TX_SWLANE "mac_tx_swlane"
257 260 #define DLSTAT_MAC_TX_HWLANE "mac_tx_hwlane"
258 261 #define DLSTAT_MAC_MISC_STAT "mac_misc_stat"
259 262 #define DLSTAT_MAC_RX_RING "mac_rx_ring"
260 263 #define DLSTAT_MAC_TX_RING "mac_tx_ring"
261 264 #define DLSTAT_MAC_FANOUT "mac_rx_swlane0_fanout"
262 265
263 266 typedef struct {
264 267 const char *si_name;
265 268 uint_t si_offset;
266 269 } stat_info_t;
267 270
268 271 #define A_CNT(arr) (sizeof (arr) / sizeof (arr[0]))
269 272
270 273 /* Definitions for rx lane stats */
271 274 #define RL_OFF(f) (offsetof(rx_lane_stat_t, f))
272 275
273 276 static stat_info_t rx_hwlane_stats_list[] = {
274 277 {"ipackets", RL_OFF(rl_ipackets)},
275 278 {"rbytes", RL_OFF(rl_rbytes)},
276 279 {"intrs", RL_OFF(rl_intrs)},
277 280 {"intrbytes", RL_OFF(rl_intrbytes)},
278 281 {"polls", RL_OFF(rl_polls)},
279 282 {"pollbytes", RL_OFF(rl_pollbytes)},
280 283 {"rxsdrops", RL_OFF(rl_sdrops)},
281 284 {"chainunder10", RL_OFF(rl_chl10)},
282 285 {"chain10to50", RL_OFF(rl_ch10_50)},
283 286 {"chainover50", RL_OFF(rl_chg50)}
284 287 };
285 288 #define RX_HWLANE_STAT_SIZE A_CNT(rx_hwlane_stats_list)
286 289
287 290 static stat_info_t rx_swlane_stats_list[] = {
288 291 {"ipackets", RL_OFF(rl_ipackets)},
289 292 {"rbytes", RL_OFF(rl_rbytes)},
290 293 {"local", RL_OFF(rl_lclpackets)},
291 294 {"localbytes", RL_OFF(rl_lclbytes)},
292 295 {"intrs", RL_OFF(rl_intrs)},
293 296 {"intrbytes", RL_OFF(rl_intrbytes)},
294 297 {"rxsdrops", RL_OFF(rl_sdrops)}
295 298 };
296 299 #define RX_SWLANE_STAT_SIZE A_CNT(rx_swlane_stats_list)
297 300
298 301 static stat_info_t rx_lane_stats_list[] = {
299 302 {"ipackets", RL_OFF(rl_ipackets)},
300 303 {"rbytes", RL_OFF(rl_rbytes)},
301 304 {"local", RL_OFF(rl_lclpackets)},
302 305 {"localbytes", RL_OFF(rl_lclbytes)},
303 306 {"intrs", RL_OFF(rl_intrs)},
304 307 {"intrbytes", RL_OFF(rl_intrbytes)},
305 308 {"polls", RL_OFF(rl_polls)},
306 309 {"rxsdrops", RL_OFF(rl_sdrops)},
307 310 {"pollbytes", RL_OFF(rl_pollbytes)},
308 311 {"chainunder10", RL_OFF(rl_chl10)},
309 312 {"chain10to50", RL_OFF(rl_ch10_50)},
310 313 {"chainover50", RL_OFF(rl_chg50)}
311 314 };
312 315 #define RX_LANE_STAT_SIZE A_CNT(rx_lane_stats_list)
313 316
314 317 /* Definitions for tx lane stats */
315 318 #define TL_OFF(f) (offsetof(tx_lane_stat_t, f))
316 319
317 320 static stat_info_t tx_lane_stats_list[] = {
318 321 {"opackets", TL_OFF(tl_opackets)},
319 322 {"obytes", TL_OFF(tl_obytes)},
320 323 {"blockcnt", TL_OFF(tl_blockcnt)},
321 324 {"unblockcnt", TL_OFF(tl_unblockcnt)},
322 325 {"txsdrops", TL_OFF(tl_sdrops)}
323 326 };
324 327 #define TX_LANE_STAT_SIZE A_CNT(tx_lane_stats_list)
325 328
326 329 /* Definitions for tx/rx misc stats */
327 330 #define M_OFF(f) (offsetof(misc_stat_t, f))
328 331
329 332 static stat_info_t misc_stats_list[] = {
330 333 {"multircv", M_OFF(ms_multircv)},
331 334 {"brdcstrcv", M_OFF(ms_brdcstrcv)},
332 335 {"multixmt", M_OFF(ms_multixmt)},
333 336 {"brdcstxmt", M_OFF(ms_brdcstxmt)},
334 337 {"multircvbytes", M_OFF(ms_multircvbytes)},
335 338 {"brdcstrcvbytes", M_OFF(ms_brdcstrcvbytes)},
336 339 {"multixmtbytes", M_OFF(ms_multixmtbytes)},
337 340 {"brdcstxmtbytes", M_OFF(ms_brdcstxmtbytes)},
338 341 {"txerrors", M_OFF(ms_txerrors)},
339 342 {"macspoofed", M_OFF(ms_macspoofed)},
340 343 {"ipspoofed", M_OFF(ms_ipspoofed)},
341 344 {"dhcpspoofed", M_OFF(ms_dhcpspoofed)},
342 345 {"restricted", M_OFF(ms_restricted)},
343 346 {"ipackets", M_OFF(ms_ipackets)},
344 347 {"rbytes", M_OFF(ms_rbytes)},
345 348 {"local", M_OFF(ms_local)},
346 349 {"localbytes", M_OFF(ms_localbytes)},
347 350 {"intrs", M_OFF(ms_intrs)},
348 351 {"intrbytes", M_OFF(ms_intrbytes)},
349 352 {"polls", M_OFF(ms_polls)},
350 353 {"pollbytes", M_OFF(ms_pollbytes)},
351 354 {"rxsdrops", M_OFF(ms_rxsdrops)},
352 355 {"chainunder10", M_OFF(ms_chainunder10)},
353 356 {"chain10to50", M_OFF(ms_chain10to50)},
354 357 {"chainover50", M_OFF(ms_chainover50)},
355 358 {"obytes", M_OFF(ms_obytes)},
356 359 {"opackets", M_OFF(ms_opackets)},
357 360 {"blockcnt", M_OFF(ms_blockcnt)},
358 361 {"unblockcnt", M_OFF(ms_unblockcnt)},
359 362 {"txsdrops", M_OFF(ms_txsdrops)}
360 363 };
361 364 #define MISC_STAT_SIZE A_CNT(misc_stats_list)
362 365
363 366 /* Definitions for rx ring stats */
364 367 #define R_OFF(f) (offsetof(ring_stat_t, f))
365 368
366 369 static stat_info_t rx_ring_stats_list[] = {
367 370 {"ipackets", R_OFF(r_packets)},
368 371 {"rbytes", R_OFF(r_bytes)}
369 372 };
370 373 #define RX_RING_STAT_SIZE A_CNT(rx_ring_stats_list)
371 374
372 375 /* Definitions for tx ring stats */
373 376 static stat_info_t tx_ring_stats_list[] = {
374 377 {"opackets", R_OFF(r_packets)},
375 378 {"obytes", R_OFF(r_bytes)}
376 379 };
377 380 #define TX_RING_STAT_SIZE A_CNT(tx_ring_stats_list)
378 381
379 382 /* Definitions for fanout stats */
380 383 #define F_OFF(f) (offsetof(fanout_stat_t, f))
381 384
382 385 static stat_info_t fanout_stats_list[] = {
383 386 {"ipackets", F_OFF(f_ipackets)},
384 387 {"rbytes", F_OFF(f_rbytes)},
385 388 };
386 389 #define FANOUT_STAT_SIZE A_CNT(fanout_stats_list)
387 390
388 391 /* Definitions for total stats */
389 392 #define T_OFF(f) (offsetof(total_stat_t, f))
390 393
391 394 static stat_info_t total_stats_list[] = {
392 395 {"ipackets", T_OFF(ts_ipackets)},
393 396 {"rbytes", T_OFF(ts_rbytes)},
394 397 {"opackets", T_OFF(ts_opackets)},
395 398 {"obytes", T_OFF(ts_obytes)}
396 399 };
397 400 #define TOTAL_STAT_SIZE A_CNT(total_stats_list)
398 401
399 402 /* Definitions for aggr stats */
400 403 #define AP_OFF(f) (offsetof(aggr_port_stat_t, f))
401 404
402 405 static stat_info_t aggr_port_stats_list[] = {
403 406 {"ipackets64", AP_OFF(ap_ipackets)},
404 407 {"rbytes64", AP_OFF(ap_rbytes)},
405 408 {"opackets64", AP_OFF(ap_opackets)},
406 409 {"obytes64", AP_OFF(ap_obytes)}
407 410 };
408 411 #define AGGR_PORT_STAT_SIZE A_CNT(aggr_port_stats_list)
409 412
410 413 /* Definitions for flow stats */
411 414 #define FL_OFF(f) (offsetof(flow_stat_t, f))
412 415
413 416 static stat_info_t flow_stats_list[] = {
414 417 {"ipackets", FL_OFF(fl_ipackets)},
415 418 {"rbytes", FL_OFF(fl_rbytes)},
416 419 {"opackets", FL_OFF(fl_opackets)},
417 420 {"obytes", FL_OFF(fl_obytes)}
418 421 };
419 422 #define FLOW_STAT_SIZE A_CNT(flow_stats_list)
420 423
421 424 /* Rx lane specific functions */
422 425 void * dlstat_rx_lane_stats(dladm_handle_t, datalink_id_t);
423 426 static boolean_t i_dlstat_rx_lane_match(void *, void *);
424 427 static void * i_dlstat_rx_lane_stat_entry_diff(void *, void *);
425 428
426 429 /* Tx lane specific functions */
427 430 void * dlstat_tx_lane_stats(dladm_handle_t, datalink_id_t);
428 431 static boolean_t i_dlstat_tx_lane_match(void *, void *);
429 432 static void * i_dlstat_tx_lane_stat_entry_diff(void *, void *);
430 433
431 434 /* Rx lane total specific functions */
432 435 void * dlstat_rx_lane_total_stats(dladm_handle_t,
433 436 datalink_id_t);
434 437
435 438 /* Tx lane total specific functions */
436 439 void * dlstat_tx_lane_total_stats(dladm_handle_t,
437 440 datalink_id_t);
438 441
439 442 /* Fanout specific functions */
440 443 void * dlstat_fanout_stats(dladm_handle_t, datalink_id_t);
441 444 static boolean_t i_dlstat_fanout_match(void *, void *);
442 445 static void * i_dlstat_fanout_stat_entry_diff(void *, void *);
443 446
444 447 /* Rx ring specific functions */
445 448 void * dlstat_rx_ring_stats(dladm_handle_t, datalink_id_t);
446 449 static boolean_t i_dlstat_rx_ring_match(void *, void *);
447 450 static void * i_dlstat_rx_ring_stat_entry_diff(void *, void *);
448 451
449 452 /* Tx ring specific functions */
450 453 void * dlstat_tx_ring_stats(dladm_handle_t, datalink_id_t);
451 454 static boolean_t i_dlstat_tx_ring_match(void *, void *);
452 455 static void * i_dlstat_tx_ring_stat_entry_diff(void *, void *);
453 456
454 457 /* Rx ring total specific functions */
455 458 void * dlstat_rx_ring_total_stats(dladm_handle_t,
456 459 datalink_id_t);
457 460
458 461 /* Tx ring total specific functions */
459 462 void * dlstat_tx_ring_total_stats(dladm_handle_t,
460 463 datalink_id_t);
461 464
462 465 /* Summary specific functions */
463 466 void * dlstat_total_stats(dladm_handle_t, datalink_id_t);
464 467 static boolean_t i_dlstat_total_match(void *, void *);
465 468 static void * i_dlstat_total_stat_entry_diff(void *, void *);
466 469
467 470 /* Aggr port specific functions */
468 471 void * dlstat_aggr_port_stats(dladm_handle_t, datalink_id_t);
469 472 static boolean_t i_dlstat_aggr_port_match(void *, void *);
470 473 static void * i_dlstat_aggr_port_stat_entry_diff(void *, void *);
471 474
472 475 /* Misc stat specific functions */
473 476 void * dlstat_misc_stats(dladm_handle_t, datalink_id_t);
474 477
475 478 typedef void * dladm_stat_query_t(dladm_handle_t, datalink_id_t);
476 479 typedef boolean_t dladm_stat_match_t(void *, void *);
477 480 typedef void * dladm_stat_diff_t(void *, void *);
478 481
479 482 typedef struct dladm_stat_desc_s {
480 483 dladm_stat_type_t ds_stattype;
481 484 dladm_stat_query_t *ds_querystat;
482 485 dladm_stat_match_t *ds_matchstat;
483 486 dladm_stat_diff_t *ds_diffstat;
484 487 uint_t ds_offset;
485 488 stat_info_t *ds_statlist;
486 489 uint_t ds_statsize;
487 490 } dladm_stat_desc_t;
488 491
489 492 /*
490 493 * dladm_stat_table has one entry for each supported stat. ds_querystat returns
491 494 * a chain of 'stat entries' for the queried stat.
492 495 * Each stat entry has set of identifiers (ids) and an object containing actual
493 496 * stat values. These stat entry objects are chained together in a linked list
494 497 * of datatype dladm_stat_chain_t. Head of this list is returned to the caller
495 498 * of dladm_link_stat_query.
496 499 *
497 500 * One node in the chain is shown below:
498 501 *
499 502 * -------------------------
500 503 * | dc_statentry |
501 504 * | -------------- |
502 505 * | | ids | |
503 506 * | -------------- |
504 507 * | | stat fields | |
505 508 * | -------------- |
506 509 * -------------------------
507 510 * | dc_next ---------|------> to next stat entry
508 511 * -------------------------
509 512 *
510 513 * In particular, for query DLADM_STAT_RX_LANE, dc_statentry carries pointer to
511 514 * object of type rx_lane_stat_entry_t.
512 515 *
513 516 * dladm_link_stat_query_all returns similar chain. However, instead of storing
514 517 * stat fields as raw numbers, it stores those as chain of <name, value> pairs.
515 518 * The resulting structure is depicted below:
516 519 *
517 520 * -------------------------
518 521 * | dc_statentry |
519 522 * | -------------- | ---------------
520 523 * | | nv_header | | | name, val |
521 524 * | -------------- | ---------------
522 525 * | | nve_stats---|----|-->| nv_nextstat--|---> to next name, val pair
523 526 * | -------------- | ---------------
524 527 * -------------------------
525 528 * | dc_next ---------|------> to next stat entry
526 529 * -------------------------
527 530 */
528 531 static dladm_stat_desc_t dladm_stat_table[] = {
529 532 { DLADM_STAT_RX_LANE, dlstat_rx_lane_stats,
530 533 i_dlstat_rx_lane_match, i_dlstat_rx_lane_stat_entry_diff,
531 534 offsetof(rx_lane_stat_entry_t, rle_stats),
532 535 rx_lane_stats_list, RX_LANE_STAT_SIZE},
533 536
534 537 { DLADM_STAT_TX_LANE, dlstat_tx_lane_stats,
535 538 i_dlstat_tx_lane_match, i_dlstat_tx_lane_stat_entry_diff,
536 539 offsetof(tx_lane_stat_entry_t, tle_stats),
537 540 tx_lane_stats_list, TX_LANE_STAT_SIZE},
538 541
539 542 { DLADM_STAT_RX_LANE_TOTAL, dlstat_rx_lane_total_stats,
540 543 i_dlstat_rx_lane_match, i_dlstat_rx_lane_stat_entry_diff,
541 544 offsetof(rx_lane_stat_entry_t, rle_stats),
542 545 rx_lane_stats_list, RX_LANE_STAT_SIZE},
543 546
544 547 { DLADM_STAT_TX_LANE_TOTAL, dlstat_tx_lane_total_stats,
545 548 i_dlstat_tx_lane_match, i_dlstat_tx_lane_stat_entry_diff,
546 549 offsetof(tx_lane_stat_entry_t, tle_stats),
547 550 tx_lane_stats_list, TX_LANE_STAT_SIZE},
548 551
549 552 { DLADM_STAT_RX_LANE_FOUT, dlstat_fanout_stats,
550 553 i_dlstat_fanout_match, i_dlstat_fanout_stat_entry_diff,
551 554 offsetof(fanout_stat_entry_t, fe_stats),
552 555 fanout_stats_list, FANOUT_STAT_SIZE},
553 556
554 557 { DLADM_STAT_RX_RING, dlstat_rx_ring_stats,
555 558 i_dlstat_rx_ring_match, i_dlstat_rx_ring_stat_entry_diff,
556 559 offsetof(ring_stat_entry_t, re_stats),
557 560 rx_ring_stats_list, RX_RING_STAT_SIZE},
558 561
559 562 { DLADM_STAT_TX_RING, dlstat_tx_ring_stats,
560 563 i_dlstat_tx_ring_match, i_dlstat_tx_ring_stat_entry_diff,
561 564 offsetof(ring_stat_entry_t, re_stats),
562 565 tx_ring_stats_list, TX_RING_STAT_SIZE},
563 566
564 567 { DLADM_STAT_RX_RING_TOTAL, dlstat_rx_ring_total_stats,
565 568 i_dlstat_rx_ring_match, i_dlstat_rx_ring_stat_entry_diff,
566 569 offsetof(ring_stat_entry_t, re_stats),
567 570 rx_ring_stats_list, RX_RING_STAT_SIZE},
568 571
569 572 { DLADM_STAT_TX_RING_TOTAL, dlstat_tx_ring_total_stats,
570 573 i_dlstat_tx_ring_match, i_dlstat_tx_ring_stat_entry_diff,
571 574 offsetof(ring_stat_entry_t, re_stats),
572 575 tx_ring_stats_list, TX_RING_STAT_SIZE},
573 576
574 577 { DLADM_STAT_TOTAL, dlstat_total_stats,
575 578 i_dlstat_total_match, i_dlstat_total_stat_entry_diff,
576 579 offsetof(total_stat_entry_t, tse_stats),
577 580 total_stats_list, TOTAL_STAT_SIZE},
578 581
579 582 { DLADM_STAT_AGGR_PORT, dlstat_aggr_port_stats,
580 583 i_dlstat_aggr_port_match, i_dlstat_aggr_port_stat_entry_diff,
581 584 offsetof(aggr_port_stat_entry_t, ape_stats),
582 585 aggr_port_stats_list, AGGR_PORT_STAT_SIZE},
583 586 /*
584 587 * We don't support -i <interval> query with misc stats. Several table fields
585 588 * are left uninitialized thus.
586 589 */
587 590 { DLADM_STAT_MISC, dlstat_misc_stats,
588 591 NULL, NULL,
589 592 0,
590 593 misc_stats_list, MISC_STAT_SIZE}
591 594 };
592 595
593 596 /* Internal functions */
594 597 static void *
595 598 dlstat_diff_stats(void *arg1, void *arg2, dladm_stat_type_t stattype)
596 599 {
597 600 return (dladm_stat_table[stattype].ds_diffstat(arg1, arg2));
598 601 }
599 602
600 603 static boolean_t
601 604 dlstat_match_stats(void *arg1, void *arg2, dladm_stat_type_t stattype)
602 605 {
603 606 return (dladm_stat_table[stattype].ds_matchstat(arg1, arg2));
604 607 }
605 608
606 609 /* Diff between two stats */
607 610 static void
608 611 i_dlstat_diff_stats(void *diff, void *op1, void *op2,
609 612 stat_info_t stats_list[], uint_t size)
610 613 {
611 614 int i;
612 615
613 616 for (i = 0; i < size; i++) {
614 617 uint64_t *op1_val = (void *)
615 618 ((uchar_t *)op1 + stats_list[i].si_offset);
616 619 uint64_t *op2_val = (void *)
617 620 ((uchar_t *)op2 + stats_list[i].si_offset);
618 621 uint64_t *diff_val = (void *)
619 622 ((uchar_t *)diff + stats_list[i].si_offset);
620 623
621 624 *diff_val = DIFF_STAT(*op1_val, *op2_val);
622 625 }
623 626 }
624 627
625 628 /*
626 629 * Perform diff = s1 - s2, where diff, s1, s2 are structure objects of same
627 630 * datatype. slist is list of offsets of the fields within the structure.
628 631 */
629 632 #define DLSTAT_DIFF_STAT(s1, s2, diff, f, slist, sz) { \
630 633 if (s2 == NULL) { \
631 634 bcopy(&s1->f, &diff->f, sizeof (s1->f)); \
632 635 } else { \
633 636 i_dlstat_diff_stats(&diff->f, &s1->f, \
634 637 &s2->f, slist, sz); \
635 638 } \
636 639 }
637 640
638 641 /* Sum two stats */
639 642 static void
640 643 i_dlstat_sum_stats(void *sum, void *op1, void *op2,
641 644 stat_info_t stats_list[], uint_t size)
642 645 {
643 646 int i;
644 647
645 648 for (i = 0; i < size; i++) {
646 649 uint64_t *op1_val = (void *)
647 650 ((uchar_t *)op1 + stats_list[i].si_offset);
648 651 uint64_t *op2_val = (void *)
649 652 ((uchar_t *)op2 + stats_list[i].si_offset);
650 653 uint64_t *sum_val = (void *)
651 654 ((uchar_t *)sum + stats_list[i].si_offset);
652 655
653 656 *sum_val = *op1_val + *op2_val;
654 657 }
655 658 }
656 659
657 660 /* Look up kstat value */
658 661 static void
659 662 i_dlstat_get_stats(kstat_ctl_t *kcp, kstat_t *ksp, void *stats,
660 663 stat_info_t stats_list[], uint_t size)
661 664 {
662 665 int i;
663 666
664 667 if (kstat_read(kcp, ksp, NULL) == -1)
665 668 return;
666 669
667 670 for (i = 0; i < size; i++) {
668 671 uint64_t *val = (void *)
669 672 ((uchar_t *)stats + stats_list[i].si_offset);
670 673
671 674 if (dladm_kstat_value(ksp, stats_list[i].si_name,
672 675 KSTAT_DATA_UINT64, val) < 0)
673 676 return;
674 677 }
675 678 }
676 679
677 680 /* Append linked list list1 to linked list list2 and return resulting list */
678 681 static dladm_stat_chain_t *
679 682 i_dlstat_join_lists(dladm_stat_chain_t *list1, dladm_stat_chain_t *list2)
680 683 {
681 684 dladm_stat_chain_t *curr;
682 685
683 686 if (list1 == NULL)
684 687 return (list2);
685 688
686 689 /* list1 has at least one element, find last element in list1 */
687 690 curr = list1;
688 691 while (curr->dc_next != NULL)
689 692 curr = curr->dc_next;
690 693
691 694 curr->dc_next = list2;
692 695 return (list1);
693 696 }
694 697
695 698 uint_t default_idlist[] = {0};
696 699 uint_t default_idlist_size = 1;
697 700
698 701 typedef enum {
699 702 DLSTAT_RX_RING_IDLIST,
700 703 DLSTAT_TX_RING_IDLIST,
701 704 DLSTAT_RX_HWLANE_IDLIST,
702 705 DLSTAT_TX_HWLANE_IDLIST,
703 706 DLSTAT_FANOUT_IDLIST
704 707 } dlstat_idlist_type_t;
705 708
706 709 void
707 710 dladm_sort_index_list(uint_t idlist[], uint_t size)
708 711 {
709 712 int i, j;
710 713
↓ open down ↓ |
479 lines elided |
↑ open up ↑ |
711 714 for (j = 1; j < size; j++) {
712 715 int key = idlist[j];
713 716 for (i = j - 1; (i >= 0) && (idlist[i] > key); i--)
714 717 idlist[i + 1] = idlist[i];
715 718 idlist[i + 1] = key;
716 719 }
717 720 }
718 721
719 722 /* Support for legacy drivers */
720 723 void
721 -i_query_legacy_stats(const char *linkname, pktsum_t *stats)
724 +i_query_legacy_stats(dladm_handle_t dh, const char *linkname, pktsum_t *stats)
722 725 {
723 - kstat_ctl_t *kcp;
724 726 kstat_t *ksp;
725 727
726 728 bzero(stats, sizeof (*stats));
727 729
728 - if ((kcp = kstat_open()) == NULL)
730 + if (dladm_dld_kcp(dh) == NULL)
729 731 return;
730 732
731 - ksp = dladm_kstat_lookup(kcp, "link", 0, linkname, NULL);
733 + ksp = dladm_kstat_lookup(dladm_dld_kcp(dh), "link", 0, linkname, NULL);
732 734
733 735 if (ksp != NULL)
734 - dladm_get_stats(kcp, ksp, stats);
735 -
736 - (void) kstat_close(kcp);
736 + dladm_get_stats(dladm_dld_kcp(dh), ksp, stats);
737 737 }
738 738
739 739 void *
740 -i_dlstat_legacy_rx_lane_stats(const char *linkname)
740 +i_dlstat_legacy_rx_lane_stats(dladm_handle_t dh, const char *linkname)
741 741 {
742 742 dladm_stat_chain_t *head = NULL;
743 743 pktsum_t stats;
744 744 rx_lane_stat_entry_t *rx_lane_stat_entry;
745 745
746 746 bzero(&stats, sizeof (pktsum_t));
747 747
748 748 /* Query for dls stats */
749 - i_query_legacy_stats(linkname, &stats);
749 + i_query_legacy_stats(dh, linkname, &stats);
750 750
751 751 /* Convert to desired data type */
752 752 rx_lane_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
753 753 if (rx_lane_stat_entry == NULL)
754 754 goto done;
755 755
756 756 rx_lane_stat_entry->rle_index = DLSTAT_INVALID_ENTRY;
757 757 rx_lane_stat_entry->rle_id = L_SWLANE;
758 758
759 759 rx_lane_stat_entry->rle_stats.rl_ipackets = stats.ipackets;
760 760 rx_lane_stat_entry->rle_stats.rl_intrs = stats.ipackets;
761 761 rx_lane_stat_entry->rle_stats.rl_rbytes = stats.rbytes;
762 762
763 763 /* Allocate memory for wrapper */
764 764 head = malloc(sizeof (dladm_stat_chain_t));
765 765 if (head == NULL) {
766 766 free(rx_lane_stat_entry);
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
767 767 goto done;
768 768 }
769 769
770 770 head->dc_statentry = rx_lane_stat_entry;
771 771 head->dc_next = NULL;
772 772 done:
773 773 return (head);
774 774 }
775 775
776 776 void *
777 -i_dlstat_legacy_tx_lane_stats(const char *linkname)
777 +i_dlstat_legacy_tx_lane_stats(dladm_handle_t dh, const char *linkname)
778 778 {
779 779 dladm_stat_chain_t *head = NULL;
780 780 pktsum_t stats;
781 781 tx_lane_stat_entry_t *tx_lane_stat_entry;
782 782
783 783 bzero(&stats, sizeof (pktsum_t));
784 784
785 785 /* Query for dls stats */
786 - i_query_legacy_stats(linkname, &stats);
786 + i_query_legacy_stats(dh, linkname, &stats);
787 787
788 788 /* Convert to desired data type */
789 789 tx_lane_stat_entry = calloc(1, sizeof (tx_lane_stat_entry_t));
790 790 if (tx_lane_stat_entry == NULL)
791 791 goto done;
792 792
793 793 tx_lane_stat_entry->tle_index = DLSTAT_INVALID_ENTRY;
794 794 tx_lane_stat_entry->tle_id = L_SWLANE;
795 795
796 796 tx_lane_stat_entry->tle_stats.tl_opackets = stats.opackets;
797 797 tx_lane_stat_entry->tle_stats.tl_obytes = stats.obytes;
798 798
799 799 /* Allocate memory for wrapper */
800 800 head = malloc(sizeof (dladm_stat_chain_t));
801 801 if (head == NULL) {
802 802 free(tx_lane_stat_entry);
803 803 goto done;
804 804 }
805 805
806 806 head->dc_statentry = tx_lane_stat_entry;
807 807 head->dc_next = NULL;
808 808 done:
809 809 return (head);
810 810 }
811 811
812 812 /*
813 813 * Ideally, we would want an ioctl to return list of ring-ids (or lane-ids)
814 814 * for a given data-link (or mac client). We could then query for specific
815 815 * kstats based on these ring-ids (lane-ids).
816 816 * Ring-ids (or lane-ids) could be returned like any other link properties
817 817 * queried by dladm show-linkprop. However, non-global zones do not have
818 818 * access to this information today.
819 819 * We thus opt for an implementation that relies heavily on kstat internals:
820 820 * i_dlstat_*search routines and i_dlstat_get_idlist.
821 821 */
822 822 /* rx hwlane specific */
823 823 static boolean_t
824 824 i_dlstat_rx_hwlane_search(kstat_t *ksp)
825 825 {
826 826 return (ksp->ks_instance == 0 &&
827 827 strstr(ksp->ks_name, "mac_rx") != 0 &&
828 828 strstr(ksp->ks_name, "hwlane") != 0 &&
829 829 strstr(ksp->ks_name, "fanout") == 0 &&
830 830 strcmp(ksp->ks_class, "net") == 0);
831 831 }
832 832
833 833 /* tx hwlane specific */
834 834 static boolean_t
835 835 i_dlstat_tx_hwlane_search(kstat_t *ksp)
836 836 {
837 837 return (ksp->ks_instance == 0 &&
838 838 strstr(ksp->ks_name, "mac_tx") != 0 &&
839 839 strstr(ksp->ks_name, "hwlane") != 0 &&
840 840 strcmp(ksp->ks_class, "net") == 0);
841 841 }
842 842
843 843 /* rx fanout specific */
844 844 static boolean_t
845 845 i_dlstat_fanout_search(kstat_t *ksp)
846 846 {
847 847 return (ksp->ks_instance == 0 &&
848 848 strstr(ksp->ks_name, "mac_rx") != 0 &&
849 849 strstr(ksp->ks_name, "swlane") != 0 &&
850 850 strstr(ksp->ks_name, "fanout") != 0 &&
851 851 strcmp(ksp->ks_class, "net") == 0);
852 852 }
853 853
854 854 /* rx ring specific */
855 855 static boolean_t
856 856 i_dlstat_rx_ring_search(kstat_t *ksp)
857 857 {
858 858 return (ksp->ks_instance == 0 &&
859 859 strstr(ksp->ks_name, "mac_rx") != 0 &&
860 860 strstr(ksp->ks_name, "ring") != 0 &&
861 861 strcmp(ksp->ks_class, "net") == 0);
862 862 }
863 863
864 864 /* tx ring specific */
865 865 static boolean_t
866 866 i_dlstat_tx_ring_search(kstat_t *ksp)
867 867 {
868 868 return (ksp->ks_instance == 0) &&
869 869 strstr(ksp->ks_name, "mac_tx") != 0 &&
870 870 strstr(ksp->ks_name, "ring") != 0 &&
871 871 strcmp(ksp->ks_class, "net") == 0;
872 872 }
873 873
874 874 typedef boolean_t dladm_search_kstat_t(kstat_t *);
875 875 typedef struct dladm_extract_idlist_s {
876 876 dlstat_idlist_type_t di_type;
877 877 char *di_prefix;
878 878 dladm_search_kstat_t *di_searchkstat;
879 879 } dladm_extract_idlist_t;
880 880
881 881 static dladm_extract_idlist_t dladm_extract_idlist[] = {
882 882 { DLSTAT_RX_RING_IDLIST, DLSTAT_MAC_RX_RING,
883 883 i_dlstat_rx_ring_search},
884 884 { DLSTAT_TX_RING_IDLIST, DLSTAT_MAC_TX_RING,
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
885 885 i_dlstat_tx_ring_search},
886 886 { DLSTAT_RX_HWLANE_IDLIST, DLSTAT_MAC_RX_HWLANE,
887 887 i_dlstat_rx_hwlane_search},
888 888 { DLSTAT_TX_HWLANE_IDLIST, DLSTAT_MAC_TX_HWLANE,
889 889 i_dlstat_tx_hwlane_search},
890 890 { DLSTAT_FANOUT_IDLIST, DLSTAT_MAC_FANOUT,
891 891 i_dlstat_fanout_search}
892 892 };
893 893
894 894 static void
895 -i_dlstat_get_idlist(const char *modname, dlstat_idlist_type_t idlist_type,
895 +i_dlstat_get_idlist(dladm_handle_t handle, const char *modname,
896 + dlstat_idlist_type_t idlist_type,
896 897 uint_t idlist[], uint_t *size)
897 898 {
898 - kstat_ctl_t *kcp;
899 + kstat_ctl_t *kcp = dladm_dld_kcp(handle);
899 900 kstat_t *ksp;
900 901 char *prefix;
901 902 int prefixlen;
902 903 boolean_t (*fptr_searchkstat)(kstat_t *);
903 904
904 905 *size = 0;
905 906
906 - if ((kcp = kstat_open()) == NULL) {
907 + if (kcp == NULL) {
907 908 warn("kstat_open operation failed");
908 - goto done;
909 + return;
909 910 }
910 911
911 912 prefix = dladm_extract_idlist[idlist_type].di_prefix;
912 913 fptr_searchkstat = dladm_extract_idlist[idlist_type].di_searchkstat;
913 914 prefixlen = strlen(prefix);
914 915 for (ksp = kcp->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
915 916 if ((strcmp(ksp->ks_module, modname) == 0) &&
916 917 fptr_searchkstat(ksp)) {
917 918 idlist[(*size)++] = atoi(&ksp->ks_name[prefixlen]);
918 919 }
919 920 }
920 921 dladm_sort_index_list(idlist, *size);
921 -
922 -done:
923 - (void) kstat_close(kcp);
924 922 }
925 923
926 924 static dladm_stat_chain_t *
927 -i_dlstat_query_stats(const char *modname, const char *prefix,
928 - uint_t idlist[], uint_t idlist_size,
925 +i_dlstat_query_stats(dladm_handle_t handle, const char *modname,
926 + const char *prefix, uint_t idlist[], uint_t idlist_size,
929 927 void * (*fn)(kstat_ctl_t *, kstat_t *, int))
930 928 {
931 - kstat_ctl_t *kcp;
932 929 kstat_t *ksp;
933 930 char statname[MAXLINKNAMELEN];
934 931 int i = 0;
935 932 dladm_stat_chain_t *head = NULL, *prev = NULL;
936 933 dladm_stat_chain_t *curr;
937 934
938 - if ((kcp = kstat_open()) == NULL) {
935 + if (dladm_dld_kcp(handle) == NULL) {
939 936 warn("kstat_open operation failed");
940 937 return (NULL);
941 938 }
942 939
943 940 for (i = 0; i < idlist_size; i++) {
944 941 uint_t index = idlist[i];
945 942
946 943 (void) snprintf(statname, sizeof (statname), "%s%d", prefix,
947 944 index);
948 945
949 - ksp = dladm_kstat_lookup(kcp, modname, 0, statname, NULL);
946 + ksp = dladm_kstat_lookup(dladm_dld_kcp(handle), modname, 0,
947 + statname, NULL);
950 948 if (ksp == NULL)
951 949 continue;
952 950
953 951 curr = malloc(sizeof (dladm_stat_chain_t));
954 952 if (curr == NULL)
955 953 break;
956 954
957 - curr->dc_statentry = fn(kcp, ksp, index);
955 + curr->dc_statentry = fn(dladm_dld_kcp(handle), ksp, index);
958 956 if (curr->dc_statentry == NULL) {
959 957 free(curr);
960 958 break;
961 959 }
962 960
963 961 (void) strlcpy(curr->dc_statheader, statname,
964 962 sizeof (curr->dc_statheader));
965 963 curr->dc_next = NULL;
966 964
967 965 if (head == NULL) /* First node */
968 966 head = curr;
969 967 else
970 968 prev->dc_next = curr;
971 969
972 970 prev = curr;
973 971 }
974 972 done:
975 - (void) kstat_close(kcp);
976 973 return (head);
977 974 }
978 975
979 976 static misc_stat_entry_t *
980 -i_dlstat_misc_stats(const char *linkname)
977 +i_dlstat_misc_stats(dladm_handle_t handle, const char *linkname)
981 978 {
982 - kstat_ctl_t *kcp;
983 979 kstat_t *ksp;
984 980 misc_stat_entry_t *misc_stat_entry = NULL;
985 981
986 - if ((kcp = kstat_open()) == NULL)
982 + if (dladm_dld_kcp(handle) == NULL)
987 983 return (NULL);
988 984
989 - ksp = dladm_kstat_lookup(kcp, linkname, 0, DLSTAT_MAC_MISC_STAT, NULL);
985 + ksp = dladm_kstat_lookup(dladm_dld_kcp(handle), linkname, 0,
986 + DLSTAT_MAC_MISC_STAT, NULL);
990 987 if (ksp == NULL)
991 988 goto done;
992 989
993 990 misc_stat_entry = calloc(1, sizeof (misc_stat_entry_t));
994 991 if (misc_stat_entry == NULL)
995 992 goto done;
996 993
997 - i_dlstat_get_stats(kcp, ksp, &misc_stat_entry->mse_stats,
994 + i_dlstat_get_stats(dladm_dld_kcp(handle), ksp,
995 + &misc_stat_entry->mse_stats,
998 996 misc_stats_list, MISC_STAT_SIZE);
999 997 done:
1000 - (void) kstat_close(kcp);
1001 998 return (misc_stat_entry);
1002 999 }
1003 1000
1004 1001 /* Rx lane statistic specific functions */
1005 1002 static boolean_t
1006 1003 i_dlstat_rx_lane_match(void *arg1, void *arg2)
1007 1004 {
1008 1005 rx_lane_stat_entry_t *s1 = arg1;
1009 1006 rx_lane_stat_entry_t *s2 = arg2;
1010 1007
1011 1008 return (s1->rle_index == s2->rle_index &&
1012 1009 s1->rle_id == s2->rle_id);
1013 1010 }
1014 1011
1015 1012 static void *
1016 1013 i_dlstat_rx_lane_stat_entry_diff(void *arg1, void *arg2)
1017 1014 {
1018 1015 rx_lane_stat_entry_t *s1 = arg1;
1019 1016 rx_lane_stat_entry_t *s2 = arg2;
1020 1017 rx_lane_stat_entry_t *diff_entry;
1021 1018
1022 1019 diff_entry = malloc(sizeof (rx_lane_stat_entry_t));
1023 1020 if (diff_entry == NULL)
1024 1021 goto done;
1025 1022
1026 1023 diff_entry->rle_index = s1->rle_index;
1027 1024 diff_entry->rle_id = s1->rle_id;
1028 1025
1029 1026 DLSTAT_DIFF_STAT(s1, s2, diff_entry, rle_stats, rx_lane_stats_list,
1030 1027 RX_LANE_STAT_SIZE);
1031 1028
1032 1029 done:
1033 1030 return (diff_entry);
1034 1031 }
1035 1032
1036 1033 static void *
1037 1034 i_dlstat_rx_hwlane_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1038 1035 {
1039 1036 rx_lane_stat_entry_t *rx_lane_stat_entry;
1040 1037
1041 1038 rx_lane_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
1042 1039 if (rx_lane_stat_entry == NULL)
1043 1040 goto done;
1044 1041
1045 1042 rx_lane_stat_entry->rle_index = i;
1046 1043 rx_lane_stat_entry->rle_id = L_HWLANE;
1047 1044
1048 1045 i_dlstat_get_stats(kcp, ksp, &rx_lane_stat_entry->rle_stats,
1049 1046 rx_hwlane_stats_list, RX_HWLANE_STAT_SIZE);
1050 1047
1051 1048 done:
1052 1049 return (rx_lane_stat_entry);
1053 1050 }
1054 1051
1055 1052 /*ARGSUSED*/
1056 1053 static void *
1057 1054 i_dlstat_rx_swlane_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1058 1055 {
1059 1056 rx_lane_stat_entry_t *rx_lane_stat_entry;
1060 1057
1061 1058 rx_lane_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
1062 1059 if (rx_lane_stat_entry == NULL)
1063 1060 goto done;
1064 1061
1065 1062 rx_lane_stat_entry->rle_index = DLSTAT_INVALID_ENTRY;
1066 1063 rx_lane_stat_entry->rle_id = L_SWLANE;
1067 1064
1068 1065 i_dlstat_get_stats(kcp, ksp, &rx_lane_stat_entry->rle_stats,
1069 1066 rx_swlane_stats_list, RX_SWLANE_STAT_SIZE);
1070 1067
1071 1068 rx_lane_stat_entry->rle_stats.rl_ipackets =
1072 1069 rx_lane_stat_entry->rle_stats.rl_intrs;
1073 1070 rx_lane_stat_entry->rle_stats.rl_rbytes =
1074 1071 rx_lane_stat_entry->rle_stats.rl_intrbytes;
1075 1072 done:
1076 1073 return (rx_lane_stat_entry);
1077 1074 }
1078 1075
1079 1076 /*ARGSUSED*/
1080 1077 static void *
1081 1078 i_dlstat_rx_local_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1082 1079 {
1083 1080 rx_lane_stat_entry_t *local_stat_entry;
1084 1081 rx_lane_stat_entry_t *rx_lane_stat_entry;
1085 1082
1086 1083 rx_lane_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
1087 1084 if (rx_lane_stat_entry == NULL)
1088 1085 goto done;
1089 1086
1090 1087 local_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
1091 1088 if (local_stat_entry == NULL)
1092 1089 goto done;
1093 1090
1094 1091 local_stat_entry->rle_index = DLSTAT_INVALID_ENTRY;
1095 1092 local_stat_entry->rle_id = L_LOCAL;
1096 1093
1097 1094 i_dlstat_get_stats(kcp, ksp, &rx_lane_stat_entry->rle_stats,
1098 1095 rx_swlane_stats_list, RX_SWLANE_STAT_SIZE);
1099 1096
1100 1097 local_stat_entry->rle_stats.rl_ipackets =
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
1101 1098 rx_lane_stat_entry->rle_stats.rl_lclpackets;
1102 1099 local_stat_entry->rle_stats.rl_rbytes =
1103 1100 rx_lane_stat_entry->rle_stats.rl_lclbytes;
1104 1101
1105 1102 done:
1106 1103 free(rx_lane_stat_entry);
1107 1104 return (local_stat_entry);
1108 1105 }
1109 1106
1110 1107 static dladm_stat_chain_t *
1111 -i_dlstat_rx_local_stats(const char *linkname)
1108 +i_dlstat_rx_local_stats(dladm_handle_t handle, const char *linkname)
1112 1109 {
1113 1110 dladm_stat_chain_t *local_stats = NULL;
1114 1111
1115 - local_stats = i_dlstat_query_stats(linkname, DLSTAT_MAC_RX_SWLANE,
1112 + local_stats = i_dlstat_query_stats(handle, linkname,
1113 + DLSTAT_MAC_RX_SWLANE,
1116 1114 default_idlist, default_idlist_size,
1117 1115 i_dlstat_rx_local_retrieve_stat);
1118 1116
1119 1117 if (local_stats != NULL) {
1120 1118 (void) strlcpy(local_stats->dc_statheader, "mac_rx_local",
1121 1119 sizeof (local_stats->dc_statheader));
1122 1120 }
1123 1121 return (local_stats);
1124 1122 }
1125 1123
1126 1124 static dladm_stat_chain_t *
1127 -i_dlstat_rx_bcast_stats(const char *linkname)
1125 +i_dlstat_rx_bcast_stats(dladm_handle_t handle, const char *linkname)
1128 1126 {
1129 1127 misc_stat_entry_t *misc_stat_entry;
1130 1128 dladm_stat_chain_t *head = NULL;
1131 1129 rx_lane_stat_entry_t *rx_lane_stat_entry;
1132 1130
1133 - misc_stat_entry = i_dlstat_misc_stats(linkname);
1131 + misc_stat_entry = i_dlstat_misc_stats(handle, linkname);
1134 1132 if (misc_stat_entry == NULL)
1135 1133 goto done;
1136 1134
1137 1135 rx_lane_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
1138 1136 if (rx_lane_stat_entry == NULL)
1139 1137 goto done;
1140 1138
1141 1139 rx_lane_stat_entry->rle_index = DLSTAT_INVALID_ENTRY;
1142 1140 rx_lane_stat_entry->rle_id = L_BCAST;
1143 1141
1144 1142 rx_lane_stat_entry->rle_stats.rl_ipackets =
1145 1143 misc_stat_entry->mse_stats.ms_brdcstrcv +
1146 1144 misc_stat_entry->mse_stats.ms_multircv;
1147 1145 rx_lane_stat_entry->rle_stats.rl_intrs =
1148 1146 misc_stat_entry->mse_stats.ms_brdcstrcv +
1149 1147 misc_stat_entry->mse_stats.ms_multircv;
1150 1148 rx_lane_stat_entry->rle_stats.rl_rbytes =
1151 1149 misc_stat_entry->mse_stats.ms_brdcstrcvbytes +
1152 1150 misc_stat_entry->mse_stats.ms_multircvbytes;
1153 1151
1154 1152 head = malloc(sizeof (dladm_stat_chain_t));
1155 1153 if (head == NULL) {
1156 1154 free(rx_lane_stat_entry);
1157 1155 goto done;
1158 1156 }
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
1159 1157
1160 1158 head->dc_statentry = rx_lane_stat_entry;
1161 1159 head->dc_next = NULL;
1162 1160
1163 1161 free(misc_stat_entry);
1164 1162 done:
1165 1163 return (head);
1166 1164 }
1167 1165
1168 1166 static dladm_stat_chain_t *
1169 -i_dlstat_rx_defunctlane_stats(const char *linkname)
1167 +i_dlstat_rx_defunctlane_stats(dladm_handle_t handle, const char *linkname)
1170 1168 {
1171 1169 misc_stat_entry_t *misc_stat_entry;
1172 1170 dladm_stat_chain_t *head = NULL;
1173 1171 rx_lane_stat_entry_t *rx_lane_stat_entry;
1174 1172
1175 - misc_stat_entry = i_dlstat_misc_stats(linkname);
1173 + misc_stat_entry = i_dlstat_misc_stats(handle, linkname);
1176 1174 if (misc_stat_entry == NULL)
1177 1175 goto done;
1178 1176
1179 1177 rx_lane_stat_entry = calloc(1, sizeof (rx_lane_stat_entry_t));
1180 1178 if (rx_lane_stat_entry == NULL)
1181 1179 goto done;
1182 1180
1183 1181 rx_lane_stat_entry->rle_index = DLSTAT_INVALID_ENTRY;
1184 1182 rx_lane_stat_entry->rle_id = L_DFNCT;
1185 1183
1186 1184 rx_lane_stat_entry->rle_stats.rl_ipackets =
1187 1185 misc_stat_entry->mse_stats.ms_ipackets;
1188 1186 rx_lane_stat_entry->rle_stats.rl_rbytes =
1189 1187 misc_stat_entry->mse_stats.ms_rbytes;
1190 1188 rx_lane_stat_entry->rle_stats.rl_intrs =
1191 1189 misc_stat_entry->mse_stats.ms_intrs;
1192 1190 rx_lane_stat_entry->rle_stats.rl_polls =
1193 1191 misc_stat_entry->mse_stats.ms_polls;
1194 1192 rx_lane_stat_entry->rle_stats.rl_sdrops =
1195 1193 misc_stat_entry->mse_stats.ms_rxsdrops;
1196 1194 rx_lane_stat_entry->rle_stats.rl_chl10 =
1197 1195 misc_stat_entry->mse_stats.ms_chainunder10;
1198 1196 rx_lane_stat_entry->rle_stats.rl_ch10_50 =
1199 1197 misc_stat_entry->mse_stats.ms_chain10to50;
1200 1198 rx_lane_stat_entry->rle_stats.rl_chg50 =
1201 1199 misc_stat_entry->mse_stats.ms_chainover50;
1202 1200
1203 1201 head = malloc(sizeof (dladm_stat_chain_t));
1204 1202 if (head == NULL) {
1205 1203 free(rx_lane_stat_entry);
1206 1204 goto done;
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
1207 1205 }
1208 1206
1209 1207 head->dc_statentry = rx_lane_stat_entry;
1210 1208 head->dc_next = NULL;
1211 1209
1212 1210 done:
1213 1211 return (head);
1214 1212 }
1215 1213
1216 1214 static dladm_stat_chain_t *
1217 -i_dlstat_rx_hwlane_stats(const char *linkname)
1215 +i_dlstat_rx_hwlane_stats(dladm_handle_t handle, const char *linkname)
1218 1216 {
1219 1217 uint_t rx_hwlane_idlist[MAX_RINGS_PER_GROUP];
1220 1218 uint_t rx_hwlane_idlist_size;
1221 1219
1222 - i_dlstat_get_idlist(linkname, DLSTAT_RX_HWLANE_IDLIST,
1220 + i_dlstat_get_idlist(handle, linkname, DLSTAT_RX_HWLANE_IDLIST,
1223 1221 rx_hwlane_idlist, &rx_hwlane_idlist_size);
1224 1222
1225 - return (i_dlstat_query_stats(linkname, DLSTAT_MAC_RX_HWLANE,
1223 + return (i_dlstat_query_stats(handle, linkname, DLSTAT_MAC_RX_HWLANE,
1226 1224 rx_hwlane_idlist, rx_hwlane_idlist_size,
1227 1225 i_dlstat_rx_hwlane_retrieve_stat));
1228 1226 }
1229 1227
1230 1228 /*ARGSUSED*/
1231 1229 static dladm_stat_chain_t *
1232 1230 i_dlstat_rx_swlane_stats(dladm_handle_t dh, datalink_id_t linkid,
1233 1231 const char *linkname)
1234 1232 {
1235 - return (i_dlstat_query_stats(linkname, DLSTAT_MAC_RX_SWLANE,
1233 + return (i_dlstat_query_stats(dh, linkname, DLSTAT_MAC_RX_SWLANE,
1236 1234 default_idlist, default_idlist_size,
1237 1235 i_dlstat_rx_swlane_retrieve_stat));
1238 1236 }
1239 1237
1240 1238 void *
1241 1239 dlstat_rx_lane_stats(dladm_handle_t dh, datalink_id_t linkid)
1242 1240 {
1243 1241 dladm_stat_chain_t *head = NULL;
1244 1242 dladm_stat_chain_t *local_stats = NULL;
1245 1243 dladm_stat_chain_t *bcast_stats = NULL;
1246 1244 dladm_stat_chain_t *defunctlane_stats = NULL;
1247 1245 dladm_stat_chain_t *lane_stats = NULL;
1248 1246 char linkname[MAXLINKNAMELEN];
1249 1247 boolean_t is_legacy_driver;
1250 1248
1251 1249 if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
1252 1250 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
1253 1251 goto done;
1254 1252 }
1255 1253
1256 1254 /* Check if it is legacy driver */
1257 1255 if (dladm_linkprop_is_set(dh, linkid, DLADM_PROP_VAL_CURRENT,
1258 1256 "_softmac", &is_legacy_driver) != DLADM_STATUS_OK) {
1259 1257 goto done;
1260 1258 }
1261 1259
1262 1260 if (is_legacy_driver) {
1263 - head = i_dlstat_legacy_rx_lane_stats(linkname);
1261 + head = i_dlstat_legacy_rx_lane_stats(dh, linkname);
1264 1262 goto done;
1265 1263 }
1266 1264
1267 - local_stats = i_dlstat_rx_local_stats(linkname);
1268 - bcast_stats = i_dlstat_rx_bcast_stats(linkname);
1269 - defunctlane_stats = i_dlstat_rx_defunctlane_stats(linkname);
1270 - lane_stats = i_dlstat_rx_hwlane_stats(linkname);
1265 + local_stats = i_dlstat_rx_local_stats(dh, linkname);
1266 + bcast_stats = i_dlstat_rx_bcast_stats(dh, linkname);
1267 + defunctlane_stats = i_dlstat_rx_defunctlane_stats(dh, linkname);
1268 + lane_stats = i_dlstat_rx_hwlane_stats(dh, linkname);
1271 1269 if (lane_stats == NULL)
1272 1270 lane_stats = i_dlstat_rx_swlane_stats(dh, linkid, linkname);
1273 1271
1274 1272 head = i_dlstat_join_lists(local_stats, bcast_stats);
1275 1273 head = i_dlstat_join_lists(head, defunctlane_stats);
1276 1274 head = i_dlstat_join_lists(head, lane_stats);
1277 1275 done:
1278 1276 return (head);
1279 1277 }
1280 1278
1281 1279 /* Tx lane statistic specific functions */
1282 1280 static boolean_t
1283 1281 i_dlstat_tx_lane_match(void *arg1, void *arg2)
1284 1282 {
1285 1283 tx_lane_stat_entry_t *s1 = arg1;
1286 1284 tx_lane_stat_entry_t *s2 = arg2;
1287 1285
1288 1286 return (s1->tle_index == s2->tle_index &&
1289 1287 s1->tle_id == s2->tle_id);
1290 1288 }
1291 1289
1292 1290 static void *
1293 1291 i_dlstat_tx_lane_stat_entry_diff(void *arg1, void *arg2)
1294 1292 {
1295 1293 tx_lane_stat_entry_t *s1 = arg1;
1296 1294 tx_lane_stat_entry_t *s2 = arg2;
1297 1295 tx_lane_stat_entry_t *diff_entry;
1298 1296
1299 1297 diff_entry = malloc(sizeof (tx_lane_stat_entry_t));
1300 1298 if (diff_entry == NULL)
1301 1299 goto done;
1302 1300
1303 1301 diff_entry->tle_index = s1->tle_index;
1304 1302 diff_entry->tle_id = s1->tle_id;
1305 1303
1306 1304 DLSTAT_DIFF_STAT(s1, s2, diff_entry, tle_stats, tx_lane_stats_list,
1307 1305 TX_LANE_STAT_SIZE);
1308 1306
1309 1307 done:
1310 1308 return (diff_entry);
1311 1309 }
1312 1310
1313 1311 static void *
1314 1312 i_dlstat_tx_hwlane_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1315 1313 {
1316 1314 tx_lane_stat_entry_t *tx_lane_stat_entry;
1317 1315
1318 1316 tx_lane_stat_entry = calloc(1, sizeof (tx_lane_stat_entry_t));
1319 1317 if (tx_lane_stat_entry == NULL)
1320 1318 goto done;
1321 1319
1322 1320 tx_lane_stat_entry->tle_index = i;
1323 1321 tx_lane_stat_entry->tle_id = L_HWLANE;
1324 1322
1325 1323 i_dlstat_get_stats(kcp, ksp, &tx_lane_stat_entry->tle_stats,
1326 1324 tx_lane_stats_list, TX_LANE_STAT_SIZE);
1327 1325
1328 1326 done:
1329 1327 return (tx_lane_stat_entry);
1330 1328 }
1331 1329
1332 1330 /*ARGSUSED*/
1333 1331 static void *
1334 1332 i_dlstat_tx_swlane_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1335 1333 {
1336 1334 tx_lane_stat_entry_t *tx_lane_stat_entry;
1337 1335
1338 1336 tx_lane_stat_entry = calloc(1, sizeof (tx_lane_stat_entry_t));
1339 1337 if (tx_lane_stat_entry == NULL)
1340 1338 goto done;
1341 1339
1342 1340 tx_lane_stat_entry->tle_index = DLSTAT_INVALID_ENTRY;
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
1343 1341 tx_lane_stat_entry->tle_id = L_SWLANE;
1344 1342
1345 1343 i_dlstat_get_stats(kcp, ksp, &tx_lane_stat_entry->tle_stats,
1346 1344 tx_lane_stats_list, TX_LANE_STAT_SIZE);
1347 1345
1348 1346 done:
1349 1347 return (tx_lane_stat_entry);
1350 1348 }
1351 1349
1352 1350 static dladm_stat_chain_t *
1353 -i_dlstat_tx_bcast_stats(const char *linkname)
1351 +i_dlstat_tx_bcast_stats(dladm_handle_t handle, const char *linkname)
1354 1352 {
1355 1353 misc_stat_entry_t *misc_stat_entry;
1356 1354 dladm_stat_chain_t *head = NULL;
1357 1355 tx_lane_stat_entry_t *tx_lane_stat_entry;
1358 1356
1359 - misc_stat_entry = i_dlstat_misc_stats(linkname);
1357 + misc_stat_entry = i_dlstat_misc_stats(handle, linkname);
1360 1358 if (misc_stat_entry == NULL)
1361 1359 goto done;
1362 1360
1363 1361 tx_lane_stat_entry = calloc(1, sizeof (tx_lane_stat_entry_t));
1364 1362 if (tx_lane_stat_entry == NULL)
1365 1363 goto done;
1366 1364
1367 1365 tx_lane_stat_entry->tle_index = DLSTAT_INVALID_ENTRY;
1368 1366 tx_lane_stat_entry->tle_id = L_BCAST;
1369 1367
1370 1368 tx_lane_stat_entry->tle_stats.tl_opackets =
1371 1369 misc_stat_entry->mse_stats.ms_brdcstxmt +
1372 1370 misc_stat_entry->mse_stats.ms_multixmt;
1373 1371
1374 1372 tx_lane_stat_entry->tle_stats.tl_obytes =
1375 1373 misc_stat_entry->mse_stats.ms_brdcstxmtbytes +
1376 1374 misc_stat_entry->mse_stats.ms_multixmtbytes;
1377 1375
1378 1376 head = malloc(sizeof (dladm_stat_chain_t));
1379 1377 if (head == NULL) {
1380 1378 free(tx_lane_stat_entry);
1381 1379 goto done;
1382 1380 }
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
1383 1381
1384 1382 head->dc_statentry = tx_lane_stat_entry;
1385 1383 head->dc_next = NULL;
1386 1384
1387 1385 free(misc_stat_entry);
1388 1386 done:
1389 1387 return (head);
1390 1388 }
1391 1389
1392 1390 static dladm_stat_chain_t *
1393 -i_dlstat_tx_defunctlane_stats(const char *linkname)
1391 +i_dlstat_tx_defunctlane_stats(dladm_handle_t handle, const char *linkname)
1394 1392 {
1395 1393 misc_stat_entry_t *misc_stat_entry;
1396 1394 dladm_stat_chain_t *head = NULL;
1397 1395 tx_lane_stat_entry_t *tx_lane_stat_entry;
1398 1396
1399 - misc_stat_entry = i_dlstat_misc_stats(linkname);
1397 + misc_stat_entry = i_dlstat_misc_stats(handle, linkname);
1400 1398 if (misc_stat_entry == NULL)
1401 1399 goto done;
1402 1400
1403 1401 tx_lane_stat_entry = calloc(1, sizeof (tx_lane_stat_entry_t));
1404 1402 if (tx_lane_stat_entry == NULL)
1405 1403 goto done;
1406 1404
1407 1405 tx_lane_stat_entry->tle_index = DLSTAT_INVALID_ENTRY;
1408 1406 tx_lane_stat_entry->tle_id = L_DFNCT;
1409 1407
1410 1408 tx_lane_stat_entry->tle_stats.tl_opackets =
1411 1409 misc_stat_entry->mse_stats.ms_opackets;
1412 1410 tx_lane_stat_entry->tle_stats.tl_obytes =
1413 1411 misc_stat_entry->mse_stats.ms_obytes;
1414 1412 tx_lane_stat_entry->tle_stats.tl_sdrops =
1415 1413 misc_stat_entry->mse_stats.ms_txsdrops;
1416 1414
1417 1415 head = malloc(sizeof (dladm_stat_chain_t));
1418 1416 if (head == NULL) {
1419 1417 free(tx_lane_stat_entry);
1420 1418 goto done;
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1421 1419 }
1422 1420
1423 1421 head->dc_statentry = tx_lane_stat_entry;
1424 1422 head->dc_next = NULL;
1425 1423
1426 1424 done:
1427 1425 return (head);
1428 1426 }
1429 1427
1430 1428 static dladm_stat_chain_t *
1431 -i_dlstat_tx_hwlane_stats(const char *linkname)
1429 +i_dlstat_tx_hwlane_stats(dladm_handle_t handle, const char *linkname)
1432 1430 {
1433 1431 uint_t tx_hwlane_idlist[MAX_RINGS_PER_GROUP];
1434 1432 uint_t tx_hwlane_idlist_size;
1435 1433
1436 - i_dlstat_get_idlist(linkname, DLSTAT_TX_HWLANE_IDLIST,
1434 + i_dlstat_get_idlist(handle, linkname, DLSTAT_TX_HWLANE_IDLIST,
1437 1435 tx_hwlane_idlist, &tx_hwlane_idlist_size);
1438 1436
1439 - return (i_dlstat_query_stats(linkname, DLSTAT_MAC_TX_HWLANE,
1437 + return (i_dlstat_query_stats(handle, linkname, DLSTAT_MAC_TX_HWLANE,
1440 1438 tx_hwlane_idlist, tx_hwlane_idlist_size,
1441 1439 i_dlstat_tx_hwlane_retrieve_stat));
1442 1440 }
1443 1441
1444 1442 /*ARGSUSED*/
1445 1443 static dladm_stat_chain_t *
1446 1444 i_dlstat_tx_swlane_stats(dladm_handle_t dh, datalink_id_t linkid,
1447 1445 const char *linkname)
1448 1446 {
1449 - return (i_dlstat_query_stats(linkname, DLSTAT_MAC_TX_SWLANE,
1447 + return (i_dlstat_query_stats(dh, linkname, DLSTAT_MAC_TX_SWLANE,
1450 1448 default_idlist, default_idlist_size,
1451 1449 i_dlstat_tx_swlane_retrieve_stat));
1452 1450 }
1453 1451
1454 1452 void *
1455 1453 dlstat_tx_lane_stats(dladm_handle_t dh, datalink_id_t linkid)
1456 1454 {
1457 1455 dladm_stat_chain_t *head = NULL;
1458 1456 dladm_stat_chain_t *bcast_stats = NULL;
1459 1457 dladm_stat_chain_t *defunctlane_stats = NULL;
1460 1458 dladm_stat_chain_t *lane_stats;
1461 1459 char linkname[MAXLINKNAMELEN];
1462 1460 boolean_t is_legacy_driver;
1463 1461
1464 1462 if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
1465 1463 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
1466 1464 goto done;
1467 1465 }
1468 1466
1469 1467 /* Check if it is legacy driver */
1470 1468 if (dladm_linkprop_is_set(dh, linkid, DLADM_PROP_VAL_CURRENT,
1471 1469 "_softmac", &is_legacy_driver) != DLADM_STATUS_OK) {
1472 1470 goto done;
1473 1471 }
1474 1472
1475 1473 if (is_legacy_driver) {
1476 - head = i_dlstat_legacy_tx_lane_stats(linkname);
1474 + head = i_dlstat_legacy_tx_lane_stats(dh, linkname);
1477 1475 goto done;
1478 1476 }
1479 1477
1480 - bcast_stats = i_dlstat_tx_bcast_stats(linkname);
1481 - defunctlane_stats = i_dlstat_tx_defunctlane_stats(linkname);
1482 - lane_stats = i_dlstat_tx_hwlane_stats(linkname);
1478 + bcast_stats = i_dlstat_tx_bcast_stats(dh, linkname);
1479 + defunctlane_stats = i_dlstat_tx_defunctlane_stats(dh, linkname);
1480 + lane_stats = i_dlstat_tx_hwlane_stats(dh, linkname);
1483 1481 if (lane_stats == NULL)
1484 1482 lane_stats = i_dlstat_tx_swlane_stats(dh, linkid, linkname);
1485 1483
1486 1484 head = i_dlstat_join_lists(bcast_stats, defunctlane_stats);
1487 1485 head = i_dlstat_join_lists(head, lane_stats);
1488 1486
1489 1487 done:
1490 1488 return (head);
1491 1489 }
1492 1490
1493 1491 /* Rx lane total statistic specific functions */
1494 1492 void *
1495 1493 dlstat_rx_lane_total_stats(dladm_handle_t dh, datalink_id_t linkid)
1496 1494 {
1497 1495 dladm_stat_chain_t *total_head = NULL;
1498 1496 dladm_stat_chain_t *rx_lane_head, *curr;
1499 1497 rx_lane_stat_entry_t *total_stats;
1500 1498
1501 1499 /* Get per rx lane stats */
1502 1500 rx_lane_head = dlstat_rx_lane_stats(dh, linkid);
1503 1501 if (rx_lane_head == NULL)
1504 1502 goto done;
1505 1503
1506 1504 total_stats = calloc(1, sizeof (rx_lane_stat_entry_t));
1507 1505 if (total_stats == NULL)
1508 1506 goto done;
1509 1507
1510 1508 total_stats->rle_index = DLSTAT_INVALID_ENTRY;
1511 1509 total_stats->rle_id = DLSTAT_INVALID_ENTRY;
1512 1510
1513 1511 for (curr = rx_lane_head; curr != NULL; curr = curr->dc_next) {
1514 1512 rx_lane_stat_entry_t *curr_lane_stats = curr->dc_statentry;
1515 1513
1516 1514 i_dlstat_sum_stats(&total_stats->rle_stats,
1517 1515 &curr_lane_stats->rle_stats, &total_stats->rle_stats,
1518 1516 rx_lane_stats_list, RX_LANE_STAT_SIZE);
1519 1517 }
1520 1518
1521 1519 total_head = malloc(sizeof (dladm_stat_chain_t));
1522 1520 if (total_head == NULL) {
1523 1521 free(total_stats);
1524 1522 goto done;
1525 1523 }
1526 1524
1527 1525 total_head->dc_statentry = total_stats;
1528 1526 (void) strlcpy(total_head->dc_statheader, "mac_rx_lane_total",
1529 1527 sizeof (total_head->dc_statheader));
1530 1528 total_head->dc_next = NULL;
1531 1529 free(rx_lane_head);
1532 1530
1533 1531 done:
1534 1532 return (total_head);
1535 1533 }
1536 1534
1537 1535 /* Tx lane total statistic specific functions */
1538 1536 void *
1539 1537 dlstat_tx_lane_total_stats(dladm_handle_t dh, datalink_id_t linkid)
1540 1538 {
1541 1539 dladm_stat_chain_t *total_head = NULL;
1542 1540 dladm_stat_chain_t *tx_lane_head, *curr;
1543 1541 tx_lane_stat_entry_t *total_stats;
1544 1542
1545 1543 /* Get per tx lane stats */
1546 1544 tx_lane_head = dlstat_tx_lane_stats(dh, linkid);
1547 1545 if (tx_lane_head == NULL)
1548 1546 goto done;
1549 1547
1550 1548 total_stats = calloc(1, sizeof (tx_lane_stat_entry_t));
1551 1549 if (total_stats == NULL)
1552 1550 goto done;
1553 1551
1554 1552 total_stats->tle_index = DLSTAT_INVALID_ENTRY;
1555 1553 total_stats->tle_id = DLSTAT_INVALID_ENTRY;
1556 1554
1557 1555 for (curr = tx_lane_head; curr != NULL; curr = curr->dc_next) {
1558 1556 tx_lane_stat_entry_t *curr_lane_stats = curr->dc_statentry;
1559 1557
1560 1558 i_dlstat_sum_stats(&total_stats->tle_stats,
1561 1559 &curr_lane_stats->tle_stats, &total_stats->tle_stats,
1562 1560 tx_lane_stats_list, TX_LANE_STAT_SIZE);
1563 1561 }
1564 1562
1565 1563 total_head = malloc(sizeof (dladm_stat_chain_t));
1566 1564 if (total_head == NULL) {
1567 1565 free(total_stats);
1568 1566 goto done;
1569 1567 }
1570 1568
1571 1569 total_head->dc_statentry = total_stats;
1572 1570 (void) strlcpy(total_head->dc_statheader, "mac_tx_lane_total",
1573 1571 sizeof (total_head->dc_statheader));
1574 1572 total_head->dc_next = NULL;
1575 1573 free(tx_lane_head);
1576 1574
1577 1575 done:
1578 1576 return (total_head);
1579 1577 }
1580 1578
1581 1579 /* Fanout specific functions */
1582 1580 static boolean_t
1583 1581 i_dlstat_fanout_match(void *arg1, void *arg2)
1584 1582 {
1585 1583 fanout_stat_entry_t *s1 = arg1;
1586 1584 fanout_stat_entry_t *s2 = arg2;
1587 1585
1588 1586 return (s1->fe_index == s2->fe_index &&
1589 1587 s1->fe_id == s2->fe_id &&
1590 1588 s1->fe_foutindex == s2->fe_foutindex);
1591 1589 }
1592 1590
1593 1591 static void *
1594 1592 i_dlstat_fanout_stat_entry_diff(void *arg1, void *arg2)
1595 1593 {
1596 1594 fanout_stat_entry_t *s1 = arg1;
1597 1595 fanout_stat_entry_t *s2 = arg2;
1598 1596 fanout_stat_entry_t *diff_entry;
1599 1597
1600 1598 diff_entry = malloc(sizeof (fanout_stat_entry_t));
1601 1599 if (diff_entry == NULL)
1602 1600 goto done;
1603 1601
1604 1602 diff_entry->fe_index = s1->fe_index;
1605 1603 diff_entry->fe_id = s1->fe_id;
1606 1604 diff_entry->fe_foutindex = s1->fe_foutindex;
1607 1605
1608 1606 DLSTAT_DIFF_STAT(s1, s2, diff_entry, fe_stats, fanout_stats_list,
1609 1607 FANOUT_STAT_SIZE);
1610 1608
1611 1609 done:
1612 1610 return (diff_entry);
1613 1611 }
1614 1612
1615 1613 static void *
1616 1614 i_dlstat_fanout_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1617 1615 {
1618 1616 fanout_stat_entry_t *fanout_stat_entry;
1619 1617
1620 1618 fanout_stat_entry = calloc(1, sizeof (fanout_stat_entry_t));
1621 1619 if (fanout_stat_entry == NULL)
1622 1620 goto done;
1623 1621
1624 1622 /* Set by the caller later */
1625 1623 fanout_stat_entry->fe_index = DLSTAT_INVALID_ENTRY;
1626 1624 fanout_stat_entry->fe_id = DLSTAT_INVALID_ENTRY;
1627 1625
1628 1626 fanout_stat_entry->fe_foutindex = i;
1629 1627
1630 1628 i_dlstat_get_stats(kcp, ksp, &fanout_stat_entry->fe_stats,
1631 1629 fanout_stats_list, FANOUT_STAT_SIZE);
1632 1630
1633 1631 done:
1634 1632 return (fanout_stat_entry);
1635 1633 }
1636 1634
1637 1635 static void *
1638 1636 i_dlstat_query_fanout_stats(dladm_handle_t dh, datalink_id_t linkid,
1639 1637 uint_t idlist[], uint_t idlist_size,
1640 1638 const char *modname, const char *prefix)
1641 1639 {
1642 1640 int i;
1643 1641 char statprefix[MAXLINKNAMELEN];
1644 1642 char linkname[MAXLINKNAMELEN];
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
1645 1643 dladm_stat_chain_t *curr, *curr_head;
1646 1644 dladm_stat_chain_t *head = NULL, *prev = NULL;
1647 1645 uint_t fanout_idlist[MAX_RINGS_PER_GROUP];
1648 1646 uint_t fanout_idlist_size;
1649 1647
1650 1648 if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
1651 1649 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
1652 1650 return (NULL);
1653 1651 }
1654 1652
1655 - i_dlstat_get_idlist(linkname, DLSTAT_FANOUT_IDLIST,
1653 + i_dlstat_get_idlist(dh, linkname, DLSTAT_FANOUT_IDLIST,
1656 1654 fanout_idlist, &fanout_idlist_size);
1657 1655
1658 1656 for (i = 0; i < idlist_size; i++) {
1659 1657 uint_t index = idlist[i];
1660 1658
1661 1659 (void) snprintf(statprefix, sizeof (statprefix), "%s%d_fanout",
1662 1660 prefix, index);
1663 1661
1664 - curr_head = i_dlstat_query_stats(modname, statprefix,
1662 + curr_head = i_dlstat_query_stats(dh, modname, statprefix,
1665 1663 fanout_idlist, fanout_idlist_size,
1666 1664 i_dlstat_fanout_retrieve_stat);
1667 1665
1668 1666 if (curr_head == NULL) /* Last lane */
1669 1667 break;
1670 1668
1671 1669 if (head == NULL) /* First lane */
1672 1670 head = curr_head;
1673 1671 else /* Link new lane list to end of previous lane list */
1674 1672 prev->dc_next = curr_head;
1675 1673
1676 1674 /* Walk new lane list and set ids */
1677 1675 for (curr = curr_head; curr != NULL; curr = curr->dc_next) {
1678 1676 fanout_stat_entry_t *curr_stats = curr->dc_statentry;
1679 1677
1680 1678 curr_stats->fe_index = index;
1681 1679 curr_stats->fe_id = L_HWLANE;
1682 1680 /*
1683 1681 * Save last pointer of previous linked list.
1684 1682 * This pointer is used to chain linked lists
1685 1683 * generated in each iteration.
1686 1684 */
1687 1685 prev = curr;
1688 1686 }
1689 1687 }
1690 1688
1691 1689 return (head);
1692 1690 }
1693 1691
1694 1692 void *
1695 1693 dlstat_fanout_swlane_and_local_stats(dladm_handle_t dh, datalink_id_t linkid,
1696 1694 const char *linkname)
1697 1695 {
1698 1696 return (i_dlstat_query_fanout_stats(dh, linkid,
1699 1697 default_idlist, default_idlist_size, linkname,
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
1700 1698 DLSTAT_MAC_RX_SWLANE));
1701 1699 }
1702 1700
1703 1701 void *
1704 1702 dlstat_fanout_hwlane_stats(dladm_handle_t dh, datalink_id_t linkid,
1705 1703 const char *linkname)
1706 1704 {
1707 1705 uint_t rx_hwlane_idlist[MAX_RINGS_PER_GROUP];
1708 1706 uint_t rx_hwlane_idlist_size;
1709 1707
1710 - i_dlstat_get_idlist(linkname, DLSTAT_RX_HWLANE_IDLIST,
1708 + i_dlstat_get_idlist(dh, linkname, DLSTAT_RX_HWLANE_IDLIST,
1711 1709 rx_hwlane_idlist, &rx_hwlane_idlist_size);
1712 1710
1713 1711 return (i_dlstat_query_fanout_stats(dh, linkid, rx_hwlane_idlist,
1714 1712 rx_hwlane_idlist_size, linkname, DLSTAT_MAC_RX_HWLANE));
1715 1713 }
1716 1714
1717 1715 void *
1718 1716 dlstat_fanout_stats(dladm_handle_t dh, datalink_id_t linkid)
1719 1717 {
1720 1718 dladm_stat_chain_t *head = NULL;
1721 1719 dladm_stat_chain_t *fout_hwlane_stats;
1722 1720 dladm_stat_chain_t *fout_swlane_and_local_stats;
1723 1721 fanout_stat_entry_t *fout_stats;
1724 1722 char linkname[MAXLINKNAMELEN];
1725 1723
1726 1724 if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
1727 1725 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
1728 1726 goto done;
1729 1727 }
1730 1728
1731 1729 fout_swlane_and_local_stats =
1732 1730 dlstat_fanout_swlane_and_local_stats(dh, linkid, linkname);
1733 1731 fout_hwlane_stats = dlstat_fanout_hwlane_stats(dh, linkid, linkname);
1734 1732
1735 1733 if (fout_swlane_and_local_stats == NULL) {
1736 1734 head = fout_hwlane_stats;
1737 1735 goto done;
1738 1736 }
1739 1737
1740 1738 fout_stats = fout_swlane_and_local_stats->dc_statentry;
1741 1739
1742 1740 if (fout_hwlane_stats != NULL) { /* hwlane(s), only local traffic */
1743 1741 fout_stats->fe_id = L_LOCAL;
1744 1742 fout_stats->fe_index = DLSTAT_INVALID_ENTRY;
1745 1743 } else { /* no hwlane, mix of local+sw classified */
1746 1744 fout_stats->fe_id = L_LCLSWLANE;
1747 1745 fout_stats->fe_index = DLSTAT_INVALID_ENTRY;
1748 1746 }
1749 1747
1750 1748 fout_swlane_and_local_stats->dc_next = fout_hwlane_stats;
1751 1749 head = fout_swlane_and_local_stats;
1752 1750
1753 1751 done:
1754 1752 return (head);
1755 1753 }
1756 1754
1757 1755 /* Rx ring statistic specific functions */
1758 1756 static boolean_t
1759 1757 i_dlstat_rx_ring_match(void *arg1, void *arg2)
1760 1758 {
1761 1759 rx_lane_stat_entry_t *s1 = arg1;
1762 1760 rx_lane_stat_entry_t *s2 = arg2;
1763 1761
1764 1762 return (s1->rle_index == s2->rle_index);
1765 1763 }
1766 1764
1767 1765 static void *
1768 1766 i_dlstat_rx_ring_stat_entry_diff(void *arg1, void *arg2)
1769 1767 {
1770 1768 ring_stat_entry_t *s1 = arg1;
1771 1769 ring_stat_entry_t *s2 = arg2;
1772 1770 ring_stat_entry_t *diff_entry;
1773 1771
1774 1772 diff_entry = malloc(sizeof (ring_stat_entry_t));
1775 1773 if (diff_entry == NULL)
1776 1774 goto done;
1777 1775
1778 1776 diff_entry->re_index = s1->re_index;
1779 1777
1780 1778 DLSTAT_DIFF_STAT(s1, s2, diff_entry, re_stats, rx_ring_stats_list,
1781 1779 RX_RING_STAT_SIZE);
1782 1780
1783 1781 done:
1784 1782 return (diff_entry);
1785 1783 }
1786 1784
1787 1785 static void *
1788 1786 i_dlstat_rx_ring_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1789 1787 {
1790 1788 ring_stat_entry_t *rx_ring_stat_entry;
1791 1789
1792 1790 rx_ring_stat_entry = calloc(1, sizeof (ring_stat_entry_t));
1793 1791 if (rx_ring_stat_entry == NULL)
1794 1792 goto done;
1795 1793
1796 1794 rx_ring_stat_entry->re_index = i;
1797 1795
1798 1796 i_dlstat_get_stats(kcp, ksp, &rx_ring_stat_entry->re_stats,
1799 1797 rx_ring_stats_list, RX_RING_STAT_SIZE);
1800 1798
1801 1799 done:
1802 1800 return (rx_ring_stat_entry);
1803 1801 }
1804 1802
1805 1803 void *
1806 1804 dlstat_rx_ring_stats(dladm_handle_t dh, datalink_id_t linkid)
1807 1805 {
1808 1806 uint_t rx_ring_idlist[MAX_RINGS_PER_GROUP];
1809 1807 uint_t rx_ring_idlist_size;
1810 1808 dladm_phys_attr_t dpa;
1811 1809 char linkname[MAXLINKNAMELEN];
1812 1810 char *modname;
1813 1811 datalink_class_t class;
1814 1812
1815 1813 /*
1816 1814 * kstats corresponding to physical device rings continue to use
1817 1815 * device names even if the link is renamed using dladm rename-link.
1818 1816 * Thus, given a linkid, we lookup the physical device name.
1819 1817 * However, if an aggr is renamed, kstats corresponding to its
1820 1818 * pseudo rings are renamed as well.
1821 1819 */
1822 1820 if (dladm_datalink_id2info(dh, linkid, NULL, &class, NULL, linkname,
1823 1821 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
1824 1822 return (NULL);
1825 1823 }
↓ open down ↓ |
105 lines elided |
↑ open up ↑ |
1826 1824
1827 1825 if (class != DATALINK_CLASS_AGGR) {
1828 1826 if (dladm_phys_info(dh, linkid, &dpa, DLADM_OPT_ACTIVE) !=
1829 1827 DLADM_STATUS_OK) {
1830 1828 return (NULL);
1831 1829 }
1832 1830 modname = dpa.dp_dev;
1833 1831 } else
1834 1832 modname = linkname;
1835 1833
1836 - i_dlstat_get_idlist(modname, DLSTAT_RX_RING_IDLIST,
1834 + i_dlstat_get_idlist(dh, modname, DLSTAT_RX_RING_IDLIST,
1837 1835 rx_ring_idlist, &rx_ring_idlist_size);
1838 1836
1839 - return (i_dlstat_query_stats(modname, DLSTAT_MAC_RX_RING,
1837 + return (i_dlstat_query_stats(dh, modname, DLSTAT_MAC_RX_RING,
1840 1838 rx_ring_idlist, rx_ring_idlist_size,
1841 1839 i_dlstat_rx_ring_retrieve_stat));
1842 1840 }
1843 1841
1844 1842 /* Tx ring statistic specific functions */
1845 1843 static boolean_t
1846 1844 i_dlstat_tx_ring_match(void *arg1, void *arg2)
1847 1845 {
1848 1846 tx_lane_stat_entry_t *s1 = arg1;
1849 1847 tx_lane_stat_entry_t *s2 = arg2;
1850 1848
1851 1849 return (s1->tle_index == s2->tle_index);
1852 1850 }
1853 1851
1854 1852 static void *
1855 1853 i_dlstat_tx_ring_stat_entry_diff(void *arg1, void *arg2)
1856 1854 {
1857 1855 ring_stat_entry_t *s1 = arg1;
1858 1856 ring_stat_entry_t *s2 = arg2;
1859 1857 ring_stat_entry_t *diff_entry;
1860 1858
1861 1859 diff_entry = malloc(sizeof (ring_stat_entry_t));
1862 1860 if (diff_entry == NULL)
1863 1861 goto done;
1864 1862
1865 1863 diff_entry->re_index = s1->re_index;
1866 1864
1867 1865 DLSTAT_DIFF_STAT(s1, s2, diff_entry, re_stats, tx_ring_stats_list,
1868 1866 TX_RING_STAT_SIZE);
1869 1867
1870 1868 done:
1871 1869 return (diff_entry);
1872 1870 }
1873 1871
1874 1872 static void *
1875 1873 i_dlstat_tx_ring_retrieve_stat(kstat_ctl_t *kcp, kstat_t *ksp, int i)
1876 1874 {
1877 1875 ring_stat_entry_t *tx_ring_stat_entry;
1878 1876
1879 1877 tx_ring_stat_entry = calloc(1, sizeof (ring_stat_entry_t));
1880 1878 if (tx_ring_stat_entry == NULL)
1881 1879 goto done;
1882 1880
1883 1881 tx_ring_stat_entry->re_index = i;
1884 1882
1885 1883 i_dlstat_get_stats(kcp, ksp, &tx_ring_stat_entry->re_stats,
1886 1884 tx_ring_stats_list, TX_RING_STAT_SIZE);
1887 1885
1888 1886 done:
1889 1887 return (tx_ring_stat_entry);
1890 1888 }
1891 1889
1892 1890 void *
1893 1891 dlstat_tx_ring_stats(dladm_handle_t dh, datalink_id_t linkid)
1894 1892 {
1895 1893 uint_t tx_ring_idlist[MAX_RINGS_PER_GROUP];
1896 1894 uint_t tx_ring_idlist_size;
1897 1895 dladm_phys_attr_t dpa;
1898 1896 char linkname[MAXLINKNAMELEN];
1899 1897 char *modname;
1900 1898 datalink_class_t class;
1901 1899
1902 1900 /*
1903 1901 * kstats corresponding to physical device rings continue to use
1904 1902 * device names even if the link is renamed using dladm rename-link.
1905 1903 * Thus, given a linkid, we lookup the physical device name.
1906 1904 * However, if an aggr is renamed, kstats corresponding to its
1907 1905 * pseudo rings are renamed as well.
1908 1906 */
1909 1907 if (dladm_datalink_id2info(dh, linkid, NULL, &class, NULL, linkname,
1910 1908 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
1911 1909 return (NULL);
1912 1910 }
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
1913 1911
1914 1912 if (class != DATALINK_CLASS_AGGR) {
1915 1913 if (dladm_phys_info(dh, linkid, &dpa, DLADM_OPT_ACTIVE) !=
1916 1914 DLADM_STATUS_OK) {
1917 1915 return (NULL);
1918 1916 }
1919 1917 modname = dpa.dp_dev;
1920 1918 } else
1921 1919 modname = linkname;
1922 1920
1923 - i_dlstat_get_idlist(modname, DLSTAT_TX_RING_IDLIST,
1921 + i_dlstat_get_idlist(dh, modname, DLSTAT_TX_RING_IDLIST,
1924 1922 tx_ring_idlist, &tx_ring_idlist_size);
1925 1923
1926 - return (i_dlstat_query_stats(modname, DLSTAT_MAC_TX_RING,
1924 + return (i_dlstat_query_stats(dh, modname, DLSTAT_MAC_TX_RING,
1927 1925 tx_ring_idlist, tx_ring_idlist_size,
1928 1926 i_dlstat_tx_ring_retrieve_stat));
1929 1927 }
1930 1928
1931 1929 /* Rx ring total statistic specific functions */
1932 1930 void *
1933 1931 dlstat_rx_ring_total_stats(dladm_handle_t dh, datalink_id_t linkid)
1934 1932 {
1935 1933 dladm_stat_chain_t *total_head = NULL;
1936 1934 dladm_stat_chain_t *rx_ring_head, *curr;
1937 1935 ring_stat_entry_t *total_stats;
1938 1936
1939 1937 /* Get per rx ring stats */
1940 1938 rx_ring_head = dlstat_rx_ring_stats(dh, linkid);
1941 1939 if (rx_ring_head == NULL)
1942 1940 goto done;
1943 1941
1944 1942 total_stats = calloc(1, sizeof (ring_stat_entry_t));
1945 1943 if (total_stats == NULL)
1946 1944 goto done;
1947 1945
1948 1946 total_stats->re_index = DLSTAT_INVALID_ENTRY;
1949 1947
1950 1948 for (curr = rx_ring_head; curr != NULL; curr = curr->dc_next) {
1951 1949 ring_stat_entry_t *curr_ring_stats = curr->dc_statentry;
1952 1950
1953 1951 i_dlstat_sum_stats(&total_stats->re_stats,
1954 1952 &curr_ring_stats->re_stats, &total_stats->re_stats,
1955 1953 rx_ring_stats_list, RX_RING_STAT_SIZE);
1956 1954 }
1957 1955
1958 1956 total_head = malloc(sizeof (dladm_stat_chain_t));
1959 1957 if (total_head == NULL) {
1960 1958 free(total_stats);
1961 1959 goto done;
1962 1960 }
1963 1961
1964 1962 total_head->dc_statentry = total_stats;
1965 1963 (void) strlcpy(total_head->dc_statheader, "mac_rx_ring_total",
1966 1964 sizeof (total_head->dc_statheader));
1967 1965 total_head->dc_next = NULL;
1968 1966 free(rx_ring_head);
1969 1967
1970 1968 done:
1971 1969 return (total_head);
1972 1970 }
1973 1971
1974 1972 /* Tx ring total statistic specific functions */
1975 1973 void *
1976 1974 dlstat_tx_ring_total_stats(dladm_handle_t dh, datalink_id_t linkid)
1977 1975 {
1978 1976 dladm_stat_chain_t *total_head = NULL;
1979 1977 dladm_stat_chain_t *tx_ring_head, *curr;
1980 1978 ring_stat_entry_t *total_stats;
1981 1979
1982 1980 /* Get per tx ring stats */
1983 1981 tx_ring_head = dlstat_tx_ring_stats(dh, linkid);
1984 1982 if (tx_ring_head == NULL)
1985 1983 goto done;
1986 1984
1987 1985 total_stats = calloc(1, sizeof (ring_stat_entry_t));
1988 1986 if (total_stats == NULL)
1989 1987 goto done;
1990 1988
1991 1989 total_stats->re_index = DLSTAT_INVALID_ENTRY;
1992 1990
1993 1991 for (curr = tx_ring_head; curr != NULL; curr = curr->dc_next) {
1994 1992 ring_stat_entry_t *curr_ring_stats = curr->dc_statentry;
1995 1993
1996 1994 i_dlstat_sum_stats(&total_stats->re_stats,
1997 1995 &curr_ring_stats->re_stats, &total_stats->re_stats,
1998 1996 tx_ring_stats_list, TX_RING_STAT_SIZE);
1999 1997 }
2000 1998
2001 1999 total_head = malloc(sizeof (dladm_stat_chain_t));
2002 2000 if (total_head == NULL) {
2003 2001 free(total_stats);
2004 2002 goto done;
2005 2003 }
2006 2004
2007 2005 total_head->dc_statentry = total_stats;
2008 2006 (void) strlcpy(total_head->dc_statheader, "mac_tx_ring_total",
2009 2007 sizeof (total_head->dc_statheader));
2010 2008 total_head->dc_next = NULL;
2011 2009 free(tx_ring_head);
2012 2010
2013 2011 done:
2014 2012 return (total_head);
2015 2013 }
2016 2014
2017 2015 /* Summary statistic specific functions */
2018 2016 /*ARGSUSED*/
2019 2017 static boolean_t
2020 2018 i_dlstat_total_match(void *arg1, void *arg2)
2021 2019 {
2022 2020 /* Always single entry for total */
2023 2021 return (B_TRUE);
2024 2022 }
2025 2023
2026 2024 static void *
2027 2025 i_dlstat_total_stat_entry_diff(void *arg1, void *arg2)
2028 2026 {
2029 2027 total_stat_entry_t *s1 = arg1;
2030 2028 total_stat_entry_t *s2 = arg2;
2031 2029 total_stat_entry_t *diff_entry;
2032 2030
2033 2031 diff_entry = malloc(sizeof (total_stat_entry_t));
2034 2032 if (diff_entry == NULL)
2035 2033 goto done;
2036 2034
2037 2035 DLSTAT_DIFF_STAT(s1, s2, diff_entry, tse_stats, total_stats_list,
2038 2036 TOTAL_STAT_SIZE);
2039 2037
2040 2038 done:
2041 2039 return (diff_entry);
2042 2040 }
2043 2041
2044 2042 void *
2045 2043 dlstat_total_stats(dladm_handle_t dh, datalink_id_t linkid)
2046 2044 {
2047 2045 dladm_stat_chain_t *head = NULL;
2048 2046 dladm_stat_chain_t *rx_total;
2049 2047 dladm_stat_chain_t *tx_total;
2050 2048 total_stat_entry_t *total_stat_entry;
2051 2049 rx_lane_stat_entry_t *rx_lane_stat_entry;
2052 2050 tx_lane_stat_entry_t *tx_lane_stat_entry;
2053 2051
2054 2052 /* Get total rx lane stats */
2055 2053 rx_total = dlstat_rx_lane_total_stats(dh, linkid);
2056 2054 if (rx_total == NULL)
2057 2055 goto done;
2058 2056
2059 2057 /* Get total tx lane stats */
2060 2058 tx_total = dlstat_tx_lane_total_stats(dh, linkid);
2061 2059 if (tx_total == NULL)
2062 2060 goto done;
2063 2061
2064 2062 /* Build total stat */
2065 2063 total_stat_entry = calloc(1, sizeof (total_stat_entry_t));
2066 2064 if (total_stat_entry == NULL)
2067 2065 goto done;
2068 2066
2069 2067 rx_lane_stat_entry = rx_total->dc_statentry;
2070 2068 tx_lane_stat_entry = tx_total->dc_statentry;
2071 2069
2072 2070 /* Extract total rx ipackets, rbytes */
2073 2071 total_stat_entry->tse_stats.ts_ipackets =
2074 2072 rx_lane_stat_entry->rle_stats.rl_ipackets;
2075 2073 total_stat_entry->tse_stats.ts_rbytes =
2076 2074 rx_lane_stat_entry->rle_stats.rl_rbytes;
2077 2075
2078 2076 /* Extract total tx opackets, obytes */
2079 2077 total_stat_entry->tse_stats.ts_opackets =
2080 2078 tx_lane_stat_entry->tle_stats.tl_opackets;
2081 2079 total_stat_entry->tse_stats.ts_obytes =
2082 2080 tx_lane_stat_entry->tle_stats.tl_obytes;
2083 2081
2084 2082 head = malloc(sizeof (dladm_stat_chain_t));
2085 2083 if (head == NULL) {
2086 2084 free(total_stat_entry);
2087 2085 goto done;
2088 2086 }
2089 2087
2090 2088 head->dc_statentry = total_stat_entry;
2091 2089 (void) strlcpy(head->dc_statheader, "mac_lane_total",
2092 2090 sizeof (head->dc_statheader));
2093 2091 head->dc_next = NULL;
2094 2092 free(rx_total);
2095 2093 free(tx_total);
2096 2094
2097 2095 done:
2098 2096 return (head);
2099 2097 }
2100 2098
2101 2099 /* Aggr total statistic(summed across all component ports) specific functions */
2102 2100 void *
2103 2101 dlstat_aggr_total_stats(dladm_stat_chain_t *head)
2104 2102 {
2105 2103 dladm_stat_chain_t *curr;
2106 2104 dladm_stat_chain_t *total_head;
2107 2105 aggr_port_stat_entry_t *total_stats;
2108 2106
2109 2107 total_stats = calloc(1, sizeof (aggr_port_stat_entry_t));
2110 2108 if (total_stats == NULL)
2111 2109 goto done;
2112 2110
2113 2111 total_stats->ape_portlinkid = DATALINK_INVALID_LINKID;
2114 2112
2115 2113 for (curr = head; curr != NULL; curr = curr->dc_next) {
2116 2114 aggr_port_stat_entry_t *curr_aggr_port_stats;
2117 2115
2118 2116 curr_aggr_port_stats = curr->dc_statentry;
2119 2117
2120 2118 i_dlstat_sum_stats(&total_stats->ape_stats,
2121 2119 &curr_aggr_port_stats->ape_stats, &total_stats->ape_stats,
2122 2120 aggr_port_stats_list, AGGR_PORT_STAT_SIZE);
2123 2121 }
2124 2122
2125 2123 total_head = malloc(sizeof (dladm_stat_chain_t));
2126 2124 if (total_head == NULL) {
2127 2125 free(total_stats);
2128 2126 goto done;
2129 2127 }
2130 2128
2131 2129 total_head->dc_statentry = total_stats;
2132 2130 total_head->dc_next = NULL;
2133 2131
2134 2132 done:
2135 2133 return (total_head);
2136 2134 }
2137 2135
2138 2136 /* Aggr port statistic specific functions */
2139 2137 static boolean_t
2140 2138 i_dlstat_aggr_port_match(void *arg1, void *arg2)
2141 2139 {
2142 2140 aggr_port_stat_entry_t *s1 = arg1;
2143 2141 aggr_port_stat_entry_t *s2 = arg2;
2144 2142
2145 2143 return (s1->ape_portlinkid == s2->ape_portlinkid);
2146 2144 }
2147 2145
2148 2146 static void *
2149 2147 i_dlstat_aggr_port_stat_entry_diff(void *arg1, void *arg2)
2150 2148 {
2151 2149 aggr_port_stat_entry_t *s1 = arg1;
2152 2150 aggr_port_stat_entry_t *s2 = arg2;
2153 2151 aggr_port_stat_entry_t *diff_entry;
2154 2152
2155 2153 diff_entry = malloc(sizeof (aggr_port_stat_entry_t));
2156 2154 if (diff_entry == NULL)
2157 2155 goto done;
2158 2156
2159 2157 diff_entry->ape_portlinkid = s1->ape_portlinkid;
2160 2158
2161 2159 DLSTAT_DIFF_STAT(s1, s2, diff_entry, ape_stats, aggr_port_stats_list,
2162 2160 AGGR_PORT_STAT_SIZE);
↓ open down ↓ |
226 lines elided |
↑ open up ↑ |
2163 2161
2164 2162 done:
2165 2163 return (diff_entry);
2166 2164 }
2167 2165
2168 2166 /*
2169 2167 * Query dls stats for the aggr port. This results in query for stats into
2170 2168 * the corresponding device driver.
2171 2169 */
2172 2170 static aggr_port_stat_entry_t *
2173 -i_dlstat_single_port_stats(const char *portname, datalink_id_t linkid)
2171 +i_dlstat_single_port_stats(dladm_handle_t handle, const char *portname,
2172 + datalink_id_t linkid)
2174 2173 {
2175 - kstat_ctl_t *kcp;
2176 2174 kstat_t *ksp;
2177 2175 char module[DLPI_LINKNAME_MAX];
2178 2176 uint_t instance;
2179 2177 aggr_port_stat_entry_t *aggr_port_stat_entry = NULL;
2180 2178
2181 2179 if (dladm_parselink(portname, module, &instance) != DLADM_STATUS_OK)
2182 2180 goto done;
2183 2181
2184 - if ((kcp = kstat_open()) == NULL) {
2182 + if (dladm_dld_kcp(handle) == NULL) {
2185 2183 warn("kstat open operation failed");
2186 2184 return (NULL);
2187 2185 }
2188 2186
2189 - ksp = dladm_kstat_lookup(kcp, module, instance, "mac", NULL);
2187 + ksp = dladm_kstat_lookup(dladm_dld_kcp(handle), module, instance,
2188 + "mac", NULL);
2190 2189 if (ksp == NULL)
2191 2190 goto done;
2192 2191
2193 2192 aggr_port_stat_entry = calloc(1, sizeof (aggr_port_stat_entry_t));
2194 2193 if (aggr_port_stat_entry == NULL)
2195 2194 goto done;
2196 2195
2197 2196 /* Save port's linkid */
2198 2197 aggr_port_stat_entry->ape_portlinkid = linkid;
2199 2198
2200 - i_dlstat_get_stats(kcp, ksp, &aggr_port_stat_entry->ape_stats,
2199 + i_dlstat_get_stats(dladm_dld_kcp(handle), ksp,
2200 + &aggr_port_stat_entry->ape_stats,
2201 2201 aggr_port_stats_list, AGGR_PORT_STAT_SIZE);
2202 2202 done:
2203 - (void) kstat_close(kcp);
2204 2203 return (aggr_port_stat_entry);
2205 2204 }
2206 2205
2207 2206 void *
2208 2207 dlstat_aggr_port_stats(dladm_handle_t dh, datalink_id_t linkid)
2209 2208 {
2210 2209 dladm_aggr_grp_attr_t ginfo;
2211 2210 int i;
2212 2211 dladm_aggr_port_attr_t *portp;
2213 2212 dladm_phys_attr_t dpa;
2214 2213 aggr_port_stat_entry_t *aggr_port_stat_entry;
2215 2214 dladm_stat_chain_t *head = NULL, *prev = NULL, *curr;
2216 2215 dladm_stat_chain_t *total_stats;
2217 2216
2218 2217 /* Get aggr info */
2219 2218 bzero(&ginfo, sizeof (dladm_aggr_grp_attr_t));
2220 2219 if (dladm_aggr_info(dh, linkid, &ginfo, DLADM_OPT_ACTIVE)
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
2221 2220 != DLADM_STATUS_OK)
2222 2221 goto done;
2223 2222 /* For every port that is member of this aggr do */
2224 2223 for (i = 0; i < ginfo.lg_nports; i++) {
2225 2224 portp = &(ginfo.lg_ports[i]);
2226 2225 if (dladm_phys_info(dh, portp->lp_linkid, &dpa,
2227 2226 DLADM_OPT_ACTIVE) != DLADM_STATUS_OK) {
2228 2227 goto done;
2229 2228 }
2230 2229
2231 - aggr_port_stat_entry = i_dlstat_single_port_stats(dpa.dp_dev,
2232 - portp->lp_linkid);
2230 + aggr_port_stat_entry = i_dlstat_single_port_stats(dh,
2231 + dpa.dp_dev, portp->lp_linkid);
2233 2232
2234 2233 /* Create dladm_stat_chain_t object for this stat */
2235 2234 curr = malloc(sizeof (dladm_stat_chain_t));
2236 2235 if (curr == NULL) {
2237 2236 free(aggr_port_stat_entry);
2238 2237 goto done;
2239 2238 }
2240 2239 (void) strlcpy(curr->dc_statheader, dpa.dp_dev,
2241 2240 sizeof (curr->dc_statheader));
2242 2241 curr->dc_statentry = aggr_port_stat_entry;
2243 2242 curr->dc_next = NULL;
2244 2243
2245 2244 /* Chain this aggr port stat entry */
2246 2245 /* head of the stat list */
2247 2246 if (prev == NULL)
2248 2247 head = curr;
2249 2248 else
2250 2249 prev->dc_next = curr;
2251 2250 prev = curr;
2252 2251 }
2253 2252
2254 2253 /*
2255 2254 * Prepend the stat list with cumulative aggr stats i.e. summed over all
2256 2255 * component ports
2257 2256 */
2258 2257 total_stats = dlstat_aggr_total_stats(head);
2259 2258 if (total_stats != NULL) {
2260 2259 total_stats->dc_next = head;
2261 2260 head = total_stats;
2262 2261 }
2263 2262
2264 2263 done:
2265 2264 free(ginfo.lg_ports);
2266 2265 return (head);
2267 2266 }
2268 2267
2269 2268 /* Misc stat specific functions */
2270 2269 void *
2271 2270 dlstat_misc_stats(dladm_handle_t dh, datalink_id_t linkid)
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
2272 2271 {
2273 2272 misc_stat_entry_t *misc_stat_entry;
2274 2273 dladm_stat_chain_t *head = NULL;
2275 2274 char linkname[MAXLINKNAMELEN];
2276 2275
2277 2276 if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname,
2278 2277 DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) {
2279 2278 goto done;
2280 2279 }
2281 2280
2282 - misc_stat_entry = i_dlstat_misc_stats(linkname);
2281 + misc_stat_entry = i_dlstat_misc_stats(dh, linkname);
2283 2282 if (misc_stat_entry == NULL)
2284 2283 goto done;
2285 2284
2286 2285 head = malloc(sizeof (dladm_stat_chain_t));
2287 2286 if (head == NULL) {
2288 2287 free(misc_stat_entry);
2289 2288 goto done;
2290 2289 }
2291 2290
2292 2291 head->dc_statentry = misc_stat_entry;
2293 2292 (void) strlcpy(head->dc_statheader, "mac_misc_stat",
2294 2293 sizeof (head->dc_statheader));
2295 2294 head->dc_next = NULL;
2296 2295
2297 2296 done:
2298 2297 return (head);
2299 2298 }
2300 2299
2301 2300 /* Exported functions */
2302 2301 dladm_stat_chain_t *
2303 2302 dladm_link_stat_query(dladm_handle_t dh, datalink_id_t linkid,
2304 2303 dladm_stat_type_t stattype)
2305 2304 {
2306 2305 return (dladm_stat_table[stattype].ds_querystat(dh, linkid));
2307 2306 }
2308 2307
2309 2308 dladm_stat_chain_t *
2310 2309 dladm_link_stat_diffchain(dladm_stat_chain_t *op1, dladm_stat_chain_t *op2,
2311 2310 dladm_stat_type_t stattype)
2312 2311 {
2313 2312 dladm_stat_chain_t *op1_curr, *op2_curr;
2314 2313 dladm_stat_chain_t *diff_curr;
2315 2314 dladm_stat_chain_t *diff_prev = NULL, *diff_head = NULL;
2316 2315
2317 2316 /* Perform op1 - op2, store result in diff */
2318 2317 for (op1_curr = op1; op1_curr != NULL; op1_curr = op1_curr->dc_next) {
2319 2318 for (op2_curr = op2; op2_curr != NULL;
2320 2319 op2_curr = op2_curr->dc_next) {
2321 2320 if (dlstat_match_stats(op1_curr->dc_statentry,
2322 2321 op2_curr->dc_statentry, stattype)) {
2323 2322 break;
2324 2323 }
2325 2324 }
2326 2325 diff_curr = malloc(sizeof (dladm_stat_chain_t));
2327 2326 if (diff_curr == NULL)
2328 2327 goto done;
2329 2328
2330 2329 diff_curr->dc_next = NULL;
2331 2330
2332 2331 if (op2_curr == NULL) {
2333 2332 /* prev iteration did not have this stat entry */
2334 2333 diff_curr->dc_statentry =
2335 2334 dlstat_diff_stats(op1_curr->dc_statentry,
2336 2335 NULL, stattype);
2337 2336 } else {
2338 2337 diff_curr->dc_statentry =
2339 2338 dlstat_diff_stats(op1_curr->dc_statentry,
2340 2339 op2_curr->dc_statentry, stattype);
2341 2340 }
2342 2341
2343 2342 if (diff_curr->dc_statentry == NULL) {
2344 2343 free(diff_curr);
2345 2344 goto done;
2346 2345 }
2347 2346
2348 2347 if (diff_prev == NULL) /* head of the diff stat list */
2349 2348 diff_head = diff_curr;
2350 2349 else
2351 2350 diff_prev->dc_next = diff_curr;
2352 2351 diff_prev = diff_curr;
2353 2352 }
2354 2353 done:
2355 2354 return (diff_head);
2356 2355 }
2357 2356
2358 2357 void
2359 2358 dladm_link_stat_free(dladm_stat_chain_t *curr)
2360 2359 {
2361 2360 while (curr != NULL) {
2362 2361 dladm_stat_chain_t *tofree = curr;
2363 2362
2364 2363 curr = curr->dc_next;
2365 2364 free(tofree->dc_statentry);
2366 2365 free(tofree);
2367 2366 }
2368 2367 }
2369 2368
2370 2369 /* Query all link stats */
2371 2370 static name_value_stat_t *
2372 2371 i_dlstat_convert_stats(void *stats, stat_info_t stats_list[], uint_t size)
2373 2372 {
2374 2373 int i;
2375 2374 name_value_stat_t *head_stat = NULL, *prev_stat = NULL;
2376 2375 name_value_stat_t *curr_stat;
2377 2376
2378 2377 for (i = 0; i < size; i++) {
2379 2378 uint64_t *val = (void *)
2380 2379 ((uchar_t *)stats + stats_list[i].si_offset);
2381 2380
2382 2381 curr_stat = calloc(1, sizeof (name_value_stat_t));
2383 2382 if (curr_stat == NULL)
2384 2383 break;
2385 2384
2386 2385 (void) strlcpy(curr_stat->nv_statname, stats_list[i].si_name,
2387 2386 sizeof (curr_stat->nv_statname));
2388 2387 curr_stat->nv_statval = *val;
2389 2388 curr_stat->nv_nextstat = NULL;
2390 2389
2391 2390 if (head_stat == NULL) /* First node */
2392 2391 head_stat = curr_stat;
2393 2392 else
2394 2393 prev_stat->nv_nextstat = curr_stat;
2395 2394
2396 2395 prev_stat = curr_stat;
2397 2396 }
2398 2397 return (head_stat);
2399 2398 }
2400 2399
2401 2400 void *
2402 2401 build_nvs_entry(char *statheader, void *statentry, dladm_stat_type_t stattype)
2403 2402 {
2404 2403 name_value_stat_entry_t *name_value_stat_entry;
2405 2404 dladm_stat_desc_t *stattbl_ptr;
2406 2405 void *statfields;
2407 2406
2408 2407 stattbl_ptr = &dladm_stat_table[stattype];
2409 2408
2410 2409 /* Allocate memory for query all stat entry */
2411 2410 name_value_stat_entry = calloc(1, sizeof (name_value_stat_entry_t));
2412 2411 if (name_value_stat_entry == NULL)
2413 2412 goto done;
2414 2413
2415 2414 /* Header for these stat fields */
2416 2415 (void) strlcpy(name_value_stat_entry->nve_header, statheader,
2417 2416 sizeof (name_value_stat_entry->nve_header));
2418 2417
2419 2418 /* Extract stat fields from the statentry */
2420 2419 statfields = (uchar_t *)statentry +
2421 2420 dladm_stat_table[stattype].ds_offset;
2422 2421
2423 2422 /* Convert curr_stat to <statname, statval> pair */
2424 2423 name_value_stat_entry->nve_stats =
2425 2424 i_dlstat_convert_stats(statfields,
2426 2425 stattbl_ptr->ds_statlist, stattbl_ptr->ds_statsize);
2427 2426 done:
2428 2427 return (name_value_stat_entry);
2429 2428 }
2430 2429
2431 2430 void *
2432 2431 i_walk_dlstat_chain(dladm_stat_chain_t *stat_head, dladm_stat_type_t stattype)
2433 2432 {
2434 2433 dladm_stat_chain_t *curr;
2435 2434 dladm_stat_chain_t *nvstat_head = NULL, *nvstat_prev = NULL;
2436 2435 dladm_stat_chain_t *nvstat_curr;
2437 2436
2438 2437 /*
2439 2438 * For every stat in the chain, build header and convert all
2440 2439 * its stat fields
2441 2440 */
2442 2441 for (curr = stat_head; curr != NULL; curr = curr->dc_next) {
2443 2442 nvstat_curr = malloc(sizeof (dladm_stat_chain_t));
2444 2443 if (nvstat_curr == NULL)
2445 2444 break;
2446 2445
2447 2446 nvstat_curr->dc_statentry = build_nvs_entry(curr->dc_statheader,
2448 2447 curr->dc_statentry, stattype);
2449 2448
2450 2449 if (nvstat_curr->dc_statentry == NULL) {
2451 2450 free(nvstat_curr);
2452 2451 break;
2453 2452 }
2454 2453
2455 2454 nvstat_curr->dc_next = NULL;
2456 2455
2457 2456 if (nvstat_head == NULL) /* First node */
2458 2457 nvstat_head = nvstat_curr;
2459 2458 else
2460 2459 nvstat_prev->dc_next = nvstat_curr;
2461 2460
2462 2461 nvstat_prev = nvstat_curr;
2463 2462 }
2464 2463 done:
2465 2464 return (nvstat_head);
2466 2465 }
2467 2466
2468 2467 dladm_stat_chain_t *
2469 2468 dladm_link_stat_query_all(dladm_handle_t dh, datalink_id_t linkid,
2470 2469 dladm_stat_type_t stattype)
2471 2470 {
2472 2471 dladm_stat_chain_t *stat_head;
2473 2472 dladm_stat_chain_t *nvstat_head = NULL;
2474 2473
2475 2474 /* Query the requested stat */
2476 2475 stat_head = dladm_link_stat_query(dh, linkid, stattype);
2477 2476 if (stat_head == NULL)
2478 2477 goto done;
2479 2478
2480 2479 /*
2481 2480 * Convert every statfield in every stat-entry of stat chain to
2482 2481 * <statname, statval> pair
2483 2482 */
2484 2483 nvstat_head = i_walk_dlstat_chain(stat_head, stattype);
2485 2484
2486 2485 /* Free stat_head */
2487 2486 dladm_link_stat_free(stat_head);
2488 2487
2489 2488 done:
2490 2489 return (nvstat_head);
2491 2490 }
2492 2491
2493 2492 void
2494 2493 dladm_link_stat_query_all_free(dladm_stat_chain_t *curr)
2495 2494 {
2496 2495 while (curr != NULL) {
2497 2496 dladm_stat_chain_t *tofree = curr;
2498 2497 name_value_stat_entry_t *nv_entry = curr->dc_statentry;
2499 2498 name_value_stat_t *nv_curr = nv_entry->nve_stats;
2500 2499
2501 2500 while (nv_curr != NULL) {
2502 2501 name_value_stat_t *nv_tofree = nv_curr;
2503 2502
2504 2503 nv_curr = nv_curr->nv_nextstat;
2505 2504 free(nv_tofree);
↓ open down ↓ |
213 lines elided |
↑ open up ↑ |
2506 2505 }
2507 2506
2508 2507 curr = curr->dc_next;
2509 2508 free(nv_entry);
2510 2509 free(tofree);
2511 2510 }
2512 2511 }
2513 2512
2514 2513 /* flow stats specific routines */
2515 2514 flow_stat_t *
2516 -dladm_flow_stat_query(const char *flowname)
2515 +dladm_flow_stat_query(dladm_handle_t handle, const char *flowname)
2517 2516 {
2518 - kstat_ctl_t *kcp;
2519 2517 kstat_t *ksp;
2520 2518 flow_stat_t *flow_stat = NULL;
2521 2519
2522 - if ((kcp = kstat_open()) == NULL)
2520 + if (dladm_dld_kcp(handle) == NULL)
2523 2521 return (NULL);
2524 2522
2525 2523 flow_stat = calloc(1, sizeof (flow_stat_t));
2526 2524 if (flow_stat == NULL)
2527 2525 goto done;
2528 2526
2529 - ksp = dladm_kstat_lookup(kcp, NULL, -1, flowname, "flow");
2527 + ksp = dladm_kstat_lookup(dladm_dld_kcp(handle), NULL, -1, flowname,
2528 + "flow");
2530 2529
2531 2530 if (ksp != NULL) {
2532 - i_dlstat_get_stats(kcp, ksp, flow_stat, flow_stats_list,
2533 - FLOW_STAT_SIZE);
2531 + i_dlstat_get_stats(dladm_dld_kcp(handle), ksp, flow_stat,
2532 + flow_stats_list, FLOW_STAT_SIZE);
2534 2533 }
2535 2534
2536 2535 done:
2537 - (void) kstat_close(kcp);
2538 2536 return (flow_stat);
2539 2537 }
2540 2538
2541 2539 flow_stat_t *
2542 2540 dladm_flow_stat_diff(flow_stat_t *op1, flow_stat_t *op2)
2543 2541 {
2544 2542 flow_stat_t *diff_stat;
2545 2543
2546 2544 diff_stat = calloc(1, sizeof (flow_stat_t));
2547 2545 if (diff_stat == NULL)
2548 2546 goto done;
2549 2547
2550 2548 if (op2 == NULL) {
2551 2549 bcopy(op1, diff_stat, sizeof (flow_stat_t));
2552 2550 } else {
2553 2551 i_dlstat_diff_stats(diff_stat, op1, op2, flow_stats_list,
2554 2552 FLOW_STAT_SIZE);
2555 2553 }
2556 2554 done:
2557 2555 return (diff_stat);
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
2558 2556 }
2559 2557
2560 2558 void
2561 2559 dladm_flow_stat_free(flow_stat_t *curr)
2562 2560 {
2563 2561 free(curr);
2564 2562 }
2565 2563
2566 2564 /* Query all flow stats */
2567 2565 name_value_stat_entry_t *
2568 -dladm_flow_stat_query_all(const char *flowname)
2566 +dladm_flow_stat_query_all(dladm_handle_t handle, const char *flowname)
2569 2567 {
2570 2568 flow_stat_t *flow_stat;
2571 2569 name_value_stat_entry_t *name_value_stat_entry = NULL;
2572 2570
2573 2571 /* Query flow stats */
2574 - flow_stat = dladm_flow_stat_query(flowname);
2572 + flow_stat = dladm_flow_stat_query(handle, flowname);
2575 2573 if (flow_stat == NULL)
2576 2574 goto done;
2577 2575
2578 2576 /* Allocate memory for query all stat entry */
2579 2577 name_value_stat_entry = calloc(1, sizeof (name_value_stat_entry_t));
2580 2578 if (name_value_stat_entry == NULL) {
2581 2579 dladm_flow_stat_free(flow_stat);
2582 2580 goto done;
2583 2581 }
2584 2582
2585 2583 /* Header for these stat fields */
2586 2584 (void) strncpy(name_value_stat_entry->nve_header, flowname,
2587 2585 MAXFLOWNAMELEN);
2588 2586
2589 2587 /* Convert every statfield in flow_stat to <statname, statval> pair */
2590 2588 name_value_stat_entry->nve_stats =
2591 2589 i_dlstat_convert_stats(flow_stat, flow_stats_list, FLOW_STAT_SIZE);
2592 2590
2593 2591 /* Free flow_stat */
2594 2592 dladm_flow_stat_free(flow_stat);
2595 2593
2596 2594 done:
2597 2595 return (name_value_stat_entry);
2598 2596 }
2599 2597
2600 2598 void
2601 2599 dladm_flow_stat_query_all_free(name_value_stat_entry_t *curr)
2602 2600 {
2603 2601 name_value_stat_t *nv_curr = curr->nve_stats;
2604 2602
2605 2603 while (nv_curr != NULL) {
2606 2604 name_value_stat_t *nv_tofree = nv_curr;
2607 2605
2608 2606 nv_curr = nv_curr->nv_nextstat;
2609 2607 free(nv_tofree);
2610 2608 }
2611 2609 }
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX