Skip to content

Commit 0784b27

Browse files
dkkranzmrgolin
authored andcommitted
efa: Read source GID from EFA DV CQ entry
Add direct verb to read source address from EFA CQ completion entry, for completion from unknown AH. Adjust the CQ entry size requested from the device accordingly. Signed-off-by: Daniel Kranzdorf <[email protected]>
1 parent df6ad86 commit 0784b27

File tree

8 files changed

+92
-39
lines changed

8 files changed

+92
-39
lines changed

providers/efa/efa.c

Lines changed: 2 additions & 1 deletion
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-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
3+
* Copyright 2019-2022 Amazon.com, Inc. or its affiliates. All rights reserved.
44
*/
55

66
#include <stdio.h>
@@ -75,6 +75,7 @@ static struct verbs_context *efa_alloc_context(struct ibv_device *vdev,
7575
ctx->sub_cqs_per_cq = resp.sub_cqs_per_cq;
7676
ctx->cmds_supp_udata_mask = resp.cmds_supp_udata_mask;
7777
ctx->cqe_size = sizeof(struct efa_io_rx_cdesc);
78+
ctx->ex_cqe_size = sizeof(struct efa_io_rx_cdesc_ex);
7879
ctx->inline_buf_size = resp.inline_buf_size;
7980
ctx->max_llq_size = resp.max_llq_size;
8081
ctx->max_tx_batch = resp.max_tx_batch;

providers/efa/efa.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct efa_context {
4242
uint16_t max_tx_batch;
4343
uint16_t min_sq_wr;
4444
size_t cqe_size;
45+
size_t ex_cqe_size;
4546
struct efa_qp **qp_table;
4647
unsigned int qp_table_sz_m1;
4748
pthread_spinlock_t qp_table_lock;
@@ -176,6 +177,11 @@ static inline struct efa_cq *to_efa_cq_ex(struct ibv_cq_ex *ibvcqx)
176177
return container_of(ibvcqx, struct efa_cq, verbs_cq.cq_ex);
177178
}
178179

180+
static inline struct efa_cq *efadv_cq_to_efa_cq(struct efadv_cq *efadv_cq)
181+
{
182+
return container_of(efadv_cq, struct efa_cq, dv_cq);
183+
}
184+
179185
static inline struct efa_qp *to_efa_qp(struct ibv_qp *ibvqp)
180186
{
181187
return container_of(ibvqp, struct efa_qp, verbs_qp.qp);

providers/efa/efa_io_defs.h

Lines changed: 6 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 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
3+
* Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All rights reserved.
44
*/
55

66
#ifndef _EFA_IO_H_
@@ -219,9 +219,7 @@ struct efa_io_cdesc_common {
219219
* 2:1 : q_type - enum efa_io_queue_type: send/recv
220220
* 3 : has_imm - indicates that immediate data is
221221
* present - for RX completions only
222-
* 4 : wide_completion - indicates that wide
223-
* completion format is used
224-
* 7:5 : reserved29
222+
* 7:4 : reserved28 - MBZ
225223
*/
226224
uint8_t flags;
227225

@@ -253,33 +251,15 @@ struct efa_io_rx_cdesc {
253251
};
254252

255253
/* Extended Rx Completion Descriptor */
256-
struct efa_io_rx_cdesc_wide {
254+
struct efa_io_rx_cdesc_ex {
257255
/* Base RX completion info */
258256
struct efa_io_rx_cdesc rx_cdesc_base;
259257

260258
/*
261-
* Word 0 of remote (source) address, needed only for in-band
262-
* ad-hoc AH support
259+
* Valid only in case of unknown AH (0xFFFF) and CQ set_src_addr is
260+
* enabled.
263261
*/
264-
uint32_t src_addr_0;
265-
266-
/*
267-
* Word 1 of remote (source) address, needed only for in-band
268-
* ad-hoc AH support
269-
*/
270-
uint32_t src_addr_1;
271-
272-
/*
273-
* Word 2 of remote (source) address, needed only for in-band
274-
* ad-hoc AH support
275-
*/
276-
uint32_t src_addr_2;
277-
278-
/*
279-
* Word 3 of remote (source) address, needed only for in-band
280-
* ad-hoc AH support
281-
*/
282-
uint32_t src_addr_3;
262+
uint8_t src_addr[16];
283263
};
284264

285265
/* tx_meta_desc */
@@ -305,6 +285,5 @@ struct efa_io_rx_cdesc_wide {
305285
#define EFA_IO_CDESC_COMMON_PHASE_MASK BIT(0)
306286
#define EFA_IO_CDESC_COMMON_Q_TYPE_MASK GENMASK(2, 1)
307287
#define EFA_IO_CDESC_COMMON_HAS_IMM_MASK BIT(3)
308-
#define EFA_IO_CDESC_COMMON_WIDE_COMPLETION_MASK BIT(4)
309288

310289
#endif /* _EFA_IO_H_ */

providers/efa/efadv.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct ibv_qp *efadv_create_qp_ex(struct ibv_context *ibvctx,
3838
enum {
3939
EFADV_DEVICE_ATTR_CAPS_RDMA_READ = 1 << 0,
4040
EFADV_DEVICE_ATTR_CAPS_RNR_RETRY = 1 << 1,
41+
EFADV_DEVICE_ATTR_CAPS_CQ_WITH_SGID = 1 << 2,
4142
};
4243

4344
struct efadv_device_attr {
@@ -67,6 +68,11 @@ int efadv_query_ah(struct ibv_ah *ibvah, struct efadv_ah_attr *attr,
6768

6869
struct efadv_cq {
6970
uint64_t comp_mask;
71+
int (*wc_read_sgid)(struct efadv_cq *efadv_cq, union ibv_gid *sgid);
72+
};
73+
74+
enum {
75+
EFADV_WC_EX_WITH_SGID = 1 << 0,
7076
};
7177

7278
struct efadv_cq_init_attr {
@@ -81,6 +87,12 @@ struct ibv_cq_ex *efadv_create_cq(struct ibv_context *ibvctx,
8187

8288
struct efadv_cq *efadv_cq_from_ibv_cq_ex(struct ibv_cq_ex *ibvcqx);
8389

90+
static inline int efadv_wc_read_sgid(struct efadv_cq *efadv_cq,
91+
union ibv_gid *sgid)
92+
{
93+
return efadv_cq->wc_read_sgid(efadv_cq, sgid);
94+
}
95+
8496
#ifdef __cplusplus
8597
}
8698
#endif

providers/efa/libefa.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ EFA_1.2 {
1717
global:
1818
efadv_cq_from_ibv_cq_ex;
1919
efadv_create_cq;
20+
efadv_wc_read_sgid;
2021
} EFA_1.1;

providers/efa/man/efadv_create_cq.3.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ struct ibv_cq_ex *efadv_create_cq(struct ibv_context *context,
2121
struct ibv_cq_init_attr_ex *attr_ex,
2222
struct efadv_cq_init_attr *efa_attr,
2323
uint32_t inlen);
24+
25+
static inline int efadv_wc_read_sgid(struct efadv_cq *efadv_cq,
26+
union ibv_gid *sgid);
2427
```
2528
2629
# DESCRIPTION
@@ -54,7 +57,17 @@ struct efadv_cq_init_attr {
5457
: Compatibility mask.
5558

5659
*wc_flags*
57-
: Required WC fields.
60+
: A bitwise OR of the various values described below.
61+
62+
EFADV_WC_EX_WITH_SGID:
63+
if source AH is unknown, require sgid in WC.
64+
65+
66+
# Completion iterator functions
67+
68+
*efadv_wc_read_sgid*
69+
: Get the source GID field from the current completion.
70+
If the AH is known, a negative error value is returned.
5871

5972

6073
# RETURN VALUE

providers/efa/man/efadv_query_device.3.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ struct efadv_device_attr {
7272
EFADV_DEVICE_ATTR_CAPS_RNR_RETRY:
7373
RNR retry is supported for SRD QPs.
7474

75+
EFADV_DEVICE_ATTR_CAPS_CQ_WITH_SGID:
76+
Reading source address (SGID) from receive completion descriptors is supported.
77+
Valid only for unknown AH.
78+
7579
*max_rdma_size*
7680
: Maximum RDMA transfer size in bytes.
7781

providers/efa/verbs.c

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ int efadv_query_device(struct ibv_context *ibvctx,
168168
if (vext_field_avail(typeof(*attr), device_caps, inlen)) {
169169
if (EFA_DEV_CAP(ctx, RNR_RETRY))
170170
attr->device_caps |= EFADV_DEVICE_ATTR_CAPS_RNR_RETRY;
171+
172+
if (EFA_DEV_CAP(ctx, CQ_WITH_SGID))
173+
attr->device_caps |= EFADV_DEVICE_ATTR_CAPS_CQ_WITH_SGID;
171174
}
172175

173176
if (vext_field_avail(typeof(*attr), max_rdma_size, inlen)) {
@@ -691,9 +694,28 @@ static uint8_t efa_wc_read_dlid_path_bits(struct ibv_cq_ex *ibvcqx)
691694
return 0;
692695
}
693696

694-
static void efa_cq_fill_pfns(struct ibv_cq_ex *ibvcqx,
695-
struct ibv_cq_init_attr_ex *attr)
697+
static int efa_wc_read_sgid(struct efadv_cq *efadv_cq, union ibv_gid *sgid)
698+
{
699+
struct efa_cq *cq = efadv_cq_to_efa_cq(efadv_cq);
700+
struct efa_io_rx_cdesc_ex *rcqex;
701+
702+
rcqex = container_of(cq->cur_cqe, struct efa_io_rx_cdesc_ex,
703+
rx_cdesc_base.common);
704+
if (rcqex->rx_cdesc_base.ah != 0xFFFF) {
705+
/* SGID is only available if AH is unknown. */
706+
return -ENOENT;
707+
}
708+
memcpy(sgid->raw, rcqex->src_addr, sizeof(sgid->raw));
709+
710+
return 0;
711+
}
712+
713+
static void efa_cq_fill_pfns(struct efa_cq *cq,
714+
struct ibv_cq_init_attr_ex *attr,
715+
struct efadv_cq_init_attr *efa_attr)
696716
{
717+
struct ibv_cq_ex *ibvcqx = &cq->verbs_cq.cq_ex;
718+
697719
ibvcqx->start_poll = efa_start_poll;
698720
ibvcqx->end_poll = efa_end_poll;
699721
ibvcqx->next_poll = efa_next_poll;
@@ -716,6 +738,9 @@ static void efa_cq_fill_pfns(struct ibv_cq_ex *ibvcqx,
716738
ibvcqx->read_sl = efa_wc_read_sl;
717739
if (attr->wc_flags & IBV_WC_EX_WITH_DLID_PATH_BITS)
718740
ibvcqx->read_dlid_path_bits = efa_wc_read_dlid_path_bits;
741+
742+
if (efa_attr && (efa_attr->wc_flags & EFADV_WC_EX_WITH_SGID))
743+
cq->dv_cq.wc_read_sgid = efa_wc_read_sgid;
719744
}
720745

721746
static void efa_sub_cq_initialize(struct efa_sub_cq *sub_cq, uint8_t *buf,
@@ -730,10 +755,12 @@ static void efa_sub_cq_initialize(struct efa_sub_cq *sub_cq, uint8_t *buf,
730755
}
731756

732757
static struct ibv_cq_ex *create_cq(struct ibv_context *ibvctx,
733-
struct ibv_cq_init_attr_ex *attr)
758+
struct ibv_cq_init_attr_ex *attr,
759+
struct efadv_cq_init_attr *efa_attr)
734760
{
735761
struct efa_context *ctx = to_efa_context(ibvctx);
736762
struct efa_create_cq_resp resp = {};
763+
uint16_t cqe_size = ctx->cqe_size;
737764
struct efa_create_cq cmd = {};
738765
uint16_t num_sub_cqs;
739766
struct efa_cq *cq;
@@ -762,9 +789,14 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *ibvctx,
762789
if (!cq)
763790
return NULL;
764791

792+
if (efa_attr && (efa_attr->wc_flags & EFADV_WC_EX_WITH_SGID)) {
793+
cmd.flags |= EFA_CREATE_CQ_WITH_SGID;
794+
cqe_size = ctx->ex_cqe_size;
795+
}
796+
765797
num_sub_cqs = ctx->sub_cqs_per_cq;
766798
cmd.num_sub_cqs = num_sub_cqs;
767-
cmd.cq_entry_size = ctx->cqe_size;
799+
cmd.cq_entry_size = cqe_size;
768800
if (attr->channel)
769801
cmd.flags |= EFA_CREATE_CQ_WITH_COMPLETION_CHANNEL;
770802

@@ -781,7 +813,7 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *ibvctx,
781813
cq->cqn = resp.cq_idx;
782814
cq->buf_size = resp.q_mmap_size;
783815
cq->num_sub_cqs = num_sub_cqs;
784-
cq->cqe_size = ctx->cqe_size;
816+
cq->cqe_size = cqe_size;
785817

786818
cq->buf = mmap(NULL, cq->buf_size, PROT_READ, MAP_SHARED,
787819
ibvctx->cmd_fd, resp.q_mmap_key);
@@ -806,7 +838,7 @@ static struct ibv_cq_ex *create_cq(struct ibv_context *ibvctx,
806838
cq->db = (uint32_t *)((uint8_t *)cq->db + resp.db_off);
807839
}
808840

809-
efa_cq_fill_pfns(&cq->verbs_cq.cq_ex, attr);
841+
efa_cq_fill_pfns(cq, attr, efa_attr);
810842
pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE);
811843

812844
return &cq->verbs_cq.cq_ex;
@@ -831,22 +863,25 @@ struct ibv_cq *efa_create_cq(struct ibv_context *ibvctx, int ncqe,
831863
};
832864
struct ibv_cq_ex *ibvcqx;
833865

834-
ibvcqx = create_cq(ibvctx, &attr_ex);
866+
ibvcqx = create_cq(ibvctx, &attr_ex, NULL);
835867

836868
return ibvcqx ? ibv_cq_ex_to_cq(ibvcqx) : NULL;
837869
}
838870

839871
struct ibv_cq_ex *efa_create_cq_ex(struct ibv_context *ibvctx,
840872
struct ibv_cq_init_attr_ex *attr_ex)
841873
{
842-
return create_cq(ibvctx, attr_ex);
874+
return create_cq(ibvctx, attr_ex, NULL);
843875
}
844876

845877
struct ibv_cq_ex *efadv_create_cq(struct ibv_context *ibvctx,
846878
struct ibv_cq_init_attr_ex *attr_ex,
847879
struct efadv_cq_init_attr *efa_attr,
848880
uint32_t inlen)
849881
{
882+
struct efa_context *ctx;
883+
uint64_t supp_wc_flags;
884+
850885
if (!is_efa_dev(ibvctx->device)) {
851886
verbs_err(verbs_get_ctx(ibvctx), "Not an EFA device\n");
852887
errno = EOPNOTSUPP;
@@ -861,14 +896,16 @@ struct ibv_cq_ex *efadv_create_cq(struct ibv_context *ibvctx,
861896
return NULL;
862897
}
863898

864-
if (efa_attr->wc_flags) {
899+
ctx = to_efa_context(ibvctx);
900+
supp_wc_flags = EFA_DEV_CAP(ctx, CQ_WITH_SGID) ? EFADV_WC_EX_WITH_SGID : 0;
901+
if (!check_comp_mask(efa_attr->wc_flags, supp_wc_flags)) {
865902
verbs_err(verbs_get_ctx(ibvctx),
866903
"Invalid EFA wc_flags[%#x]\n", efa_attr->wc_flags);
867904
errno = EOPNOTSUPP;
868905
return NULL;
869906
}
870907

871-
return create_cq(ibvctx, attr_ex);
908+
return create_cq(ibvctx, attr_ex, efa_attr);
872909
}
873910

874911
struct efadv_cq *efadv_cq_from_ibv_cq_ex(struct ibv_cq_ex *ibvcqx)

0 commit comments

Comments
 (0)