static void clear_port(ib_portid_t * portid, uint16_t cap_mask, char *node_name, int port) { uint8_t pc[1024] = { 0 }; /* bits defined in Table 228 PortCounters CounterSelect and * CounterSelect2 */ uint32_t mask = 0; if (clear_errors) { mask |= 0xFFF; if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP) mask |= 0x10000; } if (clear_counts) mask |= 0xF000; if (mask) if (!performance_reset_via(pc, portid, port, mask, ibd_timeout, IB_GSI_PORT_COUNTERS, ibmad_port)) fprintf(stderr, "Failed to reset errors %s port %d\n", node_name, port); if (clear_errors && details) { memset(pc, 0, 1024); performance_reset_via(pc, portid, port, 0xf, ibd_timeout, IB_GSI_PORT_XMIT_DISCARD_DETAILS, ibmad_port); memset(pc, 0, 1024); performance_reset_via(pc, portid, port, 0x3f, ibd_timeout, IB_GSI_PORT_RCV_ERROR_DETAILS, ibmad_port); } if (clear_counts && (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP))) { if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) mask = 0xFF; else mask = 0x0F; if (!reset_pc_ext(pc, portid, port, mask, ibd_timeout, ibmad_port)) fprintf(stderr, "Failed to reset extended data counters %s, " "%s port %d\n", node_name, portid2str(portid), port); } }
uint8_t * port_performance_reset_via(void *rcvbuf, ib_portid_t *dest, int port, unsigned mask, unsigned timeout, const void *srcport) { return performance_reset_via(rcvbuf, dest, port, mask, timeout, IB_GSI_PORT_COUNTERS, srcport); }
static uint8_t * performance_reset(void *rcvbuf, ib_portid_t *dest, int port, unsigned mask, unsigned timeout, unsigned id) { return performance_reset_via(rcvbuf, dest, port, mask, timeout, id, NULL); }
/** * read and reset IB counters (reset on demand) */ static int read_ib_counter( ) { uint32_t send_val; uint32_t recv_val; uint8_t pc[1024]; /* 32 bit counter FFFFFFFF */ uint32_t max_val = 4294967295; /* if it is bigger than this -> reset */ uint32_t reset_limit = max_val * 0.7; int mask = 0xFFFF; if ( active_ib_port == NULL ) return 0; /* reading cost ~70 mirco secs */ if ( !pma_query_via ( pc, &portid, ibportnum, ib_timeout, IB_GSI_PORT_COUNTERS, srcport ) ) { fprintf( stderr, "perfquery\n" ); exit( 1 ); } mad_decode_field( pc, IB_PC_XMT_BYTES_F, &send_val ); mad_decode_field( pc, IB_PC_RCV_BYTES_F, &recv_val ); /* multiply the numbers read by 4 as the IB port counters are not counting bytes. they always count 32dwords. see man page of perfquery for details internally a uint64_t ia used to sum up the values */ active_ib_port->sum_send_val += ( send_val - active_ib_port->last_send_val ) * 4; active_ib_port->sum_recv_val += ( recv_val - active_ib_port->last_recv_val ) * 4; active_ib_port->send_cntr->value = active_ib_port->sum_send_val; active_ib_port->recv_cntr->value = active_ib_port->sum_recv_val; if ( send_val > reset_limit || recv_val > reset_limit ) { /* reset cost ~70 mirco secs */ if ( !performance_reset_via ( pc, &portid, ibportnum, mask, ib_timeout, IB_GSI_PORT_COUNTERS, srcport ) ) { fprintf( stderr, "perf reset\n" ); exit( 1 ); } mad_decode_field( pc, IB_PC_XMT_BYTES_F, &active_ib_port->last_send_val ); mad_decode_field( pc, IB_PC_RCV_BYTES_F, &active_ib_port->last_recv_val ); } else { active_ib_port->last_send_val = send_val; active_ib_port->last_recv_val = recv_val; } return 0; }
/** * initialize one IB port so that we are able to read values from it */ static int init_ib_port( ib_port * portdata ) { int mgmt_classes[4] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS, IB_PERFORMANCE_CLASS }; char *ca = 0; static uint8_t pc[1024]; int mask = 0xFFFF; srcport = mad_rpc_open_port( ca, portdata->port_number, mgmt_classes, 4 ); if ( !srcport ) { fprintf( stderr, "Failed to open '%s' port '%d'\n", ca, portdata->port_number ); exit( 1 ); } if ( ib_resolve_self_via( &portid, &ibportnum, 0, srcport ) < 0 ) { fprintf( stderr, "can't resolve self port\n" ); exit( 1 ); } /* PerfMgt ClassPortInfo is a required attribute */ /* might be redundant, could be left out for fast implementation */ if ( !pma_query_via ( pc, &portid, ibportnum, ib_timeout, CLASS_PORT_INFO, srcport ) ) { fprintf( stderr, "classportinfo query\n" ); exit( 1 ); } if ( !performance_reset_via ( pc, &portid, ibportnum, mask, ib_timeout, IB_GSI_PORT_COUNTERS, srcport ) ) { fprintf( stderr, "perf reset\n" ); exit( 1 ); } /* read the initial values */ mad_decode_field( pc, IB_PC_XMT_BYTES_F, &portdata->last_send_val ); portdata->sum_send_val = 0; mad_decode_field( pc, IB_PC_RCV_BYTES_F, &portdata->last_recv_val ); portdata->sum_recv_val = 0; portdata->is_initialized = 1; return 0; }