1ibv_read_counters(3) Libibverbs Programmer’s Manual ibv_read_counters(3)
2
3
4
6 ibv_read_counters - Read counter values
7
9 #include <infiniband/verbs.h>
10
11 int ibv_read_counters(struct ibv_counters *counters,
12 uint64_t *counters_value,
13 uint32_t ncounters,
14 uint32_t flags);
15
17 ibv_read_counters() returns the values of the chosen counters into
18 counters_value array of which can accumulate ncounters. The values are
19 filled according to the configuration defined by the user in the
20 ibv_attach_counters_point_xxx functions.
21
23 counters
24 Counters object to read.
25
26 counters_value
27 Input buffer to hold read result.
28
29 ncounters
30 Number of counters to fill.
31
32 flags Use enum ibv_read_counters_flags.
33
34 flags Argument
35 IBV_READ_COUNTERS_ATTR_PREFER_CACHED
36 Will prefer reading the values from driver cache, else it will
37 do volatile hardware access which is the default.
38
40 ibv_read_counters() returns 0 on success, or the value of errno on
41 failure (which indicates the failure reason)
42
44 Example: Statically attach counters to a new flow
45
46 This example demonstrates the use of counters which are attached stati‐
47 cally with the creation of a new flow. The counters are read from
48 hardware periodically, and finally all resources are released.
49
50 /* create counters object and define its counters points */
51 /* create simple L2 flow with hardcoded MAC, and a count action */
52 /* read counters periodically, every 1sec, until loop ends */
53 /* assumes user prepared a RAW_PACKET QP as input */
54 /* only limited error checking in run time for code simplicity */
55
56 #include <inttypes.h>
57 #include <infiniband/verbs.h>
58
59 /* the below MAC should be replaced by user */
60 #define FLOW_SPEC_ETH_MAC_VAL {
61 .dst_mac = { 0x00, 0x01, 0x02, 0x03, 0x04,0x05},
62 .src_mac = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
63 .ether_type = 0, .vlan_tag = 0, }
64 #define FLOW_SPEC_ETH_MAC_MASK {
65 .dst_mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
66 .src_mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
67 .ether_type = 0, .vlan_tag = 0, }
68
69 void example_create_flow_with_counters_on_raw_qp(struct ibv_qp *qp) {
70 int idx = 0;
71 int loop = 10;
72 struct ibv_flow *flow = NULL;
73 struct ibv_counters *counters = NULL;
74 struct ibv_counters_init_attr init_attr = {0};
75 struct ibv_counter_attach_attr attach_attr = {0};
76
77 /* create single coutners handle */
78 counters = ibv_create_counters(qp->context, &init_attr);
79
80 /* define counters points */
81 attach_attr.counter_desc = IBV_COUNTER_PACKETS;
82 attach_attr.index = idx++;
83 ret = ibv_attach_counters_point_flow(counters, &attach_attr, NULL);
84 if (ret == ENOTSUP) {
85 fprintf(stderr, "Attaching IBV_COUNTER_PACKETS to flow is not \
86 supported");
87 exit(1);
88 }
89 attach_attr.counter_desc = IBV_COUNTER_BYTES;
90 attach_attr.index = idx++;
91 ibv_attach_counters_point_flow(counters, &attach_attr, NULL);
92 if (ret == ENOTSUP) {
93 fprintf(stderr, "Attaching IBV_COUNTER_BYTES to flow is not \
94 supported");
95 exit(1);
96 }
97
98 /* define a new flow attr that includes the counters handle */
99 struct raw_eth_flow_attr {
100 struct ibv_flow_attr attr;
101 struct ibv_flow_spec_eth spec_eth;
102 struct ibv_flow_spec_counter_action spec_count;
103 } flow_attr = {
104 .attr = {
105 .comp_mask = 0,
106 .type = IBV_FLOW_ATTR_NORMAL,
107 .size = sizeof(flow_attr),
108 .priority = 0,
109 .num_of_specs = 2, /* ETH + COUNT */
110 .port = 1,
111 .flags = 0,
112 },
113 .spec_eth = {
114 .type = IBV_EXP_FLOW_SPEC_ETH,
115 .size = sizeof(struct ibv_flow_spec_eth),
116 .val = FLOW_SPEC_ETH_MAC_VAL,
117 .mask = FLOW_SPEC_ETH_MAC_MASK,
118 },
119 .spec_count = {
120 .type = IBV_FLOW_SPEC_ACTION_COUNT,
121 .size = sizeof(struct ibv_flow_spec_counter_action),
122 .counters = counters, /* attached this counters handle
123 to the newly created ibv_flow */ } };
124
125 /* create the flow */
126 flow = ibv_create_flow(qp, &flow_attr.attr);
127
128 /* allocate array for counters value reading */
129 uint64_t *counters_value = malloc(sizeof(uint64_t) * idx);
130
131 /* periodical read and print of flow counters */
132 while (--loop) {
133 sleep(1);
134
135 /* read hardware counters values */
136 ibv_read_counters(counters, counters_value, idx,
137 IBV_READ_COUNTERS_ATTR_PREFER_CACHED);
138
139 printf("PACKETS = %"PRIu64", BYTES = %"PRIu64 \n",
140 counters_value[0], counters_value[1] );
141 }
142
143 /* all done, release all */
144 free(counters_value);
145
146 /* destroy flow and detach counters */
147 ibv_destroy_flow(flow);
148
149 /* destroy counters handle */
150 ibv_destroy_counters(counters);
151
152 return;
153 }
154
156 ibv_create_counters, ibv_destroy_counters, ibv_attach_coun‐
157 ters_point_flow, ibv_create_flow
158
160 Raed Salem <raeds@mellanox.com>
161
162 Alex Rosenbaum <alexr@mellanox.com>
163
164
165
166libibverbs 2018-04-02 ibv_read_counters(3)