|
NAME | SYNOPSIS | DESCRIPTION | ARGUMENTS | RETURN VALUE | EXAMPLE | SEE ALSO | AUTHORS | COLOPHON |
|
|
|
ibv_read_counters(3) Libibverbs Programmer’s Manual ibv_read_counters(3)
ibv_read_counters - Read counter values
#include <infiniband/verbs.h>
int ibv_read_counters(struct ibv_counters *counters,
uint64_t *counters_value,
uint32_t ncounters,
uint32_t flags);
ibv_read_counters() returns the values of the chosen counters into
counters_value array of which can accumulate ncounters. The
values are filled according to the configuration defined by the
user in the ibv_attach_counters_point_xxx functions.
counters
Counters object to read.
counters_value
Input buffer to hold read result.
ncounters
Number of counters to fill.
flags Use enum ibv_read_counters_flags.
flags Argument
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.
ibv_read_counters() returns 0 on success, or the value of errno on
failure (which indicates the failure reason)
Example: Statically attach counters to a new flow
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.
/* create counters object and define its counters points */
/* create simple L2 flow with hardcoded MAC, and a count action */
/* read counters periodically, every 1sec, until loop ends */
/* assumes user prepared a RAW_PACKET QP as input */
/* only limited error checking in run time for code simplicity */
#include <inttypes.h>
#include <infiniband/verbs.h>
/* the below MAC should be replaced by user */
#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(struct ibv_qp *qp) {
int idx = 0;
int loop = 10;
struct ibv_flow *flow = NULL;
struct ibv_counters *counters = NULL;
struct ibv_counters_init_attr init_attr = {0};
struct ibv_counter_attach_attr attach_attr = {0};
/* create single counters handle */
counters = ibv_create_counters(qp->context, &init_attr);
/* define counters points */
attach_attr.counter_desc = IBV_COUNTER_PACKETS;
attach_attr.index = idx++;
ret = ibv_attach_counters_point_flow(counters, &attach_attr, NULL);
if (ret == ENOTSUP) {
fprintf(stderr, "Attaching IBV_COUNTER_PACKETS to flow is not \
supported");
exit(1);
}
attach_attr.counter_desc = IBV_COUNTER_BYTES;
attach_attr.index = idx++;
ibv_attach_counters_point_flow(counters, &attach_attr, NULL);
if (ret == ENOTSUP) {
fprintf(stderr, "Attaching IBV_COUNTER_BYTES to flow is not \
supported");
exit(1);
}
/* define a new flow attr that includes the counters handle */
struct raw_eth_flow_attr {
struct ibv_flow_attr attr;
struct ibv_flow_spec_eth spec_eth;
struct ibv_flow_spec_counter_action spec_count;
} flow_attr = {
.attr = {
.comp_mask = 0,
.type = IBV_FLOW_ATTR_NORMAL,
.size = sizeof(flow_attr),
.priority = 0,
.num_of_specs = 2, /* ETH + COUNT */
.port = 1,
.flags = 0,
},
.spec_eth = {
.type = IBV_EXP_FLOW_SPEC_ETH,
.size = sizeof(struct 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 = sizeof(struct ibv_flow_spec_counter_action),
.counters = counters, /* attached this counters handle
to the newly created ibv_flow */ } };
/* create the flow */
flow = ibv_create_flow(qp, &flow_attr.attr);
/* allocate array for counters value reading */
uint64_t *counters_value = malloc(sizeof(uint64_t) * idx);
/* periodical read and print of flow counters */
while (--loop) {
sleep(1);
/* read hardware counters values */
ibv_read_counters(counters, counters_value, idx,
IBV_READ_COUNTERS_ATTR_PREFER_CACHED);
printf("PACKETS = %"PRIu64", BYTES = %"PRIu64 \n",
counters_value[0], counters_value[1] );
}
/* all done, release all */
free(counters_value);
/* destroy flow and detach counters */
ibv_destroy_flow(flow);
/* destroy counters handle */
ibv_destroy_counters(counters);
return;
}
ibv_create_counters, ibv_destroy_counters,
ibv_attach_counters_point_flow, ibv_create_flow
Raed Salem ⟨[email protected]⟩
Alex Rosenbaum ⟨[email protected]⟩
This page is part of the rdma-core (RDMA Core Userspace Libraries
and Daemons) project. Information about the project can be found
at ⟨https://github.com/linux-rdma/rdma-core⟩. If you have a bug
report for this manual page, send it to
[email protected]. This page was obtained from the
project's upstream Git repository
⟨https://github.com/linux-rdma/rdma-core.git⟩ on 2025-08-11. (At
that time, the date of the most recent commit that was found in
the repository was 2025-08-04.) If you discover any rendering
problems in this HTML version of the page, or you believe there is
a better or more up-to-date source for the page, or you have
corrections or improvements to the information in this COLOPHON
(which is not part of the original manual page), send a mail to
[email protected]
libibverbs 2018-04-02 ibv_read_counters(3)