.\" Automatically generated by Pandoc 3.5 .\" .TH "ibv_read_counters" "3" "2018\-04\-02" "libibverbs" "Libibverbs Programmer\[cq]s Manual" .SH NAME \f[B]ibv_read_counters\f[R] \- Read counter values .SH SYNOPSIS .IP .EX #include \f[B]\f[R] int ibv_read_counters(\f[B]struct\f[R] ibv_counters *counters, uint64_t *counters_value, uint32_t ncounters, uint32_t flags); .EE .SH DESCRIPTION \f[B]ibv_read_counters\f[R]() returns the values of the chosen counters into \f[I]counters_value\f[R] array of which can accumulate \f[I]ncounters\f[R]. The values are filled according to the configuration defined by the user in the \f[B]ibv_attach_counters_point_xxx\f[R] functions. .SH ARGUMENTS .TP \f[I]counters\f[R] Counters object to read. .TP \f[I]counters_value\f[R] Input buffer to hold read result. .TP \f[I]ncounters\f[R] Number of counters to fill. .TP \f[I]flags\f[R] Use enum ibv_read_counters_flags. .SS \f[I]flags\f[R] Argument .TP IBV_READ_COUNTERS_ATTR_PREFER_CACHED Will prefer reading the values from driver cache, else it will do volatile hardware access which is the default. .SH RETURN VALUE \f[B]ibv_read_counters\f[R]() returns 0 on success, or the value of errno on failure (which indicates the failure reason) .SH EXAMPLE Example: Statically attach counters to a new flow .PP This example demonstrates the use of counters which are attached statically with the creation of a new flow. The counters are read from hardware periodically, and finally all resources are released. .IP .EX \f[I]/* create counters object and define its counters points */\f[R] \f[I]/* create simple L2 flow with hardcoded MAC, and a count action */\f[R] \f[I]/* read counters periodically, every 1sec, until loop ends */\f[R] \f[I]/* assumes user prepared a RAW_PACKET QP as input */\f[R] \f[I]/* only limited error checking in run time for code simplicity */\f[R] #include \f[B]\f[R] #include \f[B]\f[R] \f[I]/* the below MAC should be replaced by user */\f[R] #define FLOW_SPEC_ETH_MAC_VAL { .dst_mac = { 0x00, 0x01, 0x02, 0x03, 0x04,0x05}, .src_mac = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, .ether_type = 0, .vlan_tag = 0, } #define FLOW_SPEC_ETH_MAC_MASK { .dst_mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, .src_mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, .ether_type = 0, .vlan_tag = 0, } void example_create_flow_with_counters_on_raw_qp(\f[B]struct\f[R] ibv_qp *qp) { int idx = 0; int loop = 10; \f[B]struct\f[R] ibv_flow *flow = NULL; \f[B]struct\f[R] ibv_counters *counters = NULL; \f[B]struct\f[R] ibv_counters_init_attr init_attr = {0}; \f[B]struct\f[R] ibv_counter_attach_attr attach_attr = {0}; \f[I]/* create single counters handle */\f[R] counters = ibv_create_counters(qp\->context, &init_attr); \f[I]/* define counters points */\f[R] attach_attr.counter_desc = IBV_COUNTER_PACKETS; attach_attr.index = idx++; ret = ibv_attach_counters_point_flow(counters, &attach_attr, NULL); \f[B]if\f[R] (ret == ENOTSUP) { fprintf(stderr, \[dq]Attaching IBV_COUNTER_PACKETS to flow is not \[rs] supported\[dq]); exit(1); } attach_attr.counter_desc = IBV_COUNTER_BYTES; attach_attr.index = idx++; ibv_attach_counters_point_flow(counters, &attach_attr, NULL); \f[B]if\f[R] (ret == ENOTSUP) { fprintf(stderr, \[dq]Attaching IBV_COUNTER_BYTES to flow is not \[rs] supported\[dq]); exit(1); } \f[I]/* define a new flow attr that includes the counters handle */\f[R] \f[B]struct\f[R] raw_eth_flow_attr { \f[B]struct\f[R] ibv_flow_attr attr; \f[B]struct\f[R] ibv_flow_spec_eth spec_eth; \f[B]struct\f[R] ibv_flow_spec_counter_action spec_count; } flow_attr = { .attr = { .comp_mask = 0, .type = IBV_FLOW_ATTR_NORMAL, .size = \f[B]sizeof\f[R](flow_attr), .priority = 0, .num_of_specs = 2, \f[I]/* ETH + COUNT */\f[R] .port = 1, .flags = 0, }, .spec_eth = { .type = IBV_EXP_FLOW_SPEC_ETH, .size = \f[B]sizeof\f[R](\f[B]struct\f[R] ibv_flow_spec_eth), .val = FLOW_SPEC_ETH_MAC_VAL, .mask = FLOW_SPEC_ETH_MAC_MASK, }, .spec_count = { .type = IBV_FLOW_SPEC_ACTION_COUNT, .size = \f[B]sizeof\f[R](\f[B]struct\f[R] ibv_flow_spec_counter_action), .counters = counters, \f[I]/* attached this counters handle\f[R] \f[I]to the newly created ibv_flow */\f[R] } }; \f[I]/* create the flow */\f[R] flow = ibv_create_flow(qp, &flow_attr.attr); \f[I]/* allocate array for counters value reading */\f[R] uint64_t *counters_value = malloc(\f[B]sizeof\f[R](uint64_t) * idx); \f[I]/* periodical read and print of flow counters */\f[R] \f[B]while\f[R] (\-\-loop) { sleep(1); \f[I]/* read hardware counters values */\f[R] ibv_read_counters(counters, counters_value, idx, IBV_READ_COUNTERS_ATTR_PREFER_CACHED); printf(\[dq]PACKETS = %\[dq]PRIu64\[dq], BYTES = %\[dq]PRIu64 \[rs]n\[dq], counters_value[0], counters_value[1] ); } \f[I]/* all done, release all */\f[R] free(counters_value); \f[I]/* destroy flow and detach counters */\f[R] ibv_destroy_flow(flow); \f[I]/* destroy counters handle */\f[R] ibv_destroy_counters(counters); \f[B]return\f[R]; } .EE .SH SEE ALSO \f[B]ibv_create_counters\f[R], \f[B]ibv_destroy_counters\f[R], \f[B]ibv_attach_counters_point_flow\f[R], \f[B]ibv_create_flow\f[R] .SH AUTHORS Raed Salem \c .MT raeds@mellanox.com .ME \c .PP Alex Rosenbaum \c .MT alexr@mellanox.com .ME \c