Skip to content

Commit 7ec2e79

Browse files
committed
efa: Add direct verbs query QP and CQ
Extend EFA direct verbs to allow querying of QP and CQ parameters. At first stage those new verbs enable getting queues' virtual addresses as well as their structure what can be used for accelerator driven datapath. Reviewed-by: Daniel Kranzdorf <[email protected]> Reviewed-by: Yonatan Nachum <[email protected]> Signed-off-by: Michael Margolin <[email protected]>
1 parent 318b7f5 commit 7ec2e79

File tree

8 files changed

+263
-29
lines changed

8 files changed

+263
-29
lines changed

debian/ibverbs-providers.symbols

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,16 @@ libefa.so.1 ibverbs-providers #MINVER#
170170
EFA_1.1@EFA_1.1 26
171171
EFA_1.2@EFA_1.2 43
172172
EFA_1.3@EFA_1.3 50
173+
EFA_1.4@EFA_1.4 58
173174
efadv_create_driver_qp@EFA_1.0 24
174175
efadv_create_qp_ex@EFA_1.1 26
175176
efadv_query_device@EFA_1.1 26
176177
efadv_query_ah@EFA_1.1 26
177178
efadv_cq_from_ibv_cq_ex@EFA_1.2 43
178179
efadv_create_cq@EFA_1.2 43
179180
efadv_query_mr@EFA_1.3 50
181+
efadv_query_qp_wqs@EFA_1.4 58
182+
efadv_query_cq@EFA_1.4 58
180183
libhns.so.1 ibverbs-providers #MINVER#
181184
* Build-Depends-Package: libibverbs-dev
182185
HNS_1.0@HNS_1.0 51

providers/efa/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ if (ENABLE_LTTNG AND LTTNGUST_FOUND)
33
endif()
44

