1 /* 2 * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved. 3 * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved. 4 * Copyright (c) 2009 HNR Consulting. All rights reserved. 5 * Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * OpenIB.org BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * SOFTWARE. 34 * 35 */ 36 37 #if HAVE_CONFIG_H 38 # include <config.h> 39 #endif /* HAVE_CONFIG_H */ 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <unistd.h> 44 #include <getopt.h> 45 #include <netinet/in.h> 46 47 #include <infiniband/umad.h> 48 #include <infiniband/mad.h> 49 #include <infiniband/iba/ib_types.h> 50 51 #include "ibdiag_common.h" 52 53 struct ibmad_port *srcport; 54 55 static ibmad_gid_t dgid; 56 static int with_grh; 57 58 struct perf_count { 59 uint32_t portselect; 60 uint32_t counterselect; 61 uint32_t symbolerrors; 62 uint32_t linkrecovers; 63 uint32_t linkdowned; 64 uint32_t rcverrors; 65 uint32_t rcvremotephyerrors; 66 uint32_t rcvswrelayerrors; 67 uint32_t xmtdiscards; 68 uint32_t xmtconstrainterrors; 69 uint32_t rcvconstrainterrors; 70 uint32_t linkintegrityerrors; 71 uint32_t excbufoverrunerrors; 72 uint32_t qp1dropped; 73 uint32_t vl15dropped; 74 uint32_t xmtdata; 75 uint32_t rcvdata; 76 uint32_t xmtpkts; 77 uint32_t rcvpkts; 78 uint32_t xmtwait; 79 }; 80 81 struct perf_count_ext { 82 uint32_t portselect; 83 uint32_t counterselect; 84 uint64_t portxmitdata; 85 uint64_t portrcvdata; 86 uint64_t portxmitpkts; 87 uint64_t portrcvpkts; 88 uint64_t portunicastxmitpkts; 89 uint64_t portunicastrcvpkts; 90 uint64_t portmulticastxmitpkits; 91 uint64_t portmulticastrcvpkts; 92 93 uint32_t counterSelect2; 94 uint64_t symbolErrorCounter; 95 uint64_t linkErrorRecoveryCounter; 96 uint64_t linkDownedCounter; 97 uint64_t portRcvErrors; 98 uint64_t portRcvRemotePhysicalErrors; 99 uint64_t portRcvSwitchRelayErrors; 100 uint64_t portXmitDiscards; 101 uint64_t portXmitConstraintErrors; 102 uint64_t portRcvConstraintErrors; 103 uint64_t localLinkIntegrityErrors; 104 uint64_t excessiveBufferOverrunErrors; 105 uint64_t VL15Dropped; 106 uint64_t portXmitWait; 107 uint64_t QP1Dropped; 108 }; 109 110 static uint8_t pc[1024]; 111 112 struct perf_count perf_count = {0}; 113 struct perf_count_ext perf_count_ext = {0}; 114 115 #define ALL_PORTS 0xFF 116 #define MAX_PORTS 255 117 118 /* Notes: IB semantics is to cap counters if count has exceeded limits. 119 * Therefore we must check for overflows and cap the counters if necessary. 120 * 121 * mad_decode_field and mad_encode_field assume 32 bit integers passed in 122 * for fields < 32 bits in length. 123 */ 124 125 static void aggregate_4bit(uint32_t * dest, uint32_t val) 126 { 127 if ((((*dest) + val) < (*dest)) || ((*dest) + val) > 0xf) 128 (*dest) = 0xf; 129 else 130 (*dest) = (*dest) + val; 131 } 132 133 static void aggregate_8bit(uint32_t * dest, uint32_t val) 134 { 135 if ((((*dest) + val) < (*dest)) 136 || ((*dest) + val) > 0xff) 137 (*dest) = 0xff; 138 else 139 (*dest) = (*dest) + val; 140 } 141 142 static void aggregate_16bit(uint32_t * dest, uint32_t val) 143 { 144 if ((((*dest) + val) < (*dest)) 145 || ((*dest) + val) > 0xffff) 146 (*dest) = 0xffff; 147 else 148 (*dest) = (*dest) + val; 149 } 150 151 static void aggregate_32bit(uint32_t * dest, uint32_t val) 152 { 153 if (((*dest) + val) < (*dest)) 154 (*dest) = 0xffffffff; 155 else 156 (*dest) = (*dest) + val; 157 } 158 159 static void aggregate_64bit(uint64_t * dest, uint64_t val) 160 { 161 if (((*dest) + val) < (*dest)) 162 (*dest) = 0xffffffffffffffffULL; 163 else 164 (*dest) = (*dest) + val; 165 } 166 167 static void aggregate_perfcounters(void) 168 { 169 uint32_t val; 170 171 mad_decode_field(pc, IB_PC_PORT_SELECT_F, &val); 172 perf_count.portselect = val; 173 mad_decode_field(pc, IB_PC_COUNTER_SELECT_F, &val); 174 perf_count.counterselect = val; 175 mad_decode_field(pc, IB_PC_ERR_SYM_F, &val); 176 aggregate_16bit(&perf_count.symbolerrors, val); 177 mad_decode_field(pc, IB_PC_LINK_RECOVERS_F, &val); 178 aggregate_8bit(&perf_count.linkrecovers, val); 179 mad_decode_field(pc, IB_PC_LINK_DOWNED_F, &val); 180 aggregate_8bit(&perf_count.linkdowned, val); 181 mad_decode_field(pc, IB_PC_ERR_RCV_F, &val); 182 aggregate_16bit(&perf_count.rcverrors, val); 183 mad_decode_field(pc, IB_PC_ERR_PHYSRCV_F, &val); 184 aggregate_16bit(&perf_count.rcvremotephyerrors, val); 185 mad_decode_field(pc, IB_PC_ERR_SWITCH_REL_F, &val); 186 aggregate_16bit(&perf_count.rcvswrelayerrors, val); 187 mad_decode_field(pc, IB_PC_XMT_DISCARDS_F, &val); 188 aggregate_16bit(&perf_count.xmtdiscards, val); 189 mad_decode_field(pc, IB_PC_ERR_XMTCONSTR_F, &val); 190 aggregate_8bit(&perf_count.xmtconstrainterrors, val); 191 mad_decode_field(pc, IB_PC_ERR_RCVCONSTR_F, &val); 192 aggregate_8bit(&perf_count.rcvconstrainterrors, val); 193 mad_decode_field(pc, IB_PC_ERR_LOCALINTEG_F, &val); 194 aggregate_4bit(&perf_count.linkintegrityerrors, val); 195 mad_decode_field(pc, IB_PC_ERR_EXCESS_OVR_F, &val); 196 aggregate_4bit(&perf_count.excbufoverrunerrors, val); 197 #ifdef HAVE_IB_PC_QP1_DROP_F 198 mad_decode_field(pc, IB_PC_QP1_DROP_F, &val); 199 aggregate_16bit(&perf_count.qp1dropped, val); 200 #endif 201 mad_decode_field(pc, IB_PC_VL15_DROPPED_F, &val); 202 aggregate_16bit(&perf_count.vl15dropped, val); 203 mad_decode_field(pc, IB_PC_XMT_BYTES_F, &val); 204 aggregate_32bit(&perf_count.xmtdata, val); 205 mad_decode_field(pc, IB_PC_RCV_BYTES_F, &val); 206 aggregate_32bit(&perf_count.rcvdata, val); 207 mad_decode_field(pc, IB_PC_XMT_PKTS_F, &val); 208 aggregate_32bit(&perf_count.xmtpkts, val); 209 mad_decode_field(pc, IB_PC_RCV_PKTS_F, &val); 210 aggregate_32bit(&perf_count.rcvpkts, val); 211 mad_decode_field(pc, IB_PC_XMT_WAIT_F, &val); 212 aggregate_32bit(&perf_count.xmtwait, val); 213 } 214 215 static void output_aggregate_perfcounters(ib_portid_t * portid, 216 uint16_t cap_mask) 217 { 218 char buf[1024]; 219 uint32_t val = ALL_PORTS; 220 221 /* set port_select to 255 to emulate AllPortSelect */ 222 mad_encode_field(pc, IB_PC_PORT_SELECT_F, &val); 223 mad_encode_field(pc, IB_PC_COUNTER_SELECT_F, &perf_count.counterselect); 224 mad_encode_field(pc, IB_PC_ERR_SYM_F, &perf_count.symbolerrors); 225 mad_encode_field(pc, IB_PC_LINK_RECOVERS_F, &perf_count.linkrecovers); 226 mad_encode_field(pc, IB_PC_LINK_DOWNED_F, &perf_count.linkdowned); 227 mad_encode_field(pc, IB_PC_ERR_RCV_F, &perf_count.rcverrors); 228 mad_encode_field(pc, IB_PC_ERR_PHYSRCV_F, 229 &perf_count.rcvremotephyerrors); 230 mad_encode_field(pc, IB_PC_ERR_SWITCH_REL_F, 231 &perf_count.rcvswrelayerrors); 232 mad_encode_field(pc, IB_PC_XMT_DISCARDS_F, &perf_count.xmtdiscards); 233 mad_encode_field(pc, IB_PC_ERR_XMTCONSTR_F, 234 &perf_count.xmtconstrainterrors); 235 mad_encode_field(pc, IB_PC_ERR_RCVCONSTR_F, 236 &perf_count.rcvconstrainterrors); 237 mad_encode_field(pc, IB_PC_ERR_LOCALINTEG_F, 238 &perf_count.linkintegrityerrors); 239 mad_encode_field(pc, IB_PC_ERR_EXCESS_OVR_F, 240 &perf_count.excbufoverrunerrors); 241 #ifdef HAVE_IB_PC_QP1_DROP_F 242 mad_encode_field(pc, IB_PC_QP1_DROP_F, &perf_count.qp1dropped); 243 #endif 244 mad_encode_field(pc, IB_PC_VL15_DROPPED_F, &perf_count.vl15dropped); 245 mad_encode_field(pc, IB_PC_XMT_BYTES_F, &perf_count.xmtdata); 246 mad_encode_field(pc, IB_PC_RCV_BYTES_F, &perf_count.rcvdata); 247 mad_encode_field(pc, IB_PC_XMT_PKTS_F, &perf_count.xmtpkts); 248 mad_encode_field(pc, IB_PC_RCV_PKTS_F, &perf_count.rcvpkts); 249 mad_encode_field(pc, IB_PC_XMT_WAIT_F, &perf_count.xmtwait); 250 251 mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc); 252 253 printf("# Port counters: %s port %d (CapMask: 0x%02X)\n%s", 254 portid2str(portid), ALL_PORTS, ntohs(cap_mask), buf); 255 } 256 257 static void aggregate_perfcounters_ext(uint16_t cap_mask, uint32_t cap_mask2) 258 { 259 uint32_t val; 260 uint64_t val64; 261 262 mad_decode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val); 263 perf_count_ext.portselect = val; 264 mad_decode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, &val); 265 perf_count_ext.counterselect = val; 266 mad_decode_field(pc, IB_PC_EXT_XMT_BYTES_F, &val64); 267 aggregate_64bit(&perf_count_ext.portxmitdata, val64); 268 mad_decode_field(pc, IB_PC_EXT_RCV_BYTES_F, &val64); 269 aggregate_64bit(&perf_count_ext.portrcvdata, val64); 270 mad_decode_field(pc, IB_PC_EXT_XMT_PKTS_F, &val64); 271 aggregate_64bit(&perf_count_ext.portxmitpkts, val64); 272 mad_decode_field(pc, IB_PC_EXT_RCV_PKTS_F, &val64); 273 aggregate_64bit(&perf_count_ext.portrcvpkts, val64); 274 275 if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) { 276 mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64); 277 aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64); 278 mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64); 279 aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64); 280 mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64); 281 aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64); 282 mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64); 283 aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64); 284 } 285 286 if (htonl(cap_mask2) & IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP) { 287 mad_decode_field(pc, IB_PC_EXT_COUNTER_SELECT2_F, &val); 288 perf_count_ext.counterSelect2 = val; 289 mad_decode_field(pc, IB_PC_EXT_ERR_SYM_F, &val64); 290 aggregate_64bit(&perf_count_ext.symbolErrorCounter, val64); 291 mad_decode_field(pc, IB_PC_EXT_LINK_RECOVERS_F, &val64); 292 aggregate_64bit(&perf_count_ext.linkErrorRecoveryCounter, val64); 293 mad_decode_field(pc, IB_PC_EXT_LINK_DOWNED_F, &val64); 294 aggregate_64bit(&perf_count_ext.linkDownedCounter, val64); 295 mad_decode_field(pc, IB_PC_EXT_ERR_RCV_F, &val64); 296 aggregate_64bit(&perf_count_ext.portRcvErrors, val64); 297 mad_decode_field(pc, IB_PC_EXT_ERR_PHYSRCV_F, &val64); 298 aggregate_64bit(&perf_count_ext.portRcvRemotePhysicalErrors, val64); 299 mad_decode_field(pc, IB_PC_EXT_ERR_SWITCH_REL_F, &val64); 300 aggregate_64bit(&perf_count_ext.portRcvSwitchRelayErrors, val64); 301 mad_decode_field(pc, IB_PC_EXT_XMT_DISCARDS_F, &val64); 302 aggregate_64bit(&perf_count_ext.portXmitDiscards, val64); 303 mad_decode_field(pc, IB_PC_EXT_ERR_XMTCONSTR_F, &val64); 304 aggregate_64bit(&perf_count_ext.portXmitConstraintErrors, val64); 305 mad_decode_field(pc, IB_PC_EXT_ERR_RCVCONSTR_F, &val64); 306 aggregate_64bit(&perf_count_ext.portRcvConstraintErrors, val64); 307 mad_decode_field(pc, IB_PC_EXT_ERR_LOCALINTEG_F, &val64); 308 aggregate_64bit(&perf_count_ext.localLinkIntegrityErrors, val64); 309 mad_decode_field(pc, IB_PC_EXT_ERR_EXCESS_OVR_F, &val64); 310 aggregate_64bit(&perf_count_ext.excessiveBufferOverrunErrors, val64); 311 mad_decode_field(pc, IB_PC_EXT_VL15_DROPPED_F, &val64); 312 aggregate_64bit(&perf_count_ext.VL15Dropped, val64); 313 mad_decode_field(pc, IB_PC_EXT_XMT_WAIT_F, &val64); 314 aggregate_64bit(&perf_count_ext.portXmitWait, val64); 315 mad_decode_field(pc, IB_PC_EXT_QP1_DROP_F, &val64); 316 aggregate_64bit(&perf_count_ext.QP1Dropped, val64); 317 } 318 } 319 320 static void output_aggregate_perfcounters_ext(ib_portid_t * portid, 321 uint16_t cap_mask, uint32_t cap_mask2) 322 { 323 char buf[1536]; 324 uint32_t val = ALL_PORTS; 325 326 memset(buf, 0, sizeof(buf)); 327 328 /* set port_select to 255 to emulate AllPortSelect */ 329 mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val); 330 mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F, 331 &perf_count_ext.counterselect); 332 mad_encode_field(pc, IB_PC_EXT_XMT_BYTES_F, 333 &perf_count_ext.portxmitdata); 334 mad_encode_field(pc, IB_PC_EXT_RCV_BYTES_F, 335 &perf_count_ext.portrcvdata); 336 mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F, 337 &perf_count_ext.portxmitpkts); 338 mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts); 339 340 if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) { 341 mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F, 342 &perf_count_ext.portunicastxmitpkts); 343 mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F, 344 &perf_count_ext.portunicastrcvpkts); 345 mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F, 346 &perf_count_ext.portmulticastxmitpkits); 347 mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F, 348 &perf_count_ext.portmulticastrcvpkts); 349 } 350 351 if (htonl(cap_mask2) & IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP) { 352 mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT2_F, 353 &perf_count_ext.counterSelect2); 354 mad_encode_field(pc, IB_PC_EXT_ERR_SYM_F, 355 &perf_count_ext.symbolErrorCounter); 356 mad_encode_field(pc, IB_PC_EXT_LINK_RECOVERS_F, 357 &perf_count_ext.linkErrorRecoveryCounter); 358 mad_encode_field(pc, IB_PC_EXT_LINK_DOWNED_F, 359 &perf_count_ext.linkDownedCounter); 360 mad_encode_field(pc, IB_PC_EXT_ERR_RCV_F, 361 &perf_count_ext.portRcvErrors); 362 mad_encode_field(pc, IB_PC_EXT_ERR_PHYSRCV_F, 363 &perf_count_ext.portRcvRemotePhysicalErrors); 364 mad_encode_field(pc, IB_PC_EXT_ERR_SWITCH_REL_F, 365 &perf_count_ext.portRcvSwitchRelayErrors); 366 mad_encode_field(pc, IB_PC_EXT_XMT_DISCARDS_F, 367 &perf_count_ext.portXmitDiscards); 368 mad_encode_field(pc, IB_PC_EXT_ERR_XMTCONSTR_F, 369 &perf_count_ext.portXmitConstraintErrors); 370 mad_encode_field(pc, IB_PC_EXT_ERR_RCVCONSTR_F, 371 &perf_count_ext.portRcvConstraintErrors); 372 mad_encode_field(pc, IB_PC_EXT_ERR_LOCALINTEG_F, 373 &perf_count_ext.localLinkIntegrityErrors); 374 mad_encode_field(pc, IB_PC_EXT_ERR_EXCESS_OVR_F, 375 &perf_count_ext.excessiveBufferOverrunErrors); 376 mad_encode_field(pc, IB_PC_EXT_VL15_DROPPED_F, 377 &perf_count_ext.VL15Dropped); 378 mad_encode_field(pc, IB_PC_EXT_XMT_WAIT_F, 379 &perf_count_ext.portXmitWait); 380 mad_encode_field(pc, IB_PC_EXT_QP1_DROP_F, 381 &perf_count_ext.QP1Dropped); 382 } 383 384 mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc); 385 386 printf("# Port extended counters: %s port %d (CapMask: 0x%02X CapMask2: 0x%07X)\n%s", 387 portid2str(portid), ALL_PORTS, ntohs(cap_mask), cap_mask2, buf); 388 } 389 390 static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask, 391 uint32_t cap_mask2, ib_portid_t * portid, 392 int port, int aggregate) 393 { 394 char buf[1536]; 395 396 if (extended != 1) { 397 memset(pc, 0, sizeof(pc)); 398 if (!pma_query_via(pc, portid, port, timeout, 399 IB_GSI_PORT_COUNTERS, srcport)) 400 IBEXIT("perfquery"); 401 if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) { 402 /* if PortCounters:PortXmitWait not supported clear this counter */ 403 VERBOSE("PortXmitWait not indicated" 404 " so ignore this counter"); 405 perf_count.xmtwait = 0; 406 mad_encode_field(pc, IB_PC_XMT_WAIT_F, 407 &perf_count.xmtwait); 408 } 409 if (aggregate) 410 aggregate_perfcounters(); 411 else { 412 #ifdef HAVE_IB_PC_QP1_DROP_F 413 mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc); 414 #else 415 mad_dump_fields(buf, sizeof buf, pc, sizeof pc, 416 IB_PC_FIRST_F, 417 (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)?IB_PC_LAST_F:(IB_PC_RCV_PKTS_F+1)); 418 #endif 419 } 420 } else { 421 /* 1.2 errata: bit 9 is extended counter support 422 * bit 10 is extended counter NoIETF 423 */ 424 if (!(cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) && 425 !(cap_mask & IB_PM_EXT_WIDTH_NOIETF_SUP)) 426 IBWARN 427 ("PerfMgt ClassPortInfo CapMask 0x%02X; No extended counter support indicated\n", 428 ntohs(cap_mask)); 429 430 memset(pc, 0, sizeof(pc)); 431 if (!pma_query_via(pc, portid, port, timeout, 432 IB_GSI_PORT_COUNTERS_EXT, srcport)) 433 IBEXIT("perfextquery"); 434 if (aggregate) 435 aggregate_perfcounters_ext(cap_mask, cap_mask2); 436 else 437 mad_dump_perfcounters_ext(buf, sizeof buf, pc, 438 sizeof pc); 439 } 440 441 if (!aggregate) { 442 if (extended) 443 printf("# Port extended counters: %s port %d " 444 "(CapMask: 0x%02X CapMask2: 0x%07X)\n%s", 445 portid2str(portid), port, ntohs(cap_mask), 446 cap_mask2, buf); 447 else 448 printf("# Port counters: %s port %d " 449 "(CapMask: 0x%02X)\n%s", 450 portid2str(portid), port, ntohs(cap_mask), buf); 451 } 452 } 453 454 static void reset_counters(int extended, int timeout, int mask, 455 ib_portid_t * portid, int port) 456 { 457 memset(pc, 0, sizeof(pc)); 458 if (extended != 1) { 459 if (!performance_reset_via(pc, portid, port, mask, timeout, 460 IB_GSI_PORT_COUNTERS, srcport)) 461 IBEXIT("perf reset"); 462 } else { 463 if (!performance_reset_via(pc, portid, port, mask, timeout, 464 IB_GSI_PORT_COUNTERS_EXT, srcport)) 465 IBEXIT("perf ext reset"); 466 } 467 } 468 469 static int reset, reset_only, all_ports, loop_ports, port, extended, xmt_sl, 470 rcv_sl, xmt_disc, rcv_err, extended_speeds, smpl_ctl, oprcvcounters, flowctlcounters, 471 vloppackets, vlopdata, vlxmitflowctlerrors, vlxmitcounters, swportvlcong, 472 rcvcc, slrcvfecn, slrcvbecn, xmitcc, vlxmittimecc; 473 static int ports[MAX_PORTS]; 474 static int ports_count; 475 476 static void common_func(ib_portid_t * portid, int port_num, int mask, 477 unsigned query, unsigned reset, 478 const char *name, uint16_t attr, 479 void dump_func(char *, int, void *, int)) 480 { 481 char buf[1536]; 482 483 if (query) { 484 memset(pc, 0, sizeof(pc)); 485 if (!pma_query_via(pc, portid, port_num, ibd_timeout, attr, 486 srcport)) 487 IBEXIT("cannot query %s", name); 488 489 dump_func(buf, sizeof(buf), pc, sizeof(pc)); 490 491 printf("# %s counters: %s port %d\n%s", name, 492 portid2str(portid), port_num, buf); 493 } 494 495 memset(pc, 0, sizeof(pc)); 496 if (reset && !performance_reset_via(pc, portid, port, mask, ibd_timeout, 497 attr, srcport)) 498 IBEXIT("cannot reset %s", name); 499 } 500 501 static void xmt_sl_query(ib_portid_t * portid, int port, int mask) 502 { 503 common_func(portid, port, mask, !reset_only, (reset_only || reset), 504 "PortXmitDataSL", IB_GSI_PORT_XMIT_DATA_SL, 505 mad_dump_perfcounters_xmt_sl); 506 } 507 508 static void rcv_sl_query(ib_portid_t * portid, int port, int mask) 509 { 510 common_func(portid, port, mask, !reset_only, (reset_only || reset), 511 "PortRcvDataSL", IB_GSI_PORT_RCV_DATA_SL, 512 mad_dump_perfcounters_rcv_sl); 513 } 514 515 static void xmt_disc_query(ib_portid_t * portid, int port, int mask) 516 { 517 common_func(portid, port, mask, !reset_only, (reset_only || reset), 518 "PortXmitDiscardDetails", IB_GSI_PORT_XMIT_DISCARD_DETAILS, 519 mad_dump_perfcounters_xmt_disc); 520 } 521 522 static void rcv_err_query(ib_portid_t * portid, int port, int mask) 523 { 524 common_func(portid, port, mask, !reset_only, (reset_only || reset), 525 "PortRcvErrorDetails", IB_GSI_PORT_RCV_ERROR_DETAILS, 526 mad_dump_perfcounters_rcv_err); 527 } 528 529 static uint8_t *ext_speeds_reset_via(void *rcvbuf, ib_portid_t * dest, 530 int port, uint64_t mask, unsigned timeout, 531 const struct ibmad_port * srcport) 532 { 533 ib_rpc_t rpc = { 0 }; 534 int lid = dest->lid; 535 536 DEBUG("lid %u port %d mask 0x%" PRIx64, lid, port, mask); 537 538 if (lid == -1) { 539 IBWARN("only lid routed is supported"); 540 return NULL; 541 } 542 543 if (!mask) 544 mask = ~0; 545 546 rpc.mgtclass = IB_PERFORMANCE_CLASS; 547 rpc.method = IB_MAD_METHOD_SET; 548 rpc.attr.id = IB_GSI_PORT_EXT_SPEEDS_COUNTERS; 549 550 memset(rcvbuf, 0, IB_MAD_SIZE); 551 552 mad_set_field(rcvbuf, 0, IB_PESC_PORT_SELECT_F, port); 553 mad_set_field64(rcvbuf, 0, IB_PESC_COUNTER_SELECT_F, mask); 554 rpc.attr.mod = 0; 555 rpc.timeout = timeout; 556 rpc.datasz = IB_PC_DATA_SZ; 557 rpc.dataoffs = IB_PC_DATA_OFFS; 558 if (!dest->qp) 559 dest->qp = 1; 560 if (!dest->qkey) 561 dest->qkey = IB_DEFAULT_QP1_QKEY; 562 563 return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf); 564 } 565 566 static uint8_t is_rsfec_mode_active(ib_portid_t * portid, int port, 567 uint16_t cap_mask) 568 { 569 uint8_t data[IB_SMP_DATA_SIZE] = { 0 }; 570 uint32_t fec_mode_active = 0; 571 uint32_t pie_capmask = 0; 572 if (cap_mask & IS_PM_RSFEC_COUNTERS_SUP) { 573 if (!is_port_info_extended_supported(portid, port, srcport)) { 574 IBWARN("Port Info Extended not supported"); 575 return 0; 576 } 577 578 if (!smp_query_via(data, portid, IB_ATTR_PORT_INFO_EXT, port, 0, 579 srcport)) 580 IBEXIT("smp query portinfo extended failed"); 581 582 mad_decode_field(data, IB_PORT_EXT_CAPMASK_F, &pie_capmask); 583 mad_decode_field(data, IB_PORT_EXT_FEC_MODE_ACTIVE_F, 584 &fec_mode_active); 585 if((pie_capmask & 586 CL_NTOH32(IB_PORT_EXT_CAP_IS_FEC_MODE_SUPPORTED)) && 587 (CL_NTOH16(IB_PORT_EXT_RS_FEC_MODE_ACTIVE) == (fec_mode_active & 0xffff))) 588 return 1; 589 } 590 591 return 0; 592 } 593 594 static void extended_speeds_query(ib_portid_t * portid, int port, 595 uint64_t ext_mask, uint16_t cap_mask) 596 { 597 int mask = ext_mask; 598 599 if (!reset_only) { 600 if (is_rsfec_mode_active(portid, port, cap_mask)) 601 common_func(portid, port, mask, 1, 0, 602 "PortExtendedSpeedsCounters with RS-FEC Active", 603 IB_GSI_PORT_EXT_SPEEDS_COUNTERS, 604 mad_dump_port_ext_speeds_counters_rsfec_active); 605 else 606 common_func(portid, port, mask, 1, 0, 607 "PortExtendedSpeedsCounters", 608 IB_GSI_PORT_EXT_SPEEDS_COUNTERS, 609 mad_dump_port_ext_speeds_counters); 610 } 611 612 if ((reset_only || reset) && 613 !ext_speeds_reset_via(pc, portid, port, ext_mask, ibd_timeout, srcport)) 614 IBEXIT("cannot reset PortExtendedSpeedsCounters"); 615 } 616 617 static void oprcvcounters_query(ib_portid_t * portid, int port, int mask) 618 { 619 common_func(portid, port, mask, !reset_only, (reset_only || reset), 620 "PortOpRcvCounters", IB_GSI_PORT_PORT_OP_RCV_COUNTERS, 621 mad_dump_perfcounters_port_op_rcv_counters); 622 } 623 624 static void flowctlcounters_query(ib_portid_t * portid, int port, int mask) 625 { 626 common_func(portid, port, mask, !reset_only, (reset_only || reset), 627 "PortFlowCtlCounters", IB_GSI_PORT_PORT_FLOW_CTL_COUNTERS, 628 mad_dump_perfcounters_port_flow_ctl_counters); 629 } 630 631 static void vloppackets_query(ib_portid_t * portid, int port, int mask) 632 { 633 common_func(portid, port, mask, !reset_only, (reset_only || reset), 634 "PortVLOpPackets", IB_GSI_PORT_PORT_VL_OP_PACKETS, 635 mad_dump_perfcounters_port_vl_op_packet); 636 } 637 638 static void vlopdata_query(ib_portid_t * portid, int port, int mask) 639 { 640 common_func(portid, port, mask, !reset_only, (reset_only || reset), 641 "PortVLOpData", IB_GSI_PORT_PORT_VL_OP_DATA, 642 mad_dump_perfcounters_port_vl_op_data); 643 } 644 645 static void vlxmitflowctlerrors_query(ib_portid_t * portid, int port, int mask) 646 { 647 common_func(portid, port, mask, !reset_only, (reset_only || reset), 648 "PortVLXmitFlowCtlUpdateErrors", IB_GSI_PORT_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS, 649 mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors); 650 } 651 652 static void vlxmitcounters_query(ib_portid_t * portid, int port, int mask) 653 { 654 common_func(portid, port, mask, !reset_only, (reset_only || reset), 655 "PortVLXmitWaitCounters", IB_GSI_PORT_PORT_VL_XMIT_WAIT_COUNTERS, 656 mad_dump_perfcounters_port_vl_xmit_wait_counters); 657 } 658 659 static void swportvlcong_query(ib_portid_t * portid, int port, int mask) 660 { 661 common_func(portid, port, mask, !reset_only, (reset_only || reset), 662 "SwPortVLCongestion", IB_GSI_SW_PORT_VL_CONGESTION, 663 mad_dump_perfcounters_sw_port_vl_congestion); 664 } 665 666 static void rcvcc_query(ib_portid_t * portid, int port, int mask) 667 { 668 common_func(portid, port, mask, !reset_only, (reset_only || reset), 669 "PortRcvConCtrl", IB_GSI_PORT_RCV_CON_CTRL, 670 mad_dump_perfcounters_rcv_con_ctrl); 671 } 672 673 static void slrcvfecn_query(ib_portid_t * portid, int port, int mask) 674 { 675 common_func(portid, port, mask, !reset_only, (reset_only || reset), 676 "PortSLRcvFECN", IB_GSI_PORT_SL_RCV_FECN, 677 mad_dump_perfcounters_sl_rcv_fecn); 678 } 679 680 static void slrcvbecn_query(ib_portid_t * portid, int port, int mask) 681 { 682 common_func(portid, port, mask, !reset_only, (reset_only || reset), 683 "PortSLRcvBECN", IB_GSI_PORT_SL_RCV_BECN, 684 mad_dump_perfcounters_sl_rcv_becn); 685 } 686 687 static void xmitcc_query(ib_portid_t * portid, int port, int mask) 688 { 689 common_func(portid, port, mask, !reset_only, (reset_only || reset), 690 "PortXmitConCtrl", IB_GSI_PORT_XMIT_CON_CTRL, 691 mad_dump_perfcounters_xmit_con_ctrl); 692 } 693 694 static void vlxmittimecc_query(ib_portid_t * portid, int port, int mask) 695 { 696 common_func(portid, port, mask, !reset_only, (reset_only || reset), 697 "PortVLXmitTimeCong", IB_GSI_PORT_VL_XMIT_TIME_CONG, 698 mad_dump_perfcounters_vl_xmit_time_cong); 699 } 700 701 void dump_portsamples_control(ib_portid_t * portid, int port) 702 { 703 char buf[1280]; 704 705 memset(pc, 0, sizeof(pc)); 706 if (!pma_query_via(pc, portid, port, ibd_timeout, 707 IB_GSI_PORT_SAMPLES_CONTROL, srcport)) 708 IBEXIT("sampctlquery"); 709 710 mad_dump_portsamples_control(buf, sizeof buf, pc, sizeof pc); 711 printf("# PortSamplesControl: %s port %d\n%s", portid2str(portid), 712 port, buf); 713 } 714 715 static int process_opt(void *context, int ch, char *optarg) 716 { 717 switch (ch) { 718 case 'x': 719 extended = 1; 720 break; 721 case 'X': 722 xmt_sl = 1; 723 break; 724 case 'S': 725 rcv_sl = 1; 726 break; 727 case 'D': 728 xmt_disc = 1; 729 break; 730 case 'E': 731 rcv_err = 1; 732 break; 733 case 'T': 734 extended_speeds = 1; 735 break; 736 case 'c': 737 smpl_ctl = 1; 738 break; 739 case 1: 740 oprcvcounters = 1; 741 break; 742 case 2: 743 flowctlcounters = 1; 744 break; 745 case 3: 746 vloppackets = 1; 747 break; 748 case 4: 749 vlopdata = 1; 750 break; 751 case 5: 752 vlxmitflowctlerrors = 1; 753 break; 754 case 6: 755 vlxmitcounters = 1; 756 break; 757 case 7: 758 swportvlcong = 1; 759 break; 760 case 8: 761 rcvcc = 1; 762 break; 763 case 9: 764 slrcvfecn = 1; 765 break; 766 case 10: 767 slrcvbecn = 1; 768 break; 769 case 11: 770 xmitcc = 1; 771 break; 772 case 12: 773 vlxmittimecc = 1; 774 break; 775 case 'a': 776 all_ports++; 777 port = ALL_PORTS; 778 break; 779 case 'l': 780 loop_ports++; 781 break; 782 case 'r': 783 reset++; 784 break; 785 case 'R': 786 reset_only++; 787 break; 788 case 25: 789 if (!inet_pton(AF_INET6, optarg, &dgid)) { 790 fprintf(stderr, "dgid format is wrong!\n"); 791 ibdiag_show_usage(); 792 return 1; 793 } 794 with_grh = 1; 795 break; 796 default: 797 return -1; 798 } 799 return 0; 800 } 801 802 int main(int argc, char **argv) 803 { 804 int mgmt_classes[3] = { IB_SMI_CLASS, IB_SA_CLASS, IB_PERFORMANCE_CLASS }; 805 ib_portid_t portid = { 0 }; 806 int mask = 0xffff; 807 uint64_t ext_mask = 0xffffffffffffffffULL; 808 uint32_t cap_mask2; 809 uint16_t cap_mask; 810 int all_ports_loop = 0; 811 int node_type, num_ports = 0; 812 uint8_t data[IB_SMP_DATA_SIZE] = { 0 }; 813 int start_port = 1; 814 int enhancedport0; 815 char *tmpstr; 816 int i; 817 818 const struct ibdiag_opt opts[] = { 819 {"extended", 'x', 0, NULL, "show extended port counters"}, 820 {"xmtsl", 'X', 0, NULL, "show Xmt SL port counters"}, 821 {"rcvsl", 'S', 0, NULL, "show Rcv SL port counters"}, 822 {"xmtdisc", 'D', 0, NULL, "show Xmt Discard Details"}, 823 {"rcverr", 'E', 0, NULL, "show Rcv Error Details"}, 824 {"extended_speeds", 'T', 0, NULL, "show port extended speeds counters"}, 825 {"oprcvcounters", 1, 0, NULL, "show Rcv Counters per Op code"}, 826 {"flowctlcounters", 2, 0, NULL, "show flow control counters"}, 827 {"vloppackets", 3, 0, NULL, "show packets received per Op code per VL"}, 828 {"vlopdata", 4, 0, NULL, "show data received per Op code per VL"}, 829 {"vlxmitflowctlerrors", 5, 0, NULL, "show flow control update errors per VL"}, 830 {"vlxmitcounters", 6, 0, NULL, "show ticks waiting to transmit counters per VL"}, 831 {"swportvlcong", 7, 0, NULL, "show sw port VL congestion"}, 832 {"rcvcc", 8, 0, NULL, "show Rcv congestion control counters"}, 833 {"slrcvfecn", 9, 0, NULL, "show SL Rcv FECN counters"}, 834 {"slrcvbecn", 10, 0, NULL, "show SL Rcv BECN counters"}, 835 {"xmitcc", 11, 0, NULL, "show Xmit congestion control counters"}, 836 {"vlxmittimecc", 12, 0, NULL, "show VL Xmit Time congestion control counters"}, 837 {"smplctl", 'c', 0, NULL, "show samples control"}, 838 {"all_ports", 'a', 0, NULL, "show aggregated counters"}, 839 {"loop_ports", 'l', 0, NULL, "iterate through each port"}, 840 {"reset_after_read", 'r', 0, NULL, "reset counters after read"}, 841 {"Reset_only", 'R', 0, NULL, "only reset counters"}, 842 {"dgid", 25, 1, NULL, "remote gid (IPv6 format)"}, 843 {0} 844 }; 845 char usage_args[] = " [<lid|guid> [[port(s)] [reset_mask]]]"; 846 const char *usage_examples[] = { 847 "\t\t# read local port's performance counters", 848 "32 1\t\t# read performance counters from lid 32, port 1", 849 "-x 32 1\t# read extended performance counters from lid 32, port 1", 850 "-a 32\t\t# read performance counters from lid 32, all ports", 851 "-r 32 1\t# read performance counters and reset", 852 "-x -r 32 1\t# read extended performance counters and reset", 853 "-R 0x20 1\t# reset performance counters of port 1 only", 854 "-x -R 0x20 1\t# reset extended performance counters of port 1 only", 855 "-R -a 32\t# reset performance counters of all ports", 856 "-R 32 2 0x0fff\t# reset only error counters of port 2", 857 "-R 32 2 0xf000\t# reset only non-error counters of port 2", 858 "-a 32 1-10\t# read performance counters from lid 32, port 1-10, aggregate output", 859 "-l 32 1-10\t# read performance counters from lid 32, port 1-10, output each port", 860 "-a 32 1,4,8\t# read performance counters from lid 32, port 1, 4, and 8, aggregate output", 861 "-l 32 1,4,8\t# read performance counters from lid 32, port 1, 4, and 8, output each port", 862 NULL, 863 }; 864 865 ibdiag_process_opts(argc, argv, NULL, "DK", opts, process_opt, 866 usage_args, usage_examples); 867 868 argc -= optind; 869 argv += optind; 870 871 if (argc > 1) { 872 if (strchr(argv[1], ',')) { 873 tmpstr = strtok(argv[1], ","); 874 while (tmpstr) { 875 ports[ports_count++] = strtoul(tmpstr, 0, 0); 876 tmpstr = strtok(NULL, ","); 877 } 878 port = ports[0]; 879 } 880 else if ((tmpstr = strchr(argv[1], '-'))) { 881 int pmin, pmax; 882 883 *tmpstr = '\0'; 884 tmpstr++; 885 886 pmin = strtoul(argv[1], 0, 0); 887 pmax = strtoul(tmpstr, 0, 0); 888 889 if (pmin >= pmax) 890 IBEXIT("max port must be greater than min port in range"); 891 892 while (pmin <= pmax) 893 ports[ports_count++] = pmin++; 894 895 port = ports[0]; 896 } 897 else 898 port = strtoul(argv[1], 0, 0); 899 } 900 if (argc > 2) { 901 ext_mask = strtoull(argv[2], 0, 0); 902 mask = ext_mask; 903 } 904 905 srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3); 906 if (!srcport) 907 IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port); 908 909 smp_mkey_set(srcport, ibd_mkey); 910 911 if (argc) { 912 if (with_grh && ibd_dest_type != IB_DEST_LID) 913 IBEXIT("When using GRH, LID should be provided"); 914 if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0], 915 ibd_dest_type, ibd_sm_id, srcport) < 0) 916 IBEXIT("can't resolve destination port %s", argv[0]); 917 if (with_grh) { 918 portid.grh_present = 1; 919 memcpy(&portid.gid, &dgid, sizeof(portid.gid)); 920 } 921 } else { 922 if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, 0) < 0) 923 IBEXIT("can't resolve self port %s", argv[0]); 924 } 925 926 /* PerfMgt ClassPortInfo is a required attribute */ 927 memset(pc, 0, sizeof(pc)); 928 if (!pma_query_via(pc, &portid, port, ibd_timeout, CLASS_PORT_INFO, 929 srcport)) 930 IBEXIT("classportinfo query"); 931 /* ClassPortInfo should be supported as part of libibmad */ 932 memcpy(&cap_mask, pc + 2, sizeof(cap_mask)); /* CapabilityMask */ 933 memcpy(&cap_mask2, pc + 4, sizeof(cap_mask2)); /* CapabilityMask2 */ 934 cap_mask2 = ntohl(cap_mask2) >> 5; 935 936 if (!(cap_mask & IB_PM_ALL_PORT_SELECT)) { /* bit 8 is AllPortSelect */ 937 if (!all_ports && port == ALL_PORTS) 938 IBEXIT("AllPortSelect not supported"); 939 if (all_ports && port == ALL_PORTS) 940 all_ports_loop = 1; 941 } 942 943 if (xmt_sl) { 944 xmt_sl_query(&portid, port, mask); 945 goto done; 946 } 947 948 if (rcv_sl) { 949 rcv_sl_query(&portid, port, mask); 950 goto done; 951 } 952 953 if (xmt_disc) { 954 xmt_disc_query(&portid, port, mask); 955 goto done; 956 } 957 958 if (rcv_err) { 959 rcv_err_query(&portid, port, mask); 960 goto done; 961 } 962 963 if (extended_speeds) { 964 extended_speeds_query(&portid, port, ext_mask, cap_mask); 965 goto done; 966 } 967 968 if (oprcvcounters) { 969 oprcvcounters_query(&portid, port, mask); 970 goto done; 971 } 972 973 if (flowctlcounters) { 974 flowctlcounters_query(&portid, port, mask); 975 goto done; 976 } 977 978 if (vloppackets) { 979 vloppackets_query(&portid, port, mask); 980 goto done; 981 } 982 983 if (vlopdata) { 984 vlopdata_query(&portid, port, mask); 985 goto done; 986 } 987 988 if (vlxmitflowctlerrors) { 989 vlxmitflowctlerrors_query(&portid, port, mask); 990 goto done; 991 } 992 993 if (vlxmitcounters) { 994 vlxmitcounters_query(&portid, port, mask); 995 goto done; 996 } 997 998 if (swportvlcong) { 999 swportvlcong_query(&portid, port, mask); 1000 goto done; 1001 } 1002 1003 if (rcvcc) { 1004 rcvcc_query(&portid, port, mask); 1005 goto done; 1006 } 1007 1008 if (slrcvfecn) { 1009 slrcvfecn_query(&portid, port, mask); 1010 goto done; 1011 } 1012 1013 if (slrcvbecn) { 1014 slrcvbecn_query(&portid, port, mask); 1015 goto done; 1016 } 1017 1018 if (xmitcc) { 1019 xmitcc_query(&portid, port, mask); 1020 goto done; 1021 } 1022 1023 if (vlxmittimecc) { 1024 vlxmittimecc_query(&portid, port, mask); 1025 goto done; 1026 } 1027 1028 if (smpl_ctl) { 1029 dump_portsamples_control(&portid, port); 1030 goto done; 1031 } 1032 1033 1034 if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) { 1035 if (!smp_query_via(data, &portid, IB_ATTR_NODE_INFO, 0, 0, 1036 srcport)) 1037 IBEXIT("smp query nodeinfo failed"); 1038 node_type = mad_get_field(data, 0, IB_NODE_TYPE_F); 1039 mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports); 1040 if (!num_ports) 1041 IBEXIT("smp query nodeinfo: num ports invalid"); 1042 1043 if (node_type == IB_NODE_SWITCH) { 1044 if (!smp_query_via(data, &portid, IB_ATTR_SWITCH_INFO, 1045 0, 0, srcport)) 1046 IBEXIT("smp query nodeinfo failed"); 1047 enhancedport0 = 1048 mad_get_field(data, 0, IB_SW_ENHANCED_PORT0_F); 1049 if (enhancedport0) 1050 start_port = 0; 1051 } 1052 if (all_ports_loop && !loop_ports) 1053 IBWARN 1054 ("Emulating AllPortSelect by iterating through all ports"); 1055 } 1056 1057 if (reset_only) 1058 goto do_reset; 1059 1060 if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) { 1061 for (i = start_port; i <= num_ports; i++) 1062 dump_perfcounters(extended, ibd_timeout, 1063 cap_mask, cap_mask2, 1064 &portid, i, (all_ports_loop 1065 && !loop_ports)); 1066 if (all_ports_loop && !loop_ports) { 1067 if (extended != 1) 1068 output_aggregate_perfcounters(&portid, 1069 cap_mask); 1070 else 1071 output_aggregate_perfcounters_ext(&portid, 1072 cap_mask, cap_mask2); 1073 } 1074 } else if (ports_count > 1) { 1075 for (i = 0; i < ports_count; i++) 1076 dump_perfcounters(extended, ibd_timeout, cap_mask, 1077 cap_mask2, &portid, ports[i], 1078 (all_ports && !loop_ports)); 1079 if (all_ports && !loop_ports) { 1080 if (extended != 1) 1081 output_aggregate_perfcounters(&portid, 1082 cap_mask); 1083 else 1084 output_aggregate_perfcounters_ext(&portid, 1085 cap_mask, cap_mask2); 1086 } 1087 } else 1088 dump_perfcounters(extended, ibd_timeout, cap_mask, cap_mask2, 1089 &portid, port, 0); 1090 1091 if (!reset) 1092 goto done; 1093 1094 do_reset: 1095 if (argc <= 2 && !extended) { 1096 if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP) 1097 mask |= (1 << 16); /* reset portxmitwait */ 1098 if (cap_mask & IB_PM_IS_QP1_DROP_SUP) 1099 mask |= (1 << 17); /* reset qp1dropped */ 1100 } 1101 1102 if (extended) { 1103 mask |= 0xfff0000; 1104 if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP) 1105 mask |= (1 << 28); 1106 if (cap_mask & IB_PM_IS_QP1_DROP_SUP) 1107 mask |= (1 << 29); 1108 } 1109 1110 if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) { 1111 for (i = start_port; i <= num_ports; i++) 1112 reset_counters(extended, ibd_timeout, mask, &portid, i); 1113 } else if (ports_count > 1) { 1114 for (i = 0; i < ports_count; i++) 1115 reset_counters(extended, ibd_timeout, mask, &portid, ports[i]); 1116 } else 1117 reset_counters(extended, ibd_timeout, mask, &portid, port); 1118 1119 done: 1120 mad_rpc_close_port(srcport); 1121 exit(0); 1122 } 1123