Skip to content

Commit 6c4542e

Browse files
committed
efa: Add Completion Counters support
Implement completion counters for the EFA provider. Each counter object has two event counters (success and error) with set, inc, and read operations. Counter values are accessed directly from userspace through mapped memory. Add efadv_create_comp_cntr() for extended creation with external memory options. Buffer memory is described to the kernel via efa_uverbs_buffer_desc struct passed as a driver-specific ioctl attribute. Three modes are supported per counter: user-supplied VA, user-supplied dmabuf, or provider-internal memory. Signed-off-by: Michael Margolin <mrgolin@amazon.com>
1 parent 5220723 commit 6c4542e

9 files changed

Lines changed: 377 additions & 1 deletion

File tree

debian/ibverbs-providers.symbols

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ libefa.so.1 ibverbs-providers #MINVER#
200200
efadv_get_max_sq_depth@EFA_1.5 63
201201
efadv_get_max_rq_depth@EFA_1.5 63
202202
efadv_qp_from_ibv_qp_ex@EFA_1.6 64
203+
efadv_create_comp_cntr@EFA_1.6 64
203204
libhns.so.1 ibverbs-providers #MINVER#
204205
* Build-Depends-Package: libibverbs-dev
205206
HNS_1.0@HNS_1.0 51

providers/efa/efa.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static const struct verbs_context_ops efa_ctx_ops = {
3333
.create_ah = efa_create_ah,
3434
.create_cq = efa_create_cq,
3535
.create_cq_ex = efa_create_cq_ex,
36+
.create_comp_cntr = efa_create_comp_cntr,
3637
.create_qp = efa_create_qp,
3738
.create_qp_ex = efa_create_qp_ex,
3839
.cq_event = efa_cq_event,
@@ -41,18 +42,26 @@ static const struct verbs_context_ops efa_ctx_ops = {
4142
.dereg_mr = efa_dereg_mr,
4243
.destroy_ah = efa_destroy_ah,
4344
.destroy_cq = efa_destroy_cq,
45+
.destroy_comp_cntr = efa_destroy_comp_cntr,
4446
.destroy_qp = efa_destroy_qp,
47+
.inc_comp_cntr = efa_inc_comp_cntr,
48+
.inc_err_comp_cntr = efa_inc_err_comp_cntr,
4549
.modify_qp = efa_modify_qp,
4650
.poll_cq = efa_poll_cq,
4751
.post_recv = efa_post_recv,
4852
.post_send = efa_post_send,
53+
.qp_attach_comp_cntr = efa_qp_attach_comp_cntr,
4954
.query_device_ex = efa_query_device_ex,
5055
.query_port = efa_query_port,
5156
.query_qp = efa_query_qp,
5257
.query_qp_data_in_order = efa_query_qp_data_in_order,
58+
.read_comp_cntr = efa_read_comp_cntr,
59+
.read_err_comp_cntr = efa_read_err_comp_cntr,
5360
.reg_dmabuf_mr = efa_reg_dmabuf_mr,
5461
.reg_mr = efa_reg_mr,
5562
.req_notify_cq = efa_arm_cq,
63+
.set_comp_cntr = efa_set_comp_cntr,
64+
.set_err_comp_cntr = efa_set_err_comp_cntr,
5665
.free_context = efa_free_context,
5766
};
5867

providers/efa/efa.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ struct efa_cq {
105105
struct efa_sub_cq sub_cq_arr[];
106106
};
107107

108+
struct efa_comp_cntr {
109+
struct ibv_comp_cntr ibv_comp_cntr;
110+
uint64_t comp_val __attribute__((aligned(8)));
111+
uint64_t err_val __attribute__((aligned(8)));
112+
uint64_t *comp_ptr;
113+
uint64_t *err_ptr;
114+
};
115+
108116
struct efa_wq {
109117
uint64_t *wrid;
110118
/* wrid_idx_pool: Pool of free indexes in the wrid array, used to select the
@@ -230,6 +238,11 @@ static inline struct efa_cq *efadv_cq_to_efa_cq(struct efadv_cq *efadv_cq)
230238
return container_of(efadv_cq, struct efa_cq, dv_cq);
231239
}
232240

241+
static inline struct efa_comp_cntr *to_efa_comp_cntr(struct ibv_comp_cntr *ibvcc)
242+
{
243+
return container_of(ibvcc, struct efa_comp_cntr, ibv_comp_cntr);
244+
}
245+
233246
static inline struct efa_qp *to_efa_qp(struct ibv_qp *ibvqp)
234247
{
235248
return container_of(ibvqp, struct efa_qp, verbs_qp.qp);

providers/efa/efadv.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum {
2323
EFADV_DEVICE_ATTR_CAPS_RDMA_WRITE = 1 << 3,
2424
EFADV_DEVICE_ATTR_CAPS_UNSOLICITED_WRITE_RECV = 1 << 4,
2525
EFADV_DEVICE_ATTR_CAPS_CQ_WITH_EXT_MEM_DMABUF = 1 << 5,
26+
EFADV_DEVICE_ATTR_CAPS_COMP_CNTR = 1 << 6,
2627
};
2728

2829
struct efadv_device_attr {
@@ -190,6 +191,40 @@ static inline bool efadv_wc_is_unsolicited(struct efadv_cq *efadv_cq)
190191
return efadv_cq->wc_is_unsolicited(efadv_cq);
191192
}
192193

194+
enum {
195+
EFADV_MEMORY_LOCATION_VA,
196+
EFADV_MEMORY_LOCATION_DMABUF,
197+
};
198+
199+
struct efadv_memory_location {
200+
uint8_t *ptr;
201+
struct {
202+
uint64_t offset;
203+
int32_t fd;
204+
uint32_t reserved;
205+
} dmabuf;
206+
uint8_t type;
207+
uint8_t reserved[7];
208+
};
209+
210+
enum {
211+
EFADV_COMP_CNTR_INIT_WITH_COMP_EXTERNAL_MEM = 1 << 0,
212+
EFADV_COMP_CNTR_INIT_WITH_ERR_EXTERNAL_MEM = 1 << 1,
213+
};
214+
215+
struct efadv_comp_cntr_init_attr {
216+
uint64_t comp_mask;
217+
uint32_t flags;
218+
uint32_t reserved;
219+
struct efadv_memory_location comp_cntr_ext_mem;
220+
struct efadv_memory_location err_cntr_ext_mem;
221+
};
222+
223+
struct ibv_comp_cntr *efadv_create_comp_cntr(struct ibv_context *ibvctx,
224+
struct ibv_comp_cntr_init_attr *attr,
225+
struct efadv_comp_cntr_init_attr *efa_attr,
226+
uint32_t inlen);
227+
193228
enum {
194229
EFADV_MR_ATTR_VALIDITY_RECV_IC_ID = 1 << 0,
195230
EFADV_MR_ATTR_VALIDITY_RDMA_READ_IC_ID = 1 << 1,

providers/efa/libefa.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ EFA_1.5 {
3939
EFA_1.6 {
4040
global:
4141
efadv_qp_from_ibv_qp_ex;
42+
efadv_create_comp_cntr;
4243
} EFA_1.5;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
layout: page
3+
title: EFADV_CREATE_COMP_CNTR
4+
section: 3
5+
tagline: Verbs
6+
date: 2026-04-27
7+
header: "EFA Direct Verbs Manual"
8+
footer: efa
9+
---
10+
11+
# NAME
12+
13+
efadv_create_comp_cntr - Create EFA specific Completion Counter
14+
15+
# SYNOPSIS
16+
17+
```c
18+
#include <infiniband/efadv.h>
19+
20+
struct ibv_comp_cntr *efadv_create_comp_cntr(struct ibv_context *context,
21+
struct ibv_comp_cntr_init_attr *attr,
22+
struct efadv_comp_cntr_init_attr *efa_attr,
23+
uint32_t inlen);
24+
```
25+
26+
# DESCRIPTION
27+
28+
**efadv_create_comp_cntr()** creates a Completion Counter with EFA specific
29+
properties, such as external memory for the counter values.
30+
31+
The argument *attr* is an ibv_comp_cntr_init_attr struct, as defined in
32+
<infiniband/verbs.h>.
33+
34+
Compatibility is handled using the comp_mask and inlen fields.
35+
36+
```c
37+
enum {
38+
EFADV_MEMORY_LOCATION_VA,
39+
EFADV_MEMORY_LOCATION_DMABUF,
40+
};
41+
42+
struct efadv_memory_location {
43+
uint8_t *ptr;
44+
struct {
45+
uint64_t offset;
46+
int32_t fd;
47+
uint32_t reserved;
48+
} dmabuf;
49+
uint8_t type;
50+
uint8_t reserved[7];
51+
};
52+
53+
struct efadv_comp_cntr_init_attr {
54+
uint64_t comp_mask;
55+
uint32_t flags;
56+
uint32_t reserved;
57+
struct efadv_memory_location comp_cntr_ext_mem;
58+
struct efadv_memory_location err_cntr_ext_mem;
59+
};
60+
```
61+
62+
*inlen*
63+
: In: Size of struct efadv_comp_cntr_init_attr.
64+
65+
*comp_mask*
66+
: Compatibility mask.
67+
68+
*flags*
69+
: A bitwise OR of the various values described below.
70+
71+
**EFADV_COMP_CNTR_INIT_WITH_COMP_EXTERNAL_MEM**:
72+
Use application-provided memory for the completion count, as
73+
described by *comp_cntr_ext_mem*.
74+
75+
**EFADV_COMP_CNTR_INIT_WITH_ERR_EXTERNAL_MEM**:
76+
Use application-provided memory for the error count, as
77+
described by *err_cntr_ext_mem*.
78+
79+
*comp_cntr_ext_mem*
80+
: Memory location for the completion count when using external memory.
81+
82+
*err_cntr_ext_mem*
83+
: Memory location for the error count when using external memory.
84+
85+
## efadv_memory_location
86+
87+
The external memory is described by an **efadv_memory_location** structure
88+
which supports two modes:
89+
90+
*type*
91+
: **EFADV_MEMORY_LOCATION_VA** for a virtual address, or
92+
**EFADV_MEMORY_LOCATION_DMABUF** for a DMA-BUF reference.
93+
94+
*ptr*
95+
: Virtual address pointer. Required when type is
96+
**EFADV_MEMORY_LOCATION_VA**. When type is
97+
**EFADV_MEMORY_LOCATION_DMABUF**, may optionally be set to provide a
98+
process-accessible mapping of the DMA-BUF memory.
99+
100+
*dmabuf.fd*
101+
: DMA-BUF file descriptor (used when type is
102+
**EFADV_MEMORY_LOCATION_DMABUF**).
103+
104+
*dmabuf.offset*
105+
: Offset within the DMA-BUF.
106+
107+
# RETURN VALUE
108+
109+
efadv_create_comp_cntr() returns a pointer to the created ibv_comp_cntr, or
110+
NULL if the request fails.
111+
112+
# SEE ALSO
113+
114+
**efadv**(7), **ibv_create_comp_cntr**(3), **ibv_qp_attach_comp_cntr**(3)
115+
116+
# AUTHORS
117+
118+
Michael Margolin <mrgolin@amazon.com>

providers/efa/man/efadv_query_device.3.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ struct efadv_device_attr {
9292
Indicates that creating CQs with external memory buffers by passing dmabuf is
9393
supported.
9494

95+
EFADV_DEVICE_ATTR_CAPS_COMP_CNTR:
96+
Completion counters are supported.
97+
9598
*max_rdma_size*
9699
: Maximum RDMA transfer size in bytes.
97100

0 commit comments

Comments
 (0)