55
rdma_shared_provider(efa libefa.map
6-
1 1.3.${PACKAGE_VERSION}
6+
1 1.4.${PACKAGE_VERSION}
77
${TRACE_FILE}
88
efa.c
99
verbs.c

providers/efa/efadv.h

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
22
/*
3-
* Copyright 2019-2024 Amazon.com, Inc. or its affiliates. All rights reserved.
3+
* Copyright 2019-2025 Amazon.com, Inc. or its affiliates. All rights reserved.
44
*/
55

66
#ifndef __EFADV_H__
@@ -16,32 +16,6 @@
1616
extern "C" {
1717
#endif
1818

19-
enum {
20-
/* Values must match the values in efa-abi.h */
21-
EFADV_QP_DRIVER_TYPE_SRD = 0,
22-
};
23-
24-
struct ibv_qp *efadv_create_driver_qp(struct ibv_pd *ibvpd,
25-
struct ibv_qp_init_attr *attr,
26-
uint32_t driver_qp_type);
27-
28-
enum {
29-
EFADV_QP_FLAGS_UNSOLICITED_WRITE_RECV = 1 << 0,
30-
};
31-
32-
struct efadv_qp_init_attr {
33-
uint64_t comp_mask;
34-
uint32_t driver_qp_type;
35-
uint16_t flags;
36-
uint8_t sl;
37-
uint8_t reserved[1];
38-
};
39-
40-
struct ibv_qp *efadv_create_qp_ex(struct ibv_context *ibvctx,
41-
struct ibv_qp_init_attr_ex *attr_ex,
42-
struct efadv_qp_init_attr *efa_attr,
43-
uint32_t inlen);
44-
4519
enum {
4620
EFADV_DEVICE_ATTR_CAPS_RDMA_READ = 1 << 0,
4721
EFADV_DEVICE_ATTR_CAPS_RNR_RETRY = 1 << 1,
@@ -76,6 +50,45 @@ struct efadv_ah_attr {
7650
int efadv_query_ah(struct ibv_ah *ibvah, struct efadv_ah_attr *attr,
7751
uint32_t inlen);
7852

53+
enum {
54+
/* Values must match the values in efa-abi.h */
55+
EFADV_QP_DRIVER_TYPE_SRD = 0,
56+
};
57+
58+
struct ibv_qp *efadv_create_driver_qp(struct ibv_pd *ibvpd,
59+
struct ibv_qp_init_attr *attr,
60+
uint32_t driver_qp_type);
61+
62+
enum {
63+
EFADV_QP_FLAGS_UNSOLICITED_WRITE_RECV = 1 << 0,
64+
};
65+
66+
struct efadv_qp_init_attr {
67+
uint64_t comp_mask;
68+
uint32_t driver_qp_type;
69+
uint16_t flags;
70+
uint8_t sl;
71+
uint8_t reserved;
72+
};
73+
74+
struct ibv_qp *efadv_create_qp_ex(struct ibv_context *ibvctx,
75+
struct ibv_qp_init_attr_ex *attr_ex,
76+
struct efadv_qp_init_attr *efa_attr,
77+
uint32_t inlen);
78+
79+
struct efadv_wq_attr {
80+
uint64_t comp_mask;
81+
uint8_t *buffer;
82+
uint32_t entry_size;
83+
uint32_t num_entries;
84+
uint32_t *doorbell;
85+
uint32_t max_batch;
86+
uint8_t reserved[4];
87+
};
88+
89+
int efadv_query_qp_wqs(struct ibv_qp *ibvqp, struct efadv_wq_attr *sq_attr,
90+
struct efadv_wq_attr *rq_attr, uint32_t inlen);
91+
7992
struct efadv_cq {
8093
uint64_t comp_mask;
8194
int (*wc_read_sgid)(struct efadv_cq *efadv_cq, union ibv_gid *sgid);
@@ -109,6 +122,15 @@ struct ibv_cq_ex *efadv_create_cq(struct ibv_context *ibvctx,
109122
struct efadv_cq_init_attr *efa_attr,
110123
uint32_t inlen);
111124

125+
struct efadv_cq_attr {
126+
uint64_t comp_mask;
127+
uint8_t *buffer;
128+
uint32_t entry_size;
129+
uint32_t num_entries;
130+
};
131+
132+
int efadv_query_cq(struct ibv_cq *ibvcq, struct efadv_cq_attr *attr, uint32_t inlen);
133+
112134
struct efadv_cq *efadv_cq_from_ibv_cq_ex(struct ibv_cq_ex *ibvcqx);
113135

114136
static inline int efadv_wc_read_sgid(struct efadv_cq *efadv_cq,

providers/efa/libefa.map

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,9 @@ EFA_1.3 {
2323
global:
2424
efadv_query_mr;
2525
} EFA_1.2;
26+
27+
EFA_1.4 {
28+
global:
29+
efadv_query_qp_wqs;
30+
efadv_query_cq;
31+
} EFA_1.3;

providers/efa/man/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ rdma_man_pages(
33
efadv_create_driver_qp.3.md
44
efadv_create_qp_ex.3.md
55
efadv_query_ah.3.md
6+
efadv_query_cq.3.md
67
efadv_query_device.3.md
78
efadv_query_mr.3.md
9+
efadv_query_qp_wqs.3.md
810
)

providers/efa/man/efadv_query_cq.3.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
layout: page
3+
title: EFADV_QUERY_CQ
4+
section: 3
5+
tagline: Verbs
6+
date: 2025-04-15
7+
header: "EFA Direct Verbs Manual"
8+
footer: efa
9+
---
10+
11+
# NAME
12+
13+
efadv_query_cq - Query EFA specific Completion Queue attributes
14+
15+
# SYNOPSIS
16+
17+
```c
18+
#include <infiniband/efadv.h>
19+
20+
int efadv_query_cq(struct ibv_cq *ibvcq, struct efadv_cq_attr *attr,
21+
uint32_t inlen);
22+
```
23+
24+
# DESCRIPTION
25+
26+
**efadv_query_cq()** queries device-specific Completion Queue attributes.
27+
28+
Compatibility is handled using the comp_mask and inlen fields.
29+
30+
```c
31+
struct efadv_cq_attr {
32+
uint64_t comp_mask;
33+
uint8_t *buffer;
34+
uint32_t entry_size;
35+
uint32_t num_entries;
36+
};
37+
```
38+
39+
*inlen*
40+
: In: Size of struct efadv_cq_attr.
41+
42+
*comp_mask*
43+
: Compatibility mask.
44+
45+
*buffer*
46+
: Completion queue buffer.
47+
48+
*entry_size*
49+
: Size of each completion queue entry.
50+
51+
*num_entries*
52+
: Maximal number of entries in the completion queue.
53+
54+
# RETURN VALUE
55+
56+
**efadv_query_cq()** returns 0 on success, or the value of errno on failure
57+
(which indicates the failure reason).
58+
59+
# SEE ALSO
60+
61+
**efadv**(7)
62+
63+
# NOTES
64+
65+
* Compatibility mask (comp_mask) is an out field and currently has no values.
66+
67+
# AUTHORS
68+
69+
Michael Margolin <[email protected]>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
layout: page
3+
title: EFADV_QUERY_QP_WQS
4+
section: 3
5+
tagline: Verbs
6+
date: 2025-05-14
7+
header: "EFA Direct Verbs Manual"
8+
footer: efa
9+
---
10+
11+
# NAME
12+
13+
efadv_query_qp_wqs - Query EFA specific Queue Pair work queue attributes
14+
15+
# SYNOPSIS
16+
17+
```c
18+
#include <infiniband/efadv.h>
19+
20+
int efadv_query_qp_wqs(struct ibv_qp *ibvqp, struct efadv_wq_attr *sq_attr,
21+
struct efadv_wq_attr *rq_attr, uint32_t inlen);
22+
```
23+
24+
# DESCRIPTION
25+
26+
**efadv_query_qp_wqs()** queries device-specific Queue Pair work queue attributes.
27+
28+
Compatibility is handled using the comp_mask and inlen fields.
29+
30+
```c
31+
struct efadv_wq_attr {
32+
uint64_t comp_mask;
33+
uint8_t *buffer;
34+
uint32_t entry_size;
35+
uint32_t num_entries;
36+
uint32_t *doorbell;
37+
uint32_t max_batch;
38+
uint8_t reserved[4];
39+
};
40+
```
41+
42+
*inlen*
43+
: In: Size of struct efadv_wq_attr.
44+
45+
*comp_mask*
46+
: Compatibility mask.
47+
48+
*buffer*
49+
: Queue buffer.
50+
51+
*entry_size*
52+
: Size of each entry in the queue.
53+
54+
*num_entries*
55+
: Maximal number of entries in the queue.
56+
57+
*doorbell*
58+
: Queue doorbell.
59+
60+
*max_batch*
61+
: Maximum batch size for queue submissions.
62+
63+
# RETURN VALUE
64+
65+
**efadv_query_qp_wqs()** returns 0 on success, or the value of errno on failure
66+
(which indicates the failure reason).
67+
68+
# SEE ALSO
69+
70+
**efadv**(7)
71+
72+
# NOTES
73+
74+
* Compatibility mask (comp_mask) is an out field and currently has no values.
75+
76+
# AUTHORS
77+
78+
Michael Margolin <[email protected]>

providers/efa/verbs.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,28 @@ struct ibv_cq_ex *efadv_create_cq(struct ibv_context *ibvctx,
10821082
return create_cq(ibvctx, attr_ex, &local_efa_attr);
10831083
}
10841084

1085+
int efadv_query_cq(struct ibv_cq *ibvcq, struct efadv_cq_attr *attr, uint32_t inlen)
1086+
{
1087+
struct efa_cq *cq = to_efa_cq(ibvcq);
1088+
1089+
if (!is_efa_dev(ibvcq->context->device)) {
1090+
verbs_err(verbs_get_ctx(ibvcq->context), "Not an EFA device\n");
1091+
return EOPNOTSUPP;
1092+
}
1093+
1094+
if (!vext_field_avail(typeof(*attr), num_entries, inlen)) {
1095+
verbs_err(verbs_get_ctx(ibvcq->context), "Compatibility issues\n");
1096+
return EINVAL;
1097+
}
1098+
1099+
attr->comp_mask = 0;
1100+
attr->buffer = cq->buf;
1101+
attr->entry_size = cq->cqe_size;
1102+
attr->num_entries = ibvcq->cqe;
1103+
1104+
return 0;
1105+
}
1106+
10851107
struct efadv_cq *efadv_cq_from_ibv_cq_ex(struct ibv_cq_ex *ibvcqx)
10861108
{
10871109
struct efa_cq *cq = to_efa_cq_ex(ibvcqx);
@@ -1681,7 +1703,7 @@ struct ibv_qp *efadv_create_qp_ex(struct ibv_context *ibvctx,
16811703
!vext_field_avail(struct efadv_qp_init_attr,
16821704
driver_qp_type, inlen) ||
16831705
efa_attr->comp_mask ||
1684-
!is_reserved_cleared(efa_attr->reserved) ||
1706+
efa_attr->reserved ||
16851707
(inlen > sizeof(*efa_attr) && !is_ext_cleared(efa_attr, inlen))) {
16861708
verbs_err(verbs_get_ctx(ibvctx), "Compatibility issues\n");
16871709
errno = EINVAL;
@@ -1725,6 +1747,38 @@ int efa_query_qp(struct ibv_qp *ibvqp, struct ibv_qp_attr *attr,
17251747
&cmd, sizeof(cmd));
17261748
}
17271749

1750+
int efadv_query_qp_wqs(struct ibv_qp *ibvqp, struct efadv_wq_attr *sq_attr,
1751+
struct efadv_wq_attr *rq_attr, uint32_t inlen)
1752+
{
1753+
struct efa_qp *qp = to_efa_qp(ibvqp);
1754+
1755+
if (!is_efa_dev(ibvqp->context->device)) {
1756+
verbs_err(verbs_get_ctx(ibvqp->context), "Not an EFA device\n");
1757+
return EOPNOTSUPP;
1758+
}
1759+
1760+
if (!vext_field_avail(typeof(*sq_attr), max_batch, inlen)) {
1761+
verbs_err(verbs_get_ctx(ibvqp->context), "Compatibility issues\n");
1762+
return EINVAL;
1763+
}
1764+
1765+
sq_attr->comp_mask = 0;
1766+
sq_attr->buffer = qp->sq.desc;
1767+
sq_attr->entry_size = sizeof(struct efa_io_tx_wqe);
1768+
sq_attr->num_entries = qp->sq.wq.wqe_cnt;
1769+
sq_attr->doorbell = qp->sq.wq.db;
1770+
sq_attr->max_batch = qp->sq.max_batch_wr;
1771+
1772+
rq_attr->comp_mask = 0;
1773+
rq_attr->buffer = qp->rq.buf;
1774+
rq_attr->entry_size = sizeof(struct efa_io_rx_desc);
1775+
rq_attr->num_entries = qp->rq.wq.desc_mask + 1;
1776+
rq_attr->doorbell = qp->rq.wq.db;
1777+
rq_attr->max_batch = rq_attr->num_entries;
1778+
1779+
return 0;
1780+
}
1781+
17281782
int efa_query_qp_data_in_order(struct ibv_qp *ibvqp, enum ibv_wr_opcode op,
17291783
uint32_t flags)
17301784
{

0 commit comments

Comments
 (0)