Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (C) 2016 Mellanox Technologies Ltd. All rights reserved. |
| 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. Neither the name of the copyright holder nor the names of its |
| 14 | * contributors may be used to endorse or promote products derived from |
| 15 | * this software without specific prior written permission. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 20 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 21 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
| 23 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | */ |
| 29 | #ifndef __IBVT_ENV_H_ |
| 30 | #define __IBVT_ENV_H_ |
| 31 | |
| 32 | #ifdef HAVE_CONFIG_H |
| 33 | #include "config.h" |
| 34 | #endif |
| 35 | |
| 36 | #include <inttypes.h> |
| 37 | #include <signal.h> |
Artemy Kovalyov | 36eea22 | 2017-10-04 01:27:27 +0300 | [diff] [blame] | 38 | #define __STDC_LIMIT_MACROS |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 39 | #include <stdint.h> |
| 40 | #include <stdio.h> |
| 41 | #include <stdlib.h> |
| 42 | #include <string.h> |
| 43 | #include <sys/mman.h> |
| 44 | #include <sys/time.h> |
| 45 | #include <sys/types.h> |
| 46 | #include <unistd.h> |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 47 | #include <dirent.h> |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 48 | #include <linux/limits.h> |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 49 | |
| 50 | #include <infiniband/verbs.h> |
| 51 | |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 52 | #if HAVE_INFINIBAND_VERBS_EXP_H |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 53 | #include <infiniband/verbs_exp.h> |
| 54 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 55 | #define ibv_flow_attr ibv_exp_flow_attr |
| 56 | #define ibv_flow_spec_eth ibv_exp_flow_spec_eth |
| 57 | #define ibv_flow ibv_exp_flow |
| 58 | #define ibv_flow_attr ibv_exp_flow_attr |
| 59 | #define ibv_create_flow ibv_exp_create_flow |
| 60 | #define ibv_destroy_flow ibv_exp_destroy_flow |
| 61 | #define ibv_flow_attr ibv_exp_flow_attr |
| 62 | #define ibv_flow_spec ibv_exp_flow_spec |
| 63 | #define ibv_flow_attr ibv_exp_flow_attr |
| 64 | #define ibv_flow_spec_tunnel ibv_exp_flow_spec_tunnel |
| 65 | #define ibv_flow_spec_eth ibv_exp_flow_spec_eth |
| 66 | #define ibv_flow_spec_ipv4 ibv_exp_flow_spec_ipv4 |
| 67 | #define ibv_flow_spec_tcp_udp ibv_exp_flow_spec_tcp_udp |
| 68 | #define ibv_flow_attr ibv_exp_flow_attr |
| 69 | #define IBV_FLOW_ATTR_NORMAL IBV_EXP_FLOW_ATTR_NORMAL |
| 70 | #define ibv_flow_attr ibv_exp_flow_attr |
| 71 | #define ibv_flow_spec ibv_exp_flow_spec |
| 72 | #define IBV_FLOW_SPEC_ETH IBV_EXP_FLOW_SPEC_ETH |
| 73 | #define ibv_flow_spec_eth ibv_exp_flow_spec_eth |
| 74 | #define IBV_FLOW_SPEC_IPV4 IBV_EXP_FLOW_SPEC_IPV4 |
| 75 | #define IBV_FLOW_SPEC_UDP IBV_EXP_FLOW_SPEC_UDP |
| 76 | #define IBV_FLOW_SPEC_VXLAN_TUNNEL IBV_EXP_FLOW_SPEC_VXLAN_TUNNEL |
| 77 | #define ibv_flow_spec_tunnel ibv_exp_flow_spec_tunnel |
| 78 | #define IBV_FLOW_SPEC_INNER IBV_EXP_FLOW_SPEC_INNER |
| 79 | #define ibv_flow ibv_exp_flow |
| 80 | #define ibv_flow_spec_type ibv_exp_flow_spec_type |
Moses Reuben | 06b0ac5 | 2016-12-15 11:15:09 -0500 | [diff] [blame] | 81 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 82 | #define IBV_FLOW_SPEC_ACTION_TAG IBV_EXP_FLOW_SPEC_ACTION_TAG |
| 83 | #define ibv_flow_spec_action_tag ibv_exp_flow_spec_action_tag |
Moses Reuben | 520ff65 | 2017-01-05 09:57:18 +0000 | [diff] [blame] | 84 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 85 | #define ibv_peer_commit ibv_exp_peer_commit |
| 86 | #define ibv_peer_commit_qp ibv_exp_peer_commit_qp |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 87 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 88 | #define ibv_create_qp_ex ibv_exp_create_qp |
| 89 | #define ibv_qp_init_attr_ex ibv_exp_qp_init_attr |
| 90 | #define ibv_create_cq_attr_ex ibv_exp_cq_init_attr |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 91 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 92 | #define IBV_QP_INIT_ATTR_PD IBV_EXP_QP_INIT_ATTR_PD |
| 93 | #define IBV_QP_INIT_ATTR_PEER_DIRECT IBV_EXP_QP_INIT_ATTR_PEER_DIRECT |
| 94 | #define IBV_CREATE_CQ_ATTR_PEER_DIRECT IBV_EXP_CQ_INIT_ATTR_PEER_DIRECT |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 95 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 96 | #define IBV_PEER_OP_FENCE IBV_EXP_PEER_OP_FENCE |
| 97 | #define IBV_PEER_OP_STORE_DWORD IBV_EXP_PEER_OP_STORE_DWORD |
| 98 | #define IBV_PEER_OP_STORE_QWORD IBV_EXP_PEER_OP_STORE_QWORD |
| 99 | #define IBV_PEER_OP_POLL_AND_DWORD IBV_EXP_PEER_OP_POLL_AND_DWORD |
| 100 | #define IBV_PEER_OP_POLL_NOR_DWORD IBV_EXP_PEER_OP_POLL_NOR_DWORD |
| 101 | #define IBV_PEER_OP_POLL_GEQ_DWORD IBV_EXP_PEER_OP_POLL_NOR_DWORD |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 102 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 103 | #define IBV_PEER_OP_FENCE_CAP IBV_EXP_PEER_OP_FENCE_CAP |
| 104 | #define IBV_PEER_OP_STORE_DWORD_CAP IBV_EXP_PEER_OP_STORE_DWORD_CAP |
| 105 | #define IBV_PEER_OP_STORE_QWORD_CAP IBV_EXP_PEER_OP_STORE_QWORD_CAP |
| 106 | #define IBV_PEER_OP_POLL_AND_DWORD_CAP IBV_EXP_PEER_OP_POLL_AND_DWORD_CAP |
| 107 | #define IBV_PEER_OP_POLL_NOR_DWORD_CAP IBV_EXP_PEER_OP_POLL_NOR_DWORD_CAP |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 108 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 109 | #define IBV_PEER_FENCE_CPU_TO_HCA IBV_EXP_PEER_FENCE_CPU_TO_HCA |
| 110 | #define IBV_PEER_FENCE_PEER_TO_HCA IBV_EXP_PEER_FENCE_PEER_TO_HCA |
| 111 | #define IBV_PEER_FENCE_PEER_TO_CPU IBV_EXP_PEER_FENCE_PEER_TO_CPU |
| 112 | #define IBV_PEER_FENCE_HCA_TO_PEER IBV_EXP_PEER_FENCE_HCA_TO_PEER |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 113 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 114 | #define ibv_peer_direct_attr ibv_exp_peer_direct_attr |
| 115 | #define ibv_peer_direction ibv_exp_peer_direction |
| 116 | #define ibv_peer_op ibv_exp_peer_op |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 117 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 118 | #define IBV_ROLLBACK_ABORT_UNCOMMITED IBV_EXP_ROLLBACK_ABORT_UNCOMMITED |
| 119 | #define IBV_ROLLBACK_ABORT_LATE IBV_EXP_ROLLBACK_ABORT_LATE |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 120 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 121 | #define ibv_rollback_ctx ibv_exp_rollback_ctx |
| 122 | #define ibv_rollback_qp ibv_exp_rollback_qp |
| 123 | #define ibv_peer_peek ibv_exp_peer_peek |
| 124 | #define ibv_peer_peek_cq ibv_exp_peer_peek_cq |
| 125 | #define ibv_peer_abort_peek ibv_exp_peer_abort_peek |
| 126 | #define ibv_peer_abort_peek_cq ibv_exp_peer_abort_peek_cq |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 127 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 128 | #define IBV_PEER_DIRECTION_FROM_CPU IBV_EXP_PEER_DIRECTION_FROM_CPU |
| 129 | #define IBV_PEER_DIRECTION_FROM_HCA IBV_EXP_PEER_DIRECTION_FROM_HCA |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 130 | |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 131 | #define ibv_peer_buf ibv_exp_peer_buf |
| 132 | #define ibv_peer_buf_alloc_attr ibv_exp_peer_buf_alloc_attr |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 133 | #define IBV_SEND_SIGNALED IBV_EXP_SEND_SIGNALED |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 134 | |
| 135 | #define ibv_create_cq_ex_(ctx, attr, n, ch) \ |
| 136 | ibv_exp_create_cq(ctx, n, NULL, ch, 0, attr) |
| 137 | |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 138 | #define ibv_device_attr_ex ibv_exp_device_attr |
Artemy Kovalyov | fc18a36 | 2018-12-12 10:07:23 +0200 | [diff] [blame] | 139 | #if HAVE_DECL_IBV_EXP_DEVICE_ATTR_RESERVED_2 |
| 140 | # define SET_DEVICE_ATTR_COMP_MASK(attr) \ |
| 141 | (attr)->comp_mask = 0xffffffff; \ |
| 142 | (attr)->comp_mask_2 = IBV_EXP_DEVICE_ATTR_RESERVED_2 - 1; |
| 143 | #else |
| 144 | # define SET_DEVICE_ATTR_COMP_MASK(attr) \ |
| 145 | (attr)->comp_mask = IBV_EXP_DEVICE_ATTR_RESERVED - 1; |
| 146 | #endif |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 147 | #define ibv_query_device_(ctx, attr, attr2) ({ \ |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 148 | int ret; \ |
Artemy Kovalyov | fc18a36 | 2018-12-12 10:07:23 +0200 | [diff] [blame] | 149 | SET_DEVICE_ATTR_COMP_MASK(attr) \ |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 150 | ret = ibv_exp_query_device(ctx, attr); \ |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 151 | attr2 = (typeof attr2)(attr); ret ; }) |
| 152 | |
| 153 | #define IBV_ACCESS_ON_DEMAND IBV_EXP_ACCESS_ON_DEMAND |
| 154 | |
| 155 | #define ibv_reg_mr(p, a, len, access) ({ \ |
| 156 | struct ibv_exp_reg_mr_in in; \ |
| 157 | in.pd = p; \ |
| 158 | in.addr = a; \ |
| 159 | in.length = len; \ |
| 160 | in.exp_access = access; \ |
| 161 | in.comp_mask = 0; \ |
| 162 | ibv_exp_reg_mr(&in); }) |
| 163 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 164 | |
| 165 | #define ibv_srq_init_attr_ex ibv_exp_create_srq_attr |
| 166 | #define ibv_create_srq_ex ibv_exp_create_srq |
| 167 | #define ibv_dct ibv_exp_dct |
| 168 | |
| 169 | #define IBV_WR_SEND IBV_EXP_WR_SEND |
| 170 | #define IBV_WR_RDMA_READ IBV_EXP_WR_RDMA_READ |
| 171 | #define IBV_WR_RDMA_WRITE IBV_EXP_WR_RDMA_WRITE |
| 172 | #define ibv_wr_opcode ibv_exp_wr_opcode |
| 173 | #define ibv_send_flags ibv_exp_send_flags |
| 174 | #define _wr_opcode exp_opcode |
| 175 | #define _wr_send_flags exp_send_flags |
| 176 | #define ibv_post_send ibv_exp_post_send |
| 177 | #define ibv_send_wr ibv_exp_send_wr |
| 178 | |
Artemy Kovalyov | faf40a5 | 2017-07-15 12:30:50 +0300 | [diff] [blame] | 179 | #define ibv_wc ibv_exp_wc |
| 180 | #define ibv_poll_cq(a,b,c) ibv_exp_poll_cq(a,b,c,sizeof(*(c))) |
| 181 | #define ibv_wc_opcode ibv_exp_wc_opcode |
| 182 | #define _wc_opcode exp_opcode |
| 183 | #define wc_flags exp_wc_flags |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 184 | #define IBV_ODP_SUPPORT_IMPLICIT IBV_EXP_ODP_SUPPORT_IMPLICIT |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 185 | #else |
| 186 | |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 187 | #define general_odp_caps general_caps |
| 188 | #define ibv_create_cq_attr_ex ibv_cq_init_attr_ex |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 189 | |
Artemy Kovalyov | 7f03ef9 | 2018-12-12 10:01:51 +0200 | [diff] [blame] | 190 | #if HAVE_DECL_IBV_CREATE_CQ_ATTR_IGNORE_OVERRUN |
| 191 | # define SET_IGNORE_OVERRUN(attr) \ |
| 192 | (attr)->comp_mask = IBV_CQ_INIT_ATTR_MASK_FLAGS; \ |
| 193 | (attr)->flags = IBV_CREATE_CQ_ATTR_IGNORE_OVERRUN; |
| 194 | #else |
| 195 | # define SET_IGNORE_OVERRUN(attr) |
| 196 | #endif |
| 197 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 198 | #define ibv_create_cq_ex_(ctx, attr, n, ch) ({ \ |
| 199 | (attr)->cqe = n; \ |
| 200 | (attr)->channel = ch; \ |
Artemy Kovalyov | de0c6c1 | 2017-03-07 14:46:25 +0200 | [diff] [blame] | 201 | (attr)->wc_flags = IBV_CREATE_CQ_SUP_WC_FLAGS; \ |
Artemy Kovalyov | 7f03ef9 | 2018-12-12 10:01:51 +0200 | [diff] [blame] | 202 | SET_IGNORE_OVERRUN(attr) \ |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 203 | ibv_cq_ex_to_cq(ibv_create_cq_ex(ctx, attr)); }) |
| 204 | |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 205 | #define ibv_query_device_(ctx, attr, attr2) ({ \ |
| 206 | int ret = ibv_query_device_ex(ctx, NULL, attr); \ |
| 207 | attr2 = &(attr)->orig_attr; ret ; }) |
| 208 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 209 | #define _wr_opcode opcode |
| 210 | #define _wr_send_flags send_flags |
Artemy Kovalyov | faf40a5 | 2017-07-15 12:30:50 +0300 | [diff] [blame] | 211 | #define _wc_opcode opcode |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 212 | //#define IBV_ODP_SUPPORT_IMPLICIT 2 pending kernel fix |
| 213 | #define IBV_ODP_SUPPORT_IMPLICIT 0 |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 214 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 215 | #endif |
| 216 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 217 | #if HAVE_INFINIBAND_MLX5DV_H |
| 218 | extern "C" { |
| 219 | #include <infiniband/mlx5dv.h> |
| 220 | } |
| 221 | #endif |
| 222 | |
Artemy Kovalyov | 67cef55 | 2017-09-27 09:01:02 +0300 | [diff] [blame] | 223 | #ifdef __x86_64__ |
| 224 | |
| 225 | #define PAGE 0x1000 |
| 226 | #define UP (1ULL<<47) |
| 227 | |
| 228 | #elif (__ppc64__|__PPC64__) |
| 229 | |
| 230 | #define PAGE 0x10000 |
| 231 | #define UP (1ULL<<46) |
| 232 | |
Artemy Kovalyov | 2423985 | 2018-11-08 10:56:15 +0200 | [diff] [blame] | 233 | #elif __aarch64__ |
| 234 | |
| 235 | #define PAGE 0x1000 |
| 236 | #define UP (1ULL<<47) |
| 237 | |
| 238 | #else |
| 239 | |
| 240 | #error Unknown architecture |
| 241 | |
Artemy Kovalyov | 67cef55 | 2017-09-27 09:01:02 +0300 | [diff] [blame] | 242 | #endif |
| 243 | |
| 244 | #define PAGE_MASK (PAGE - 1) |
| 245 | #define PAGE_ALIGN(x) ((x) & ~PAGE_MASK) |
| 246 | #define PAGE_UPALIGN(x) (((x) + PAGE_MASK) & ~PAGE_MASK) |
| 247 | |
| 248 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 249 | #include "common.h" |
| 250 | |
| 251 | #define EXEC(x) do { \ |
| 252 | VERBS_TRACE("%3d.%p: execute\t%s" #x "\n", __LINE__, this, this->env.lvl_str); \ |
| 253 | this->env.lvl_str[this->env.lvl++] = ' '; \ |
| 254 | ASSERT_NO_FATAL_FAILURE(this->x); \ |
| 255 | this->env.lvl_str[--this->env.lvl] = 0; \ |
| 256 | } while(0) |
| 257 | |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 258 | #define INIT(x) do { \ |
| 259 | if (!this->env.skip) { \ |
| 260 | VERBS_TRACE("%3d.%p: initialize\t%s" #x "\n", __LINE__, this, this->env.lvl_str); \ |
| 261 | this->env.lvl_str[this->env.lvl++] = ' '; \ |
| 262 | EXPECT_NO_FATAL_FAILURE(this->x); \ |
| 263 | this->env.lvl_str[--this->env.lvl] = 0; \ |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 264 | if (this->env.skip) { \ |
| 265 | VERBS_TRACE("%3d.%p: failed\t%s" #x " - skipping test\n", __LINE__, this, this->env.lvl_str); \ |
| 266 | return; \ |
| 267 | } \ |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 268 | } \ |
| 269 | } while(0) |
| 270 | |
Artemy Kovalyov | 062c3ef | 2016-08-29 11:14:47 +0300 | [diff] [blame] | 271 | #define EXECL(x) do { \ |
| 272 | VERBS_TRACE("%3d.%p: execute\t%s" #x "\n", __LINE__, this, this->env.lvl_str); \ |
| 273 | this->env.lvl_str[this->env.lvl++] = ' '; \ |
| 274 | ASSERT_NO_FATAL_FAILURE(x); \ |
| 275 | this->env.lvl_str[--this->env.lvl] = 0; \ |
| 276 | } while(0) |
| 277 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 278 | #define DO(x) do { \ |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 279 | VERBS_TRACE("%3d.%p: doing\t%s" #x "\n", __LINE__, this, this->env.lvl_str); \ |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 280 | if (this->env.run) \ |
| 281 | ASSERT_EQ(0, x) << "errno: " << errno; \ |
| 282 | else if (x) { \ |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 283 | VERBS_NOTICE("%3d.%p: failed\t%s" #x " - skipping test (errno %d)\n", __LINE__, this, this->env.lvl_str, errno); \ |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 284 | this->env.skip = 1; \ |
| 285 | return; \ |
| 286 | } \ |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 287 | } while(0) |
| 288 | |
| 289 | #define SET(x,y) do { \ |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 290 | VERBS_TRACE("%3d.%p: doing\t%s" #y "\n", __LINE__, this, this->env.lvl_str); \ |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 291 | x=y; \ |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 292 | if (this->env.run) \ |
| 293 | ASSERT_TRUE(x) << #y << " errno: " << errno; \ |
| 294 | else if (!x) { \ |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 295 | VERBS_NOTICE("%3d.%p: failed\t%s" #y " - skipping test (errno %d)\n", __LINE__, this, this->env.lvl_str, errno); \ |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 296 | this->env.skip = 1; \ |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 297 | return; \ |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 298 | } \ |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 299 | } while(0) |
| 300 | |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 301 | #define SKIP(report) do { \ |
| 302 | ::testing::UnitTest::GetInstance()->runtime_skip(report); \ |
| 303 | return; \ |
Artemy Kovalyov | e69018f | 2016-11-17 16:17:29 +0200 | [diff] [blame] | 304 | } while(0) |
| 305 | |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 306 | |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 307 | #define CHK_SUT(FEATURE_NAME) \ |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 308 | do { \ |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 309 | if (this->skip) { \ |
Artemy Kovalyov | e69018f | 2016-11-17 16:17:29 +0200 | [diff] [blame] | 310 | std::cout << "[ SKIPPED ] Feature " << #FEATURE_NAME << " lacks resources to be tested" << std::endl; \ |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 311 | SKIP(1); \ |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 312 | } \ |
| 313 | this->run = 1; \ |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 314 | } while(0); |
| 315 | |
Artemy Kovalyov | e69018f | 2016-11-17 16:17:29 +0200 | [diff] [blame] | 316 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 317 | #define FREE(x,y) do { \ |
| 318 | if (y) { \ |
| 319 | VERBS_TRACE("%3d.%p: freeing\t%s" #x "\n", __LINE__, this, env.lvl_str); \ |
| 320 | if (x(y)) { \ |
| 321 | ADD_FAILURE() << "errno: " << errno; \ |
| 322 | env.fatality = 1; \ |
| 323 | } \ |
| 324 | y = NULL; \ |
| 325 | } \ |
| 326 | } while(0) |
| 327 | |
Artemy Kovalyov | 0d95372 | 2017-07-15 12:36:17 +0300 | [diff] [blame] | 328 | #ifdef PALLADIUM |
| 329 | #define POLL_RETRIES 8000000000ULL |
| 330 | #else |
| 331 | #define POLL_RETRIES 80000000ULL |
| 332 | #endif |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 333 | |
| 334 | #define ACTIVE (1 << 0) |
| 335 | |
| 336 | #define Q_KEY 0x11111111 |
| 337 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 338 | #define DC_KEY 1 |
| 339 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 340 | static void hexdump(const char *pfx, void *buff, size_t len) __attribute__ ((unused)); |
| 341 | static void hexdump(const char *pfx, void *buff, size_t len) { |
| 342 | unsigned char *p = (unsigned char*)buff, *end = (unsigned char*)buff + len, c; |
| 343 | |
| 344 | while(p < end) { |
| 345 | printf("%4s %p: ", pfx, p /*- (unsigned char *)buff*/); |
| 346 | for (c=0; c<16; c++) |
| 347 | printf( p+c < end ? "%02x " : " ", p[c]); |
| 348 | for (c=0; c<16; c++) |
| 349 | printf( p+c < end ? "%c" : " ", p[c] >= 32 && p[c] < 128 ? p[c] : '.'); |
| 350 | p += 16; |
| 351 | printf("\n"); |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | struct ibvt_env { |
| 356 | ibvt_env &env; |
| 357 | char lvl_str[256]; |
| 358 | int lvl; |
| 359 | int skip; |
| 360 | int fatality; |
| 361 | int flags; |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 362 | int run; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 363 | |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 364 | char meminfo[8192]; |
| 365 | int ram_init; |
| 366 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 367 | struct ibv_send_wr *wr_list; |
| 368 | struct ibv_send_wr *wr_list_end; |
| 369 | |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 370 | void init_ram() { |
| 371 | int fd = open("/proc/meminfo", O_RDONLY); |
| 372 | ASSERT_GT(fd, 0); |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 373 | ASSERT_GT(read(fd, meminfo, sizeof(meminfo)), 0); |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 374 | close(fd); |
| 375 | ram_init = 1; |
| 376 | } |
| 377 | |
| 378 | void check_ram(const char* var, long val) { |
| 379 | if (!ram_init) |
| 380 | ASSERT_NO_FATAL_FAILURE(init_ram()); |
| 381 | char *hit = strstr(meminfo, var); |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 382 | ASSERT_TRUE(hit) << var; |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 383 | if ((val >> 10) > atoi(hit + strlen(var))) { |
| 384 | VERBS_NOTICE("%smeminfo %s is lower than %ld - skipping test\n", |
| 385 | lvl_str, var, val >> 10); |
| 386 | skip = 1; |
| 387 | } |
| 388 | } |
| 389 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 390 | virtual void add_wr(ibv_send_wr *wr) { |
| 391 | if (wr_list) |
| 392 | wr_list_end->next = wr; |
| 393 | else |
| 394 | wr_list = wr; |
| 395 | wr_list_end = wr; |
| 396 | } |
| 397 | |
| 398 | virtual void free_wr() { |
| 399 | while (wr_list) { |
| 400 | struct ibv_send_wr *wr = wr_list; |
| 401 | wr_list = wr_list->next; |
| 402 | free(wr); |
| 403 | } |
| 404 | } |
| 405 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 406 | ibvt_env() : |
| 407 | env(*this), |
| 408 | lvl(0), |
| 409 | skip(0), |
| 410 | fatality(0), |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 411 | flags(ACTIVE), |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 412 | run(0), |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 413 | ram_init(0), |
| 414 | wr_list(NULL) |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 415 | { |
| 416 | memset(lvl_str, 0, sizeof(lvl_str)); |
| 417 | } |
| 418 | }; |
| 419 | |
| 420 | struct ibvt_obj { |
| 421 | ibvt_env &env; |
| 422 | |
| 423 | ibvt_obj(ibvt_env &e) : env(e) { } |
| 424 | |
| 425 | virtual void init() = 0; |
| 426 | }; |
| 427 | |
| 428 | struct ibvt_ctx : public ibvt_obj { |
| 429 | struct ibv_context *ctx; |
| 430 | ibvt_ctx *other; |
| 431 | struct ibv_device *dev; |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 432 | struct ibv_device_attr *dev_attr_orig; |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 433 | struct ibv_device_attr_ex dev_attr; |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 434 | struct ibv_port_attr port_attr; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 435 | uint8_t port_num; |
| 436 | uint16_t lid; |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 437 | union ibv_gid gid; |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 438 | char *pdev_name; |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 439 | char *vdev_name; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 440 | |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 441 | #if HAVE_INFINIBAND_VERBS_EXP_H |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 442 | |
| 443 | #define DEV_FS "/sys/class/infiniband_verbs" |
| 444 | #define DEBUGFS "/sys/kernel/debug/mlx5" |
| 445 | |
| 446 | void init_sysfs() { |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 447 | char path[PATH_MAX]; |
| 448 | char pdev[PATH_MAX], *p = pdev, *tok; |
| 449 | struct stat st; |
| 450 | |
| 451 | sprintf(path, "/sys/class/infiniband/%s", ibv_get_device_name(dev)); |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 452 | if (readlink(path, pdev, PATH_MAX) <= 0) |
| 453 | return; |
| 454 | |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 455 | while ((tok = strsep(&p, "/"))) { |
| 456 | if (tok[0] == '.') |
| 457 | continue; |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 458 | sprintf(path, DEBUGFS "/%s", tok); |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 459 | if (stat(path, &st) == 0) { |
| 460 | pdev_name = strdup(tok); |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 461 | break; |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 462 | } |
| 463 | } |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 464 | |
| 465 | DIR *verbs = opendir(DEV_FS); |
| 466 | struct dirent *d; |
| 467 | char buff[PATH_MAX]; |
| 468 | int fd, len; |
| 469 | |
| 470 | while ((d = readdir(verbs))) { |
| 471 | sprintf(path, DEV_FS "/%s/ibdev", |
| 472 | d->d_name); |
| 473 | fd = open(path, O_RDONLY); |
| 474 | if (fd < 0) |
| 475 | continue; |
| 476 | len = read(fd, buff, sizeof(buff)); |
| 477 | close(fd); |
| 478 | buff[len-1] = 0; |
| 479 | if (!strcmp(buff, ibv_get_device_name(dev))) { |
| 480 | vdev_name = strdup(d->d_name); |
| 481 | break; |
| 482 | } |
| 483 | } |
| 484 | closedir(verbs); |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 485 | } |
| 486 | |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 487 | int read_sysfs(const char* dir, char* dev_name, const char* var) { |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 488 | char path[PATH_MAX]; |
| 489 | char buff[PATH_MAX]; |
| 490 | int fd; |
| 491 | |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 492 | sprintf(path, "%s/%s/%s", dir, dev_name, var); |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 493 | fd = open(path, O_RDONLY); |
| 494 | |
| 495 | if (fd < 0) |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 496 | return -1; |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 497 | if (read(fd, buff, sizeof(buff)) <= 0) { |
| 498 | close(fd); |
| 499 | return -1; |
| 500 | } |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 501 | close(fd); |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 502 | return atoi(buff); |
Artemy Kovalyov | 207d074 | 2016-09-13 12:54:47 +0300 | [diff] [blame] | 503 | } |
| 504 | |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 505 | void check_debugfs(const char* var, int val) { |
| 506 | if (!pdev_name) |
| 507 | return; |
| 508 | int val_fs = read_sysfs(DEBUGFS, pdev_name, var); |
| 509 | VERBS_INFO("%3d.%p: debugfs\t%s %s = %d\n", __LINE__, |
| 510 | this, env.lvl_str, var, val_fs); |
| 511 | ASSERT_GE(val_fs, val) << var; |
| 512 | } |
| 513 | |
| 514 | void read_dev_fs(const char* var, int* val) { |
| 515 | if (!vdev_name) |
| 516 | return; |
| 517 | *val = read_sysfs(DEV_FS, vdev_name, var); |
| 518 | VERBS_INFO("%3d.%p: dev fs\t%s %s = %d\n", __LINE__, |
| 519 | this, env.lvl_str, var, *val); |
| 520 | } |
| 521 | |
| 522 | void check_dev_fs(const char* var, int val) { |
| 523 | if (!vdev_name) |
| 524 | return; |
| 525 | int val_fs = read_sysfs(DEV_FS, vdev_name, var); |
| 526 | VERBS_INFO("%3d.%p: dev fs\t%s %s = %d\n", __LINE__, |
| 527 | this, env.lvl_str, var, val_fs); |
| 528 | ASSERT_GE(val_fs, val) << var; |
| 529 | } |
| 530 | #else |
| 531 | void init_sysfs() {} |
| 532 | void check_debugfs(const char* var, int val) {} |
| 533 | void read_dev_fs(const char* var, int* val) {} |
| 534 | void check_dev_fs(const char* var, int val) {} |
| 535 | #endif |
| 536 | |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 537 | ibvt_ctx(ibvt_env &e, ibvt_ctx *o = NULL) : |
| 538 | ibvt_obj(e), |
| 539 | ctx(NULL), |
| 540 | other(o), |
| 541 | port_num(0), |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 542 | pdev_name(NULL), |
| 543 | vdev_name(NULL) {} |
Artemy-Mellanox | 409fabc | 2017-02-19 00:32:51 +0200 | [diff] [blame] | 544 | |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 545 | virtual bool check_port(struct ibv_device *dev) { |
Artemy Kovalyov | 218e2c6 | 2017-02-13 13:40:06 +0200 | [diff] [blame] | 546 | if (getenv("IBV_DEV") && strcmp(ibv_get_device_name(dev), getenv("IBV_DEV"))) |
Artemy Kovalyov | a36c8fe | 2017-01-23 21:45:45 +0200 | [diff] [blame] | 547 | return false; |
| 548 | if (port_attr.state == IBV_PORT_ACTIVE) |
| 549 | return true; |
Moses Reuben | 06b0ac5 | 2016-12-15 11:15:09 -0500 | [diff] [blame] | 550 | return false; |
| 551 | } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 552 | |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 553 | |
| 554 | int grh_required() { |
| 555 | return port_attr.link_layer == IBV_LINK_LAYER_ETHERNET; |
| 556 | } |
| 557 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 558 | virtual ibv_context *open_device(struct ibv_device *ibdev) { |
| 559 | return ibv_open_device(ibdev); |
| 560 | } |
| 561 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 562 | virtual void init() { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 563 | struct ibv_device **dev_list = NULL; |
| 564 | int num_devices; |
| 565 | if (ctx) |
| 566 | return; |
| 567 | |
| 568 | dev_list = ibv_get_device_list(&num_devices); |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 569 | for (int devn = 0; devn < num_devices; devn++) { |
| 570 | if (other && other->dev == dev_list[devn]) |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 571 | continue; |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 572 | SET(ctx, open_device(dev_list[devn])); |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 573 | memset(&dev_attr, 0, sizeof(dev_attr)); |
| 574 | DO(ibv_query_device_(ctx, &dev_attr, dev_attr_orig)); |
| 575 | for (int port = 1; port <= dev_attr_orig->phys_port_cnt; port++) { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 576 | DO(ibv_query_port(ctx, port, &port_attr)); |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 577 | if (!check_port(dev_list[devn])) |
Moses Reuben | 06b0ac5 | 2016-12-15 11:15:09 -0500 | [diff] [blame] | 578 | continue; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 579 | |
| 580 | port_num = port; |
| 581 | lid = port_attr.lid; |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 582 | DO(ibv_query_gid(ctx, port_num, 0, &gid)); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 583 | break; |
| 584 | } |
| 585 | if (port_num) { |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 586 | dev = dev_list[devn]; |
| 587 | VERBS_INFO("dev %s\n", ibv_get_device_name(dev)); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 588 | break; |
| 589 | } else { |
| 590 | DO(ibv_close_device(ctx)); |
Artemy Kovalyov | 5070fdf | 2016-09-07 16:31:34 +0300 | [diff] [blame] | 591 | ctx = NULL; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 592 | } |
| 593 | } |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 594 | if (dev_list) |
| 595 | ibv_free_device_list(dev_list); |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 596 | if (!port_num) { |
| 597 | VERBS_NOTICE("suitable port not found\n"); |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 598 | env.skip = 1; |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 599 | } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 600 | } |
| 601 | |
| 602 | virtual ~ibvt_ctx() { |
| 603 | FREE(ibv_close_device, ctx); |
| 604 | } |
| 605 | }; |
| 606 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 607 | #if HAVE_DECL_MLX5DV_CONTEXT_FLAGS_DEVX |
| 608 | struct ibvt_ctx_devx : public ibvt_ctx { |
| 609 | ibvt_ctx_devx(ibvt_env &e, ibvt_ctx *o = NULL) : |
| 610 | ibvt_ctx(e, o) {} |
| 611 | |
| 612 | virtual ibv_context *open_device(struct ibv_device *ibdev) { |
| 613 | struct ibv_context *res; |
| 614 | struct mlx5dv_context_attr dv_attr = {}; |
| 615 | |
| 616 | dv_attr.flags |= MLX5DV_CONTEXT_FLAGS_DEVX; |
| 617 | res = mlx5dv_open_device(ibdev, &dv_attr); |
| 618 | |
| 619 | return res; |
| 620 | } |
| 621 | }; |
| 622 | #endif |
| 623 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 624 | struct ibvt_pd : public ibvt_obj { |
| 625 | struct ibv_pd *pd; |
| 626 | ibvt_ctx &ctx; |
| 627 | |
| 628 | ibvt_pd(ibvt_env &e, ibvt_ctx &c) : ibvt_obj(e), pd(NULL), ctx(c) {} |
| 629 | |
| 630 | virtual void init() { |
| 631 | if (pd) |
| 632 | return; |
| 633 | EXEC(ctx.init()); |
| 634 | SET(pd, ibv_alloc_pd(ctx.ctx)); |
| 635 | } |
| 636 | |
| 637 | virtual ~ibvt_pd() { |
| 638 | FREE(ibv_dealloc_pd, pd); |
| 639 | } |
| 640 | }; |
| 641 | |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 642 | struct ibvt_cq; |
| 643 | |
| 644 | struct ibvt_wc { |
| 645 | struct ibv_wc wc; |
| 646 | ibvt_cq &cq; |
| 647 | |
| 648 | struct ibv_wc operator()() { |
| 649 | return wc; |
| 650 | } |
| 651 | |
| 652 | ibvt_wc(ibvt_cq &c) : cq(c) { |
| 653 | memset(&wc, 0, sizeof(wc)); |
| 654 | } |
| 655 | |
| 656 | virtual ~ibvt_wc() ; |
| 657 | }; |
| 658 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 659 | struct ibvt_cq : public ibvt_obj { |
| 660 | struct ibv_cq *cq; |
| 661 | ibvt_ctx &ctx; |
| 662 | |
| 663 | ibvt_cq(ibvt_env &e, ibvt_ctx &c) : ibvt_obj(e), cq(NULL), ctx(c) {} |
| 664 | |
| 665 | virtual void init_attr(struct ibv_create_cq_attr_ex &attr, int &cqe) { |
| 666 | memset(&attr, 0, sizeof(attr)); |
Artemy Kovalyov | 8b8ef17 | 2017-02-13 13:46:22 +0000 | [diff] [blame] | 667 | cqe = 0x1000; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 668 | } |
| 669 | |
| 670 | virtual void init() { |
| 671 | struct ibv_create_cq_attr_ex attr; |
| 672 | int cqe; |
| 673 | if (cq) |
| 674 | return; |
| 675 | EXEC(ctx.init()); |
| 676 | init_attr(attr, cqe); |
| 677 | SET(cq, ibv_create_cq_ex_(ctx.ctx, &attr, cqe, NULL)); |
| 678 | } |
| 679 | |
| 680 | virtual ~ibvt_cq() { |
| 681 | FREE(ibv_destroy_cq, cq); |
| 682 | } |
| 683 | |
| 684 | virtual void arm() {} |
| 685 | |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 686 | virtual void poll() { |
| 687 | ibvt_wc wc(*this); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 688 | |
| 689 | VERBS_TRACE("%d.%p polling...\n", __LINE__, this); |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 690 | EXEC(do_poll(wc)); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 691 | |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 692 | VERBS_TRACE("poll status %s(%d) opcode %d len %d qp %x lid %x flags %lx\n", |
| 693 | ibv_wc_status_str(wc().status), |
| 694 | wc().status, wc()._wc_opcode, |
| 695 | wc().byte_len, wc().qp_num, |
| 696 | wc().slid, (uint64_t)wc().wc_flags); |
| 697 | //if (wc().status) getchar(); |
| 698 | ASSERT_FALSE(wc().status) << ibv_wc_status_str(wc().status); |
| 699 | } |
| 700 | |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 701 | #if HAVE_INFINIBAND_VERBS_EXP_H |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 702 | virtual void do_poll(struct ibvt_wc &wc) { |
| 703 | long result = 0, retries = POLL_RETRIES; |
Artemy Kovalyov | 8d83098 | 2017-03-09 12:22:04 +0200 | [diff] [blame] | 704 | errno = 0; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 705 | while (!result && --retries) { |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 706 | result = ibv_poll_cq(cq, 1, &wc.wc); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 707 | ASSERT_GE(result,0); |
| 708 | } |
| 709 | ASSERT_GT(retries,0) << "errno: " << errno; |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 710 | } |
| 711 | #else |
| 712 | struct ibv_cq_ex *cq2() { |
| 713 | return (struct ibv_cq_ex *)this->cq; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 714 | } |
Artemy Kovalyov | faf40a5 | 2017-07-15 12:30:50 +0300 | [diff] [blame] | 715 | |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 716 | virtual void do_poll(struct ibvt_wc &wc) { |
| 717 | long result = 0, retries = POLL_RETRIES; |
| 718 | struct ibv_poll_cq_attr attr = {}; |
| 719 | |
| 720 | errno = 0; |
| 721 | while (--retries) { |
| 722 | result = ibv_start_poll(cq2(), &attr); |
| 723 | if (!result) |
| 724 | break; |
| 725 | ASSERT_EQ(ENOENT, result); |
| 726 | } |
| 727 | ASSERT_GT(retries,0) << "errno: " << errno; |
| 728 | |
| 729 | wc.wc.status = cq2()->status; |
| 730 | wc.wc.wr_id = cq2()->wr_id; |
| 731 | wc.wc.opcode = ibv_wc_read_opcode(cq2()); |
| 732 | wc.wc.wc_flags = ibv_wc_read_wc_flags(cq2()); |
| 733 | wc.wc.byte_len = ibv_wc_read_byte_len(cq2()); |
| 734 | wc.wc.slid = ibv_wc_read_slid(cq2()); |
| 735 | wc.wc.qp_num = ibv_wc_read_qp_num(cq2()); |
| 736 | |
| 737 | } |
| 738 | #endif |
Moses Reuben | 06b0ac5 | 2016-12-15 11:15:09 -0500 | [diff] [blame] | 739 | virtual void poll_arrive(int n) { |
| 740 | struct ibv_wc wc[n]; |
Artemy Kovalyov | 0d95372 | 2017-07-15 12:36:17 +0300 | [diff] [blame] | 741 | long result = 0, retries = POLL_RETRIES; |
Moses Reuben | 06b0ac5 | 2016-12-15 11:15:09 -0500 | [diff] [blame] | 742 | |
| 743 | VERBS_TRACE("%d.%p polling...\n", __LINE__, this); |
| 744 | |
| 745 | while (!result && --retries) { |
| 746 | result = ibv_poll_cq(cq, n, wc); |
| 747 | ASSERT_GE(result,0); |
| 748 | } |
| 749 | ASSERT_EQ(result,0) << "errno: " << errno; |
| 750 | |
| 751 | } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 752 | }; |
| 753 | |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 754 | inline ibvt_wc::~ibvt_wc() { |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 755 | #if !HAVE_INFINIBAND_VERBS_EXP_H |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 756 | ibv_end_poll(cq.cq2()); |
| 757 | #endif |
| 758 | } |
| 759 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 760 | struct ibvt_cq_event : public ibvt_cq { |
| 761 | struct ibv_comp_channel *channel; |
| 762 | int num_cq_events; |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 763 | int solicited_only; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 764 | |
Artemy Kovalyov | b78f6de | 2016-08-30 17:41:21 +0300 | [diff] [blame] | 765 | ibvt_cq_event(ibvt_env &e, ibvt_ctx &c) : |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 766 | ibvt_cq(e, c), |
| 767 | channel(NULL), |
| 768 | num_cq_events(0), |
| 769 | solicited_only(0) {} |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 770 | |
| 771 | virtual void init() { |
| 772 | struct ibv_create_cq_attr_ex attr; |
| 773 | int cqe; |
| 774 | if (cq) |
| 775 | return; |
| 776 | EXEC(ctx.init()); |
| 777 | SET(channel, ibv_create_comp_channel(ctx.ctx)); |
| 778 | init_attr(attr, cqe); |
| 779 | SET(cq, ibv_create_cq_ex_(ctx.ctx, &attr, cqe, channel)); |
| 780 | } |
| 781 | |
| 782 | virtual ~ibvt_cq_event() { |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 783 | if (num_cq_events) |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 784 | ibv_ack_cq_events(cq, num_cq_events); |
| 785 | FREE(ibv_destroy_cq, cq); |
| 786 | FREE(ibv_destroy_comp_channel, channel); |
| 787 | } |
| 788 | |
| 789 | virtual void arm() { |
| 790 | num_cq_events = 0; |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 791 | DO(ibv_req_notify_cq(cq, solicited_only)); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 792 | } |
| 793 | |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 794 | virtual void do_poll(struct ibvt_wc &wc) { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 795 | struct ibv_cq *ev_cq; |
| 796 | void *ev_ctx; |
| 797 | |
| 798 | DO(ibv_get_cq_event(channel, &ev_cq, &ev_ctx)); |
| 799 | ASSERT_EQ(ev_cq, cq); |
| 800 | num_cq_events++; |
Artemy Kovalyov | 3acead4 | 2017-09-27 09:07:49 +0300 | [diff] [blame] | 801 | DO(ibv_req_notify_cq(cq, solicited_only)); |
| 802 | EXEC(ibvt_cq::do_poll(wc)); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 803 | } |
| 804 | }; |
| 805 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 806 | struct ibvt_abstract_mr : public ibvt_obj { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 807 | size_t size; |
Artemy Kovalyov | e69018f | 2016-11-17 16:17:29 +0200 | [diff] [blame] | 808 | intptr_t addr; |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 809 | char *buff; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 810 | |
Artemy Kovalyov | 67cef55 | 2017-09-27 09:01:02 +0300 | [diff] [blame] | 811 | char *mem; |
| 812 | size_t mem_size; |
| 813 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 814 | ibvt_abstract_mr(ibvt_env &e, size_t s, intptr_t a) : |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 815 | ibvt_obj(e), |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 816 | size(s), |
Artemy Kovalyov | e69018f | 2016-11-17 16:17:29 +0200 | [diff] [blame] | 817 | addr(a), |
Artemy Kovalyov | b58b1c0 | 2017-10-30 14:33:00 +0200 | [diff] [blame] | 818 | buff(NULL), |
| 819 | mem(NULL) {} |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 820 | |
Artemy Kovalyov | a36c8fe | 2017-01-23 21:45:45 +0200 | [diff] [blame] | 821 | virtual int mmap_flags() { |
| 822 | return MAP_PRIVATE|MAP_ANON; |
| 823 | } |
| 824 | |
Artemy Kovalyov | 67cef55 | 2017-09-27 09:01:02 +0300 | [diff] [blame] | 825 | virtual void init_mmap() { |
Artemy Kovalyov | a36c8fe | 2017-01-23 21:45:45 +0200 | [diff] [blame] | 826 | int flags = mmap_flags(); |
Artemy Kovalyov | 67cef55 | 2017-09-27 09:01:02 +0300 | [diff] [blame] | 827 | if (addr) { |
| 828 | flags |= MAP_FIXED; |
| 829 | mem_size = PAGE_UPALIGN(size + (addr & PAGE_MASK)); |
| 830 | } else { |
| 831 | mem_size = size; |
| 832 | } |
| 833 | |
| 834 | mem = (char*)mmap((void*)PAGE_ALIGN(addr), |
| 835 | mem_size, PROT_READ|PROT_WRITE, |
| 836 | flags, -1, 0); |
| 837 | ASSERT_NE(mem, MAP_FAILED); |
| 838 | |
| 839 | buff = addr ? (char*)addr : mem; |
| 840 | } |
| 841 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 842 | virtual ~ibvt_abstract_mr() { |
Artemy Kovalyov | b58b1c0 | 2017-10-30 14:33:00 +0200 | [diff] [blame] | 843 | if (mem && mem != MAP_FAILED) |
| 844 | munmap(mem, mem_size); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 845 | } |
| 846 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 847 | virtual uint32_t lkey() = 0; |
| 848 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 849 | virtual void fill() { |
| 850 | EXEC(init()); |
| 851 | for (size_t i = 0; i < size; i++) |
| 852 | buff[i] = i & 0xff; |
| 853 | } |
| 854 | |
Artemy Kovalyov | 0fdd2ef | 2018-07-16 15:50:14 +0000 | [diff] [blame] | 855 | virtual void check(size_t skip = 0, size_t shift = 0, int repeat = 1, size_t length = 0) { |
Artemy Kovalyov | 179ad63 | 2018-04-28 20:12:16 +0000 | [diff] [blame] | 856 | if (!length) |
| 857 | length = size; |
Artemy Kovalyov | e5c9366 | 2017-01-30 17:17:22 +0200 | [diff] [blame] | 858 | for (int n = 0; n < repeat; n++) |
Artemy Kovalyov | 179ad63 | 2018-04-28 20:12:16 +0000 | [diff] [blame] | 859 | for (size_t i = skip + n * (length / repeat); i < length / repeat - shift; i++) |
Artemy Kovalyov | e5c9366 | 2017-01-30 17:17:22 +0200 | [diff] [blame] | 860 | ASSERT_EQ((char)((i + shift) & 0xff), buff[i]) << "i=" << i; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 861 | memset(buff, 0, size); |
| 862 | } |
| 863 | |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 864 | virtual void dump(size_t offset = 0, |
| 865 | size_t length = 0, |
| 866 | const char *pfx = "") { |
| 867 | hexdump(pfx, buff + offset, length ?: size); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 868 | } |
| 869 | |
Artemy Kovalyov | fc636ed | 2016-11-27 13:16:39 +0200 | [diff] [blame] | 870 | virtual struct ibv_sge sge(intptr_t start, size_t length) { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 871 | struct ibv_sge ret; |
| 872 | |
| 873 | memset(&ret, 0, sizeof(ret)); |
Artemy Kovalyov | fc636ed | 2016-11-27 13:16:39 +0200 | [diff] [blame] | 874 | ret.addr = (intptr_t)buff + start; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 875 | ret.length = length; |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 876 | ret.lkey = lkey(); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 877 | |
| 878 | return ret; |
| 879 | } |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 880 | |
| 881 | virtual struct ibv_sge sge() { return sge(0, size); } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 882 | }; |
| 883 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 884 | struct ibvt_mr : public ibvt_abstract_mr { |
| 885 | ibvt_pd &pd; |
| 886 | long access_flags; |
| 887 | struct ibv_mr *mr; |
| 888 | |
| 889 | ibvt_mr(ibvt_env &e, ibvt_pd &p, size_t s, intptr_t a = 0, |
| 890 | long af = IBV_ACCESS_LOCAL_WRITE | |
| 891 | IBV_ACCESS_REMOTE_READ | |
| 892 | IBV_ACCESS_REMOTE_WRITE) : |
| 893 | ibvt_abstract_mr(e, s, a), pd(p), access_flags(af), mr(NULL) {} |
| 894 | |
| 895 | virtual void init() { |
| 896 | if (mr) |
| 897 | return; |
| 898 | EXEC(pd.init()); |
| 899 | EXEC(init_mmap()); |
| 900 | SET(mr, ibv_reg_mr(pd.pd, buff, size, access_flags)); |
| 901 | VERBS_TRACE("\t\t\t\tibv_reg_mr(pd, %p, %zx, %lx) = %x\n", buff, size, access_flags, mr->lkey); |
| 902 | } |
| 903 | |
| 904 | virtual uint32_t lkey() { |
| 905 | return mr->lkey; |
| 906 | } |
| 907 | |
| 908 | virtual ~ibvt_mr() { |
| 909 | FREE(ibv_dereg_mr, mr); |
| 910 | } |
| 911 | }; |
| 912 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 913 | struct ibvt_srq : public ibvt_obj { |
| 914 | struct ibv_srq *srq; |
| 915 | |
| 916 | ibvt_pd &pd; |
| 917 | ibvt_cq &cq; |
| 918 | |
| 919 | ibvt_srq(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) : |
| 920 | ibvt_obj(e), srq(NULL), pd(p), cq(c) {} |
| 921 | |
| 922 | ~ibvt_srq() { |
| 923 | FREE(ibv_destroy_srq, srq); |
| 924 | } |
| 925 | |
| 926 | virtual void init_attr(struct ibv_srq_init_attr_ex &attr) { |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 927 | #if HAVE_INFINIBAND_VERBS_EXP_H |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 928 | attr.comp_mask = |
| 929 | IBV_EXP_CREATE_SRQ_CQ; |
| 930 | attr.srq_type = IBV_EXP_SRQT_BASIC; |
| 931 | attr.pd = pd.pd; |
| 932 | attr.cq = cq.cq; |
| 933 | attr.base.attr.max_wr = 128; |
| 934 | attr.base.attr.max_sge = 1; |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 935 | #else |
| 936 | attr.comp_mask = |
| 937 | IBV_SRQ_INIT_ATTR_TYPE | |
| 938 | IBV_SRQ_INIT_ATTR_PD | |
| 939 | IBV_SRQ_INIT_ATTR_CQ; |
| 940 | attr.pd = pd.pd; |
| 941 | attr.cq = cq.cq; |
| 942 | attr.attr.max_wr = 128; |
| 943 | attr.attr.max_sge = 1; |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 944 | #endif |
| 945 | } |
| 946 | |
| 947 | virtual void init() { |
| 948 | struct ibv_srq_init_attr_ex attr = {}; |
| 949 | if (srq) |
| 950 | return; |
| 951 | |
Artemy Kovalyov | c0206e6 | 2017-09-13 13:34:04 +0300 | [diff] [blame] | 952 | INIT(pd.init()); |
| 953 | INIT(cq.init()); |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 954 | init_attr(attr); |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 955 | SET(srq, ibv_create_srq_ex(pd.ctx.ctx, &attr)); |
| 956 | } |
| 957 | |
| 958 | virtual void recv(ibv_sge sge) { |
| 959 | struct ibv_recv_wr wr; |
| 960 | struct ibv_recv_wr *bad_wr = NULL; |
| 961 | |
| 962 | memset(&wr, 0, sizeof(wr)); |
| 963 | wr.next = NULL; |
| 964 | wr.wr_id = 0x56789; |
| 965 | wr.sg_list = &sge; |
| 966 | wr.num_sge = 1; |
| 967 | DO(ibv_post_srq_recv(srq, &wr, &bad_wr)); |
| 968 | } |
| 969 | }; |
| 970 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 971 | struct ibvt_qp : public ibvt_obj { |
| 972 | struct ibv_qp *qp; |
| 973 | ibvt_pd &pd; |
| 974 | ibvt_cq &cq; |
| 975 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 976 | ibvt_qp(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) : ibvt_obj(e), qp(NULL), pd(p), cq(c) {} |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 977 | |
| 978 | virtual ~ibvt_qp() { |
| 979 | FREE(ibv_destroy_qp, qp); |
| 980 | } |
| 981 | |
| 982 | virtual void init_attr(struct ibv_qp_init_attr_ex &attr) { |
| 983 | memset(&attr, 0, sizeof(attr)); |
Artemy Kovalyov | 8b8ef17 | 2017-02-13 13:46:22 +0000 | [diff] [blame] | 984 | attr.cap.max_send_wr = 0x1000; |
| 985 | attr.cap.max_recv_wr = 0x1000; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 986 | attr.cap.max_send_sge = 1; |
| 987 | attr.cap.max_recv_sge = 1; |
| 988 | attr.send_cq = cq.cq; |
| 989 | attr.recv_cq = cq.cq; |
| 990 | attr.pd = pd.pd; |
| 991 | attr.comp_mask = IBV_QP_INIT_ATTR_PD; |
| 992 | } |
| 993 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 994 | virtual void init() { |
| 995 | struct ibv_qp_init_attr_ex attr; |
| 996 | INIT(pd.init()); |
| 997 | INIT(cq.init()); |
| 998 | init_attr(attr); |
| 999 | SET(qp, ibv_create_qp_ex(pd.ctx.ctx, &attr)); |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 1000 | INIT(init_dv()); |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1001 | } |
| 1002 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 1003 | #if HAVE_DECL_MLX5DV_INIT_OBJ |
| 1004 | uint8_t *sq; |
| 1005 | volatile uint32_t *qp_dbr; |
| 1006 | void *uar_ptr; |
| 1007 | int sqi; |
| 1008 | int sq_len; |
| 1009 | |
| 1010 | virtual void init_dv() { |
| 1011 | struct mlx5dv_qp dvqp = {}; |
| 1012 | struct mlx5dv_obj dv = {}; |
| 1013 | |
| 1014 | dv.qp.in = qp; |
| 1015 | dv.qp.out = &dvqp; |
| 1016 | DO(mlx5dv_init_obj(&dv, MLX5DV_OBJ_QP)); |
| 1017 | sq = (uint8_t *)dvqp.sq.buf; |
| 1018 | qp_dbr = dvqp.dbrec; |
| 1019 | uar_ptr = dvqp.bf.reg; |
| 1020 | sq_len = dvqp.sq.stride * dvqp.sq.wqe_cnt; |
| 1021 | sqi = 0; |
| 1022 | } |
| 1023 | |
| 1024 | void *get_wqe(int i) { |
| 1025 | void *wqe = sq + ((sqi + i) * MLX5_SEND_WQE_BB) % sq_len; |
| 1026 | memset(wqe, 0, MLX5_SEND_WQE_BB); |
| 1027 | return wqe; |
| 1028 | } |
| 1029 | |
| 1030 | void ring_db(int i) { |
| 1031 | void *ctrl = sq + (sqi * MLX5_SEND_WQE_BB) % sq_len; |
| 1032 | |
| 1033 | //hexdump("WQE", ctrl, i * MLX5_SEND_WQE_BB); |
| 1034 | |
| 1035 | sqi += i; |
| 1036 | asm volatile("" ::: "memory"); |
| 1037 | |
| 1038 | qp_dbr[MLX5_SND_DBR] = htobe32(sqi & 0xffff); |
| 1039 | asm volatile("" ::: "memory"); |
| 1040 | |
| 1041 | *(uint64_t *)uar_ptr = *(uint64_t *)ctrl; |
| 1042 | asm volatile("" ::: "memory"); |
| 1043 | } |
| 1044 | #else |
| 1045 | virtual void init_dv() {} |
| 1046 | #endif |
| 1047 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 1048 | virtual void post_all_wr() { |
| 1049 | struct ibv_send_wr *bad_wr = NULL; |
| 1050 | DO(ibv_post_send(qp, env.wr_list, &bad_wr)); |
| 1051 | env.free_wr(); |
| 1052 | } |
| 1053 | |
Artemy Kovalyov | fc636ed | 2016-11-27 13:16:39 +0200 | [diff] [blame] | 1054 | virtual void recv(ibv_sge sge) { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1055 | struct ibv_recv_wr wr; |
| 1056 | struct ibv_recv_wr *bad_wr = NULL; |
| 1057 | |
| 1058 | memset(&wr, 0, sizeof(wr)); |
| 1059 | wr.next = NULL; |
| 1060 | wr.wr_id = 0; |
| 1061 | wr.sg_list = &sge; |
| 1062 | wr.num_sge = 1; |
| 1063 | DO(ibv_post_recv(qp, &wr, &bad_wr)); |
| 1064 | } |
| 1065 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1066 | virtual void post_send(ibv_sge sge, enum ibv_wr_opcode opcode, |
| 1067 | int flags = IBV_SEND_SIGNALED) { |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1068 | struct ibv_send_wr wr; |
| 1069 | struct ibv_send_wr *bad_wr = NULL; |
| 1070 | |
| 1071 | memset(&wr, 0, sizeof(wr)); |
| 1072 | wr.next = NULL; |
| 1073 | wr.wr_id = 0; |
| 1074 | wr.sg_list = &sge; |
| 1075 | wr.num_sge = 1; |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1076 | wr._wr_opcode = opcode; |
| 1077 | wr._wr_send_flags = flags; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1078 | DO(ibv_post_send(qp, &wr, &bad_wr)); |
| 1079 | } |
| 1080 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 1081 | virtual void rdma_wr(ibv_sge src_sge, ibv_sge dst_sge, enum ibv_wr_opcode opcode, int flags = IBV_SEND_SIGNALED) { |
| 1082 | struct __rdma_wr { |
| 1083 | ibv_send_wr wr; |
| 1084 | ibv_sge sge; |
| 1085 | } *wr = (__rdma_wr *)calloc(1, sizeof(*wr)); |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1086 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 1087 | wr->sge = src_sge; |
| 1088 | wr->wr.wr_id = 0; |
| 1089 | wr->wr.sg_list = &wr->sge; |
| 1090 | wr->wr.num_sge = 1; |
| 1091 | wr->wr._wr_opcode = opcode; |
| 1092 | wr->wr._wr_send_flags = flags; |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1093 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 1094 | wr->wr.wr.rdma.remote_addr = dst_sge.addr; |
| 1095 | wr->wr.wr.rdma.rkey = dst_sge.lkey; |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1096 | |
Artemy Kovalyov | 79a00f7 | 2018-12-12 09:29:00 +0200 | [diff] [blame] | 1097 | env.add_wr(&wr->wr); |
| 1098 | } |
| 1099 | |
| 1100 | virtual void rdma(ibv_sge src_sge, ibv_sge dst_sge, enum ibv_wr_opcode opcode, int flags = IBV_SEND_SIGNALED) { |
| 1101 | rdma_wr(src_sge, dst_sge, opcode, flags); |
| 1102 | EXEC(post_all_wr()); |
Artemy Kovalyov | 21e22a3 | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1103 | } |
| 1104 | |
Artemy Kovalyov | 921fbbe | 2017-08-20 02:51:49 +0300 | [diff] [blame] | 1105 | virtual void rdma2(ibv_sge src_sge1, |
| 1106 | ibv_sge src_sge2, |
| 1107 | ibv_sge dst_sge, |
| 1108 | enum ibv_wr_opcode opcode, |
| 1109 | enum ibv_send_flags flags = IBV_SEND_SIGNALED) { |
| 1110 | struct ibv_send_wr wr; |
| 1111 | struct ibv_send_wr *bad_wr = NULL; |
| 1112 | struct ibv_sge sg[2]; |
| 1113 | |
| 1114 | |
| 1115 | sg[0] = src_sge1; |
| 1116 | sg[1] = src_sge2; |
| 1117 | memset(&wr, 0, sizeof(wr)); |
| 1118 | wr.next = NULL; |
| 1119 | wr.wr_id = 0; |
| 1120 | wr.sg_list = sg; |
| 1121 | wr.num_sge = 2; |
| 1122 | wr._wr_opcode = opcode; |
| 1123 | wr._wr_send_flags = flags; |
| 1124 | |
| 1125 | wr.wr.rdma.remote_addr = dst_sge.addr; |
| 1126 | wr.wr.rdma.rkey = dst_sge.lkey; |
| 1127 | |
| 1128 | DO(ibv_post_send(qp, &wr, &bad_wr)); |
| 1129 | } |
| 1130 | |
Artemy Kovalyov | fc636ed | 2016-11-27 13:16:39 +0200 | [diff] [blame] | 1131 | virtual void send(ibv_sge sge) { |
| 1132 | post_send(sge, IBV_WR_SEND); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1133 | } |
Artemy Kovalyov | a4bd425 | 2017-07-15 12:34:20 +0300 | [diff] [blame] | 1134 | |
| 1135 | virtual void connect(ibvt_qp *remote) = 0; |
Artemy Kovalyov | be5fe9b | 2018-02-24 20:51:48 +0200 | [diff] [blame] | 1136 | |
| 1137 | virtual int hdr_len() { return 0; } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1138 | }; |
| 1139 | |
| 1140 | struct ibvt_qp_rc : public ibvt_qp { |
| 1141 | ibvt_qp *remote; |
| 1142 | |
| 1143 | ibvt_qp_rc(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) : ibvt_qp(e, p, c) {} |
| 1144 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1145 | virtual void init_attr(struct ibv_qp_init_attr_ex &attr) { |
| 1146 | ibvt_qp::init_attr(attr); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1147 | attr.qp_type = IBV_QPT_RC; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1148 | } |
| 1149 | |
| 1150 | virtual void connect(ibvt_qp *remote) { |
| 1151 | struct ibv_qp_attr attr; |
| 1152 | int flags; |
| 1153 | |
| 1154 | this->remote = remote; |
| 1155 | |
| 1156 | memset(&attr, 0, sizeof(attr)); |
| 1157 | attr.qp_state = IBV_QPS_INIT; |
| 1158 | attr.port_num = pd.ctx.port_num; |
| 1159 | attr.pkey_index = 0; |
| 1160 | attr.qp_access_flags = IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE; |
| 1161 | flags = IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_ACCESS_FLAGS; |
| 1162 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1163 | |
| 1164 | memset(&attr, 0, sizeof(attr)); |
| 1165 | attr.qp_state = IBV_QPS_RTR; |
| 1166 | attr.path_mtu = IBV_MTU_512; |
| 1167 | attr.dest_qp_num = remote->qp->qp_num; |
| 1168 | attr.rq_psn = 0; |
| 1169 | attr.max_dest_rd_atomic = 1; |
| 1170 | attr.min_rnr_timer = 12; |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 1171 | if (!pd.ctx.grh_required()) { |
| 1172 | attr.ah_attr.is_global = 0; |
| 1173 | } else { |
| 1174 | attr.ah_attr.is_global = 1; |
| 1175 | attr.ah_attr.grh.hop_limit = 1; |
| 1176 | attr.ah_attr.grh.dgid = remote->pd.ctx.gid; |
| 1177 | attr.ah_attr.grh.sgid_index = 0; |
| 1178 | } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1179 | attr.ah_attr.dlid = remote->pd.ctx.lid; |
| 1180 | attr.ah_attr.sl = 0; |
| 1181 | attr.ah_attr.src_path_bits = 0; |
| 1182 | attr.ah_attr.port_num = remote->pd.ctx.port_num; |
| 1183 | flags = IBV_QP_STATE | IBV_QP_AV | IBV_QP_PATH_MTU | IBV_QP_DEST_QPN | |
| 1184 | IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC | IBV_QP_MIN_RNR_TIMER; |
| 1185 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1186 | |
| 1187 | memset(&attr, 0, sizeof(attr)); |
| 1188 | attr.qp_state = IBV_QPS_RTS; |
| 1189 | attr.timeout = 14; |
| 1190 | attr.retry_cnt = 7; |
| 1191 | attr.rnr_retry = 7; |
| 1192 | attr.sq_psn = 0; |
| 1193 | attr.max_rd_atomic = 1; |
| 1194 | flags = IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | |
| 1195 | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC; |
| 1196 | |
| 1197 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1198 | } |
| 1199 | }; |
| 1200 | |
| 1201 | struct ibvt_qp_ud : public ibvt_qp_rc { |
| 1202 | struct ibv_ah *ah; |
| 1203 | |
| 1204 | ibvt_qp_ud(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) : ibvt_qp_rc(e, p, c) {} |
| 1205 | |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 1206 | virtual ~ibvt_qp_ud() { |
| 1207 | FREE(ibv_destroy_ah, ah); |
| 1208 | } |
| 1209 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1210 | virtual void init_attr(struct ibv_qp_init_attr_ex &attr) { |
| 1211 | ibvt_qp::init_attr(attr); |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1212 | attr.qp_type = IBV_QPT_UD; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1213 | } |
| 1214 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1215 | virtual void post_send(ibv_sge sge, enum ibv_wr_opcode opcode, |
| 1216 | int flags = IBV_SEND_SIGNALED) { |
Artemy Kovalyov | 7ad124b | 2016-11-28 12:08:28 +0200 | [diff] [blame] | 1217 | struct ibv_sge sge_ud = sge; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1218 | struct ibv_send_wr wr; |
| 1219 | struct ibv_send_wr *bad_wr = NULL; |
| 1220 | |
Artemy Kovalyov | 7ad124b | 2016-11-28 12:08:28 +0200 | [diff] [blame] | 1221 | sge_ud.addr += 40; |
| 1222 | sge_ud.length -= 40; |
| 1223 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1224 | memset(&wr, 0, sizeof(wr)); |
| 1225 | wr.next = NULL; |
| 1226 | wr.wr_id = 0; |
Artemy Kovalyov | 7ad124b | 2016-11-28 12:08:28 +0200 | [diff] [blame] | 1227 | wr.sg_list = &sge_ud; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1228 | wr.num_sge = 1; |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1229 | wr._wr_opcode = opcode; |
| 1230 | wr._wr_send_flags = flags; |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1231 | |
| 1232 | wr.wr.ud.ah = ah; |
| 1233 | wr.wr.ud.remote_qpn = remote->qp->qp_num; |
| 1234 | wr.wr.ud.remote_qkey = Q_KEY; |
| 1235 | |
| 1236 | DO(ibv_post_send(qp, &wr, &bad_wr)); |
| 1237 | } |
| 1238 | |
| 1239 | virtual void connect(ibvt_qp *remote) { |
| 1240 | struct ibv_qp_attr attr; |
| 1241 | int flags; |
| 1242 | |
| 1243 | this->remote = remote; |
| 1244 | |
| 1245 | memset(&attr, 0, sizeof(attr)); |
| 1246 | attr.qp_state = IBV_QPS_INIT; |
| 1247 | attr.port_num = pd.ctx.port_num; |
| 1248 | attr.pkey_index = 0; |
| 1249 | attr.qkey = Q_KEY; |
| 1250 | flags = IBV_QP_STATE | IBV_QP_PKEY_INDEX | IBV_QP_PORT | IBV_QP_QKEY; |
| 1251 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1252 | |
| 1253 | memset(&attr, 0, sizeof(attr)); |
| 1254 | attr.qp_state = IBV_QPS_RTR; |
| 1255 | flags = IBV_QP_STATE; |
| 1256 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1257 | |
Artemy Kovalyov | 19ecad3 | 2018-12-05 20:49:49 +0200 | [diff] [blame] | 1258 | if (!pd.ctx.grh_required()) { |
| 1259 | attr.ah_attr.is_global = 0; |
| 1260 | } else { |
| 1261 | attr.ah_attr.is_global = 1; |
| 1262 | attr.ah_attr.grh.hop_limit = 1; |
| 1263 | attr.ah_attr.grh.dgid = remote->pd.ctx.gid; |
| 1264 | attr.ah_attr.grh.sgid_index = 0; |
| 1265 | } |
| 1266 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1267 | attr.ah_attr.dlid = remote->pd.ctx.lid; |
| 1268 | attr.ah_attr.sl = 0; |
| 1269 | attr.ah_attr.src_path_bits = 0; |
| 1270 | attr.ah_attr.port_num = remote->pd.ctx.port_num; |
| 1271 | SET(ah, ibv_create_ah(pd.pd, &attr.ah_attr)); |
| 1272 | |
| 1273 | memset(&attr, 0, sizeof(attr)); |
| 1274 | attr.qp_state = IBV_QPS_RTS; |
| 1275 | attr.sq_psn = 0; |
| 1276 | flags = IBV_QP_STATE | IBV_QP_SQ_PSN; |
| 1277 | |
| 1278 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1279 | } |
Artemy Kovalyov | be5fe9b | 2018-02-24 20:51:48 +0200 | [diff] [blame] | 1280 | |
| 1281 | virtual int hdr_len() { return 40; } |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1282 | }; |
| 1283 | |
Artemy Kovalyov | 441bd41 | 2018-02-24 20:55:49 +0200 | [diff] [blame] | 1284 | #if HAVE_INFINIBAND_VERBS_EXP_H |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1285 | #define HAVE_DC 1 |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1286 | struct ibvt_dct : public ibvt_obj { |
| 1287 | struct ibv_dct *dct; |
| 1288 | ibvt_pd &pd; |
| 1289 | ibvt_cq &cq; |
| 1290 | ibvt_srq &srq; |
| 1291 | |
| 1292 | ibvt_dct(ibvt_env &e, ibvt_pd &p, ibvt_cq &c, ibvt_srq &s) : |
| 1293 | ibvt_obj(e), dct(NULL), pd(p), cq(c), srq(s) {} |
| 1294 | |
| 1295 | virtual void init() { |
| 1296 | struct ibv_exp_dct_init_attr attr = {}; |
| 1297 | |
| 1298 | if (dct) |
| 1299 | return; |
| 1300 | |
| 1301 | INIT(pd.init()); |
| 1302 | INIT(cq.init()); |
| 1303 | INIT(srq.init()); |
| 1304 | |
| 1305 | attr.pd = pd.pd; |
| 1306 | attr.cq = cq.cq; |
| 1307 | attr.srq = srq.srq; |
| 1308 | attr.dc_key = DC_KEY; |
| 1309 | attr.port = pd.ctx.port_num; |
| 1310 | attr.access_flags = IBV_ACCESS_REMOTE_WRITE; |
| 1311 | attr.min_rnr_timer = 2; |
| 1312 | attr.mtu = IBV_MTU_512; |
| 1313 | attr.hop_limit = 1; |
| 1314 | attr.inline_size = 0; |
| 1315 | SET(dct, ibv_exp_create_dct(pd.ctx.ctx, &attr)); |
| 1316 | } |
| 1317 | |
| 1318 | virtual void connect(ibvt_qp *remote) { } |
| 1319 | |
| 1320 | virtual ~ibvt_dct() { |
| 1321 | FREE(ibv_exp_destroy_dct, dct); |
| 1322 | } |
| 1323 | }; |
| 1324 | |
| 1325 | struct ibvt_qp_dc : public ibvt_qp_ud { |
| 1326 | ibvt_dct* dremote; |
| 1327 | |
| 1328 | ibvt_qp_dc(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) : ibvt_qp_ud(e, p, c) {} |
| 1329 | |
| 1330 | virtual void init_attr(struct ibv_qp_init_attr_ex &attr) { |
| 1331 | ibvt_qp::init_attr(attr); |
| 1332 | attr.qp_type = IBV_EXP_QPT_DC_INI; |
| 1333 | } |
| 1334 | |
| 1335 | virtual void connect(ibvt_dct *remote) { |
| 1336 | struct ibv_exp_qp_attr attr; |
| 1337 | long long flags; |
| 1338 | |
| 1339 | this->dremote = remote; |
| 1340 | |
| 1341 | memset(&attr, 0, sizeof(attr)); |
| 1342 | attr.qp_state = IBV_QPS_INIT; |
| 1343 | attr.port_num = pd.ctx.port_num; |
| 1344 | attr.pkey_index = 0; |
| 1345 | attr.dct_key = DC_KEY; |
| 1346 | flags = IBV_EXP_QP_STATE | |
| 1347 | IBV_EXP_QP_PKEY_INDEX | |
| 1348 | IBV_EXP_QP_PORT | |
| 1349 | IBV_EXP_QP_DC_KEY; |
| 1350 | |
| 1351 | DO(ibv_exp_modify_qp(qp, &attr, flags)); |
| 1352 | |
| 1353 | memset(&attr, 0, sizeof(attr)); |
| 1354 | attr.qp_state = IBV_QPS_RTR; |
| 1355 | attr.path_mtu = IBV_MTU_512; |
| 1356 | attr.ah_attr.is_global = 0; |
| 1357 | flags = IBV_EXP_QP_STATE | IBV_EXP_QP_PATH_MTU | |
| 1358 | IBV_EXP_QP_AV; |
| 1359 | |
| 1360 | |
| 1361 | attr.ah_attr.dlid = dremote->pd.ctx.lid; |
| 1362 | attr.ah_attr.sl = 0; |
| 1363 | attr.ah_attr.src_path_bits = 0; |
| 1364 | attr.ah_attr.port_num = dremote->pd.ctx.port_num; |
| 1365 | SET(ah, ibv_create_ah(pd.pd, &attr.ah_attr)); |
| 1366 | DO(ibv_exp_modify_qp(qp, &attr, flags)); |
| 1367 | |
| 1368 | memset(&attr, 0, sizeof(attr)); |
| 1369 | attr.qp_state = IBV_QPS_RTS; |
| 1370 | attr.timeout = 14; |
| 1371 | attr.retry_cnt = 7; |
| 1372 | attr.rnr_retry = 7; |
| 1373 | attr.max_rd_atomic = 1; |
| 1374 | flags = IBV_EXP_QP_STATE | IBV_EXP_QP_TIMEOUT | |
| 1375 | IBV_EXP_QP_RETRY_CNT | |
| 1376 | IBV_EXP_QP_RNR_RETRY | |
| 1377 | IBV_EXP_QP_MAX_QP_RD_ATOMIC; |
| 1378 | |
| 1379 | DO(ibv_exp_modify_qp(qp, &attr, flags)); |
| 1380 | } |
| 1381 | |
| 1382 | virtual void post_send(ibv_sge sge, enum ibv_wr_opcode opcode, |
| 1383 | int flags = IBV_SEND_SIGNALED) { |
| 1384 | struct ibv_sge sge_ud = sge; |
| 1385 | struct ibv_exp_send_wr wr = {}; |
| 1386 | struct ibv_exp_send_wr *bad_wr = NULL; |
| 1387 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1388 | wr.sg_list = &sge_ud; |
| 1389 | wr.num_sge = 1; |
| 1390 | wr.exp_opcode = opcode; |
| 1391 | wr.exp_send_flags = flags; |
| 1392 | |
| 1393 | wr.dc.ah = ah; |
| 1394 | wr.dc.dct_number = dremote->dct->dct_num; |
| 1395 | wr.dc.dct_access_key = DC_KEY; |
| 1396 | |
| 1397 | DO(ibv_exp_post_send(qp, &wr, &bad_wr)); |
| 1398 | } |
Artemy Kovalyov | a4bd425 | 2017-07-15 12:34:20 +0300 | [diff] [blame] | 1399 | |
| 1400 | virtual void rdma(ibv_sge src_sge, ibv_sge dst_sge, enum ibv_wr_opcode opcode, enum ibv_send_flags flags = IBV_SEND_SIGNALED) { |
| 1401 | struct ibv_send_wr wr; |
| 1402 | struct ibv_send_wr *bad_wr = NULL; |
| 1403 | |
| 1404 | memset(&wr, 0, sizeof(wr)); |
| 1405 | wr.next = NULL; |
| 1406 | wr.wr_id = 0; |
| 1407 | wr.sg_list = &src_sge; |
| 1408 | wr.num_sge = 1; |
| 1409 | wr._wr_opcode = opcode; |
| 1410 | wr._wr_send_flags = flags; |
| 1411 | |
| 1412 | wr.dc.ah = ah; |
| 1413 | wr.dc.dct_number = dremote->dct->dct_num; |
| 1414 | wr.dc.dct_access_key = DC_KEY; |
| 1415 | |
| 1416 | wr.wr.rdma.remote_addr = dst_sge.addr; |
| 1417 | wr.wr.rdma.rkey = dst_sge.lkey; |
| 1418 | |
| 1419 | DO(ibv_post_send(qp, &wr, &bad_wr)); |
| 1420 | } |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1421 | }; |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1422 | |
| 1423 | |
| 1424 | #elif HAVE_DECL_MLX5DV_DCTYPE_DCT |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1425 | #define HAVE_DC 1 |
| 1426 | |
| 1427 | struct ibvt_dct : public ibvt_obj { |
| 1428 | struct ibv_qp *dct; |
| 1429 | ibvt_pd &pd; |
| 1430 | ibvt_cq &cq; |
| 1431 | ibvt_srq &srq; |
| 1432 | |
| 1433 | ibvt_dct(ibvt_env &e, ibvt_pd &p, ibvt_cq &c, ibvt_srq &s) : |
| 1434 | ibvt_obj(e), dct(NULL), pd(p), cq(c), srq(s) {} |
| 1435 | |
| 1436 | virtual void init() { |
| 1437 | struct ibv_qp_attr attr = {}; |
| 1438 | struct ibv_qp_init_attr_ex init_attr = {}; |
| 1439 | struct mlx5dv_qp_init_attr dv_attr = {}; |
| 1440 | |
| 1441 | if (dct) |
| 1442 | return; |
| 1443 | |
| 1444 | INIT(pd.init()); |
| 1445 | INIT(cq.init()); |
| 1446 | INIT(srq.init()); |
| 1447 | |
| 1448 | init_attr.pd = pd.pd; |
| 1449 | init_attr.send_cq = cq.cq; |
| 1450 | init_attr.recv_cq = cq.cq; |
| 1451 | init_attr.srq = srq.srq; |
| 1452 | init_attr.qp_type = IBV_QPT_DRIVER; |
| 1453 | init_attr.comp_mask = IBV_QP_INIT_ATTR_PD; |
| 1454 | |
| 1455 | dv_attr.comp_mask = MLX5DV_QP_INIT_ATTR_MASK_DC; |
| 1456 | dv_attr.dc_init_attr.dc_type = MLX5DV_DCTYPE_DCT; |
| 1457 | dv_attr.dc_init_attr.dct_access_key = DC_KEY; |
| 1458 | SET(dct, mlx5dv_create_qp(pd.ctx.ctx, &init_attr, &dv_attr)); |
| 1459 | |
| 1460 | attr.qp_state = IBV_QPS_INIT; |
| 1461 | attr.port_num = pd.ctx.port_num; |
| 1462 | attr.qp_access_flags = IBV_ACCESS_LOCAL_WRITE | |
| 1463 | IBV_ACCESS_REMOTE_READ | |
| 1464 | IBV_ACCESS_REMOTE_WRITE; |
| 1465 | |
| 1466 | DO(ibv_modify_qp(dct, &attr, IBV_QP_STATE | |
| 1467 | IBV_QP_PKEY_INDEX | |
| 1468 | IBV_QP_PORT | |
| 1469 | IBV_QP_ACCESS_FLAGS)); |
| 1470 | |
| 1471 | memset(&attr, 0, sizeof(attr)); |
| 1472 | attr.qp_state = IBV_QPS_RTR; |
| 1473 | attr.path_mtu = IBV_MTU_512; |
| 1474 | attr.min_rnr_timer = 2; |
| 1475 | attr.ah_attr.grh.hop_limit = 1; |
| 1476 | attr.ah_attr.port_num = pd.ctx.port_num; |
| 1477 | |
| 1478 | DO(ibv_modify_qp(dct, &attr, IBV_QP_STATE | |
| 1479 | IBV_QP_MIN_RNR_TIMER | |
| 1480 | IBV_QP_AV | |
| 1481 | IBV_QP_PATH_MTU)); |
| 1482 | } |
| 1483 | |
| 1484 | virtual void connect(ibvt_qp *remote) { } |
| 1485 | |
| 1486 | virtual ~ibvt_dct() { |
| 1487 | FREE(ibv_destroy_qp, dct); |
| 1488 | } |
| 1489 | }; |
| 1490 | |
| 1491 | struct ibvt_qp_dc : public ibvt_qp_ud { |
| 1492 | ibvt_dct* dremote; |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1493 | |
| 1494 | ibvt_qp_dc(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) : ibvt_qp_ud(e, p, c) {} |
| 1495 | |
| 1496 | virtual void init() { |
| 1497 | struct ibv_qp_init_attr_ex attr = {}; |
| 1498 | struct mlx5dv_qp_init_attr dv_attr = {}; |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1499 | |
| 1500 | INIT(pd.init()); |
| 1501 | INIT(cq.init()); |
| 1502 | |
| 1503 | ibvt_qp::init_attr(attr); |
| 1504 | attr.qp_type = IBV_QPT_DRIVER; |
| 1505 | attr.cap.max_send_wr = 0x40; |
| 1506 | attr.cap.max_recv_wr = 0; |
| 1507 | attr.cap.max_recv_sge = 0; |
| 1508 | |
| 1509 | dv_attr.comp_mask = MLX5DV_QP_INIT_ATTR_MASK_DC; |
| 1510 | dv_attr.dc_init_attr.dc_type = MLX5DV_DCTYPE_DCI; |
| 1511 | dv_attr.dc_init_attr.dct_access_key = DC_KEY; |
| 1512 | SET(qp, mlx5dv_create_qp(pd.ctx.ctx, &attr, &dv_attr)); |
| 1513 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 1514 | EXEC(init_dv()); |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1515 | } |
| 1516 | |
| 1517 | virtual void connect(ibvt_dct *remote) { |
| 1518 | struct ibv_qp_attr attr; |
| 1519 | long long flags; |
| 1520 | |
| 1521 | this->dremote = remote; |
| 1522 | |
| 1523 | memset(&attr, 0, sizeof(attr)); |
| 1524 | attr.qp_state = IBV_QPS_INIT; |
| 1525 | attr.port_num = pd.ctx.port_num; |
| 1526 | attr.pkey_index = 0; |
| 1527 | flags = IBV_QP_STATE | |
| 1528 | IBV_QP_PKEY_INDEX | |
| 1529 | IBV_QP_PORT; |
| 1530 | |
| 1531 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1532 | |
| 1533 | memset(&attr, 0, sizeof(attr)); |
| 1534 | attr.qp_state = IBV_QPS_RTR; |
| 1535 | attr.path_mtu = IBV_MTU_512; |
| 1536 | attr.ah_attr.is_global = 0; |
| 1537 | flags = IBV_QP_STATE | IBV_QP_PATH_MTU; |
| 1538 | |
| 1539 | attr.ah_attr.dlid = dremote->pd.ctx.lid; |
| 1540 | attr.ah_attr.sl = 0; |
| 1541 | attr.ah_attr.src_path_bits = 0; |
| 1542 | attr.ah_attr.port_num = dremote->pd.ctx.port_num; |
| 1543 | SET(ah, ibv_create_ah(pd.pd, &attr.ah_attr)); |
| 1544 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1545 | |
| 1546 | memset(&attr, 0, sizeof(attr)); |
| 1547 | attr.qp_state = IBV_QPS_RTS; |
| 1548 | attr.timeout = 14; |
| 1549 | attr.retry_cnt = 7; |
| 1550 | attr.rnr_retry = 7; |
| 1551 | attr.max_rd_atomic = 1; |
| 1552 | flags = IBV_QP_STATE | IBV_QP_TIMEOUT | |
| 1553 | IBV_QP_RETRY_CNT | IBV_QP_SQ_PSN | |
| 1554 | IBV_QP_RNR_RETRY | |
| 1555 | IBV_QP_MAX_QP_RD_ATOMIC; |
| 1556 | |
| 1557 | DO(ibv_modify_qp(qp, &attr, flags)); |
| 1558 | } |
| 1559 | |
| 1560 | virtual void post_send(ibv_sge sge, enum ibv_wr_opcode opcode, |
| 1561 | int flags = IBV_SEND_SIGNALED) { |
| 1562 | uint8_t mac[6] = {}, gid[16] = {}; |
| 1563 | uint8_t fm_ce_se = 0, op, ds = 5; |
| 1564 | |
| 1565 | if (flags == IBV_SEND_SIGNALED) |
| 1566 | fm_ce_se |= MLX5_WQE_CTRL_CQ_UPDATE; |
| 1567 | if (opcode == IBV_WR_SEND) |
| 1568 | op = MLX5_OPCODE_SEND; |
| 1569 | else |
| 1570 | FAIL(); |
| 1571 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 1572 | struct mlx5_wqe_ctrl_seg *ctrl = (struct mlx5_wqe_ctrl_seg *)get_wqe(0); |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1573 | mlx5dv_set_ctrl_seg(ctrl, sqi, op, 0, qp->qp_num, fm_ce_se, ds, 0, 0); |
| 1574 | |
| 1575 | struct mlx5_wqe_datagram_seg *avseg = (struct mlx5_wqe_datagram_seg *)(ctrl + 1); |
| 1576 | mlx5dv_set_dgram_seg(avseg, DC_KEY, dremote->dct->qp_num, 1, 0, |
| 1577 | dremote->pd.ctx.lid, dremote->pd.ctx.lid, |
| 1578 | mac, 0, 1, 0, gid); |
| 1579 | struct mlx5_wqe_data_seg *dseg = (struct mlx5_wqe_data_seg *)(avseg + 1); |
| 1580 | mlx5dv_set_data_seg(dseg, sge.length, sge.lkey, (intptr_t)sge.addr); |
| 1581 | |
Artemy Kovalyov | cec4ef9 | 2018-12-12 09:41:01 +0200 | [diff] [blame] | 1582 | ring_db(2); |
Artemy Kovalyov | b4f5b67 | 2018-10-13 21:35:43 +0000 | [diff] [blame] | 1583 | } |
| 1584 | |
| 1585 | virtual void rdma(ibv_sge src_sge, ibv_sge dst_sge, enum ibv_wr_opcode opcode, enum ibv_send_flags flags = IBV_SEND_SIGNALED) { |
| 1586 | FAIL(); |
| 1587 | } |
| 1588 | }; |
| 1589 | |
Artemy Kovalyov | 1ccd1a7 | 2017-06-02 03:22:22 +0300 | [diff] [blame] | 1590 | #endif |
| 1591 | |
| 1592 | template <typename QP> |
| 1593 | struct ibvt_qp_srq : public QP { |
| 1594 | ibvt_srq &srq; |
| 1595 | |
| 1596 | ibvt_qp_srq(ibvt_env &e, ibvt_pd &p, ibvt_cq &c, ibvt_srq &s) : |
| 1597 | QP(e, p, c), srq(s) {} |
| 1598 | |
| 1599 | virtual void init_attr(struct ibv_qp_init_attr_ex &attr) { |
| 1600 | QP::init_attr(attr); |
| 1601 | attr.srq = srq.srq; |
| 1602 | } |
| 1603 | |
| 1604 | }; |
| 1605 | |
Artemy Kovalyov | 5985a67 | 2018-04-28 20:08:24 +0000 | [diff] [blame] | 1606 | #if HAVE_INFINIBAND_VERBS_EXP_H |
| 1607 | struct ibvt_mw : public ibvt_mr { |
| 1608 | ibvt_mr &master; |
| 1609 | ibvt_qp &qp; |
| 1610 | |
| 1611 | ibvt_mw(ibvt_mr &i, intptr_t a, size_t size, ibvt_qp &q) : |
| 1612 | ibvt_mr(i.env, i.pd, size, a), master(i), qp(q) {} |
| 1613 | |
| 1614 | virtual void init() { |
| 1615 | intptr_t addr; |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 1616 | if (mr || env.skip) |
Artemy Kovalyov | 5985a67 | 2018-04-28 20:08:24 +0000 | [diff] [blame] | 1617 | return; |
| 1618 | if (master.buff) { |
| 1619 | addr = (intptr_t)master.buff; |
| 1620 | buff = master.buff; |
| 1621 | } else { |
| 1622 | EXEC(init_mmap()); |
| 1623 | addr = (intptr_t)buff; |
| 1624 | } |
| 1625 | |
| 1626 | struct ibv_exp_create_mr_in mr_in = {}; |
| 1627 | mr_in.pd = pd.pd; |
| 1628 | mr_in.attr.create_flags = IBV_EXP_MR_INDIRECT_KLMS; |
| 1629 | mr_in.attr.max_klm_list_size = 4; |
| 1630 | mr_in.attr.exp_access_flags = IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE; |
| 1631 | mr_in.comp_mask = 0; |
| 1632 | SET(mr, ibv_exp_create_mr(&mr_in)); |
| 1633 | |
Artemy Kovalyov | a5bfe6f | 2018-06-03 17:25:12 +0300 | [diff] [blame] | 1634 | if (env.skip) |
| 1635 | return; |
Artemy Kovalyov | 5985a67 | 2018-04-28 20:08:24 +0000 | [diff] [blame] | 1636 | struct ibv_exp_mem_region mem_reg = {}; |
| 1637 | mem_reg.base_addr = addr; |
| 1638 | mem_reg.length = size; |
| 1639 | mem_reg.mr = master.mr; |
| 1640 | |
| 1641 | struct ibv_exp_send_wr wr = {}, *bad_wr = NULL; |
| 1642 | wr.exp_opcode = IBV_EXP_WR_UMR_FILL; |
| 1643 | wr.ext_op.umr.umr_type = IBV_EXP_UMR_MR_LIST; |
| 1644 | wr.ext_op.umr.exp_access = IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE; |
| 1645 | wr.ext_op.umr.modified_mr = mr; |
| 1646 | wr.ext_op.umr.num_mrs = 1; |
| 1647 | wr.ext_op.umr.mem_list.mem_reg_list = &mem_reg; |
| 1648 | wr.ext_op.umr.base_addr = addr; |
| 1649 | wr.exp_send_flags = IBV_EXP_SEND_INLINE; |
| 1650 | |
| 1651 | DO(ibv_exp_post_send(qp.qp, &wr, &bad_wr)); |
| 1652 | } |
| 1653 | }; |
| 1654 | #endif |
| 1655 | |
Artemy Kovalyov | ea26e1c | 2016-06-20 17:14:47 +0300 | [diff] [blame] | 1656 | #endif |
| 1657 | |