blob: d6fccee7ace59895aaf6c389b79d83cec2e48b6d [file] [log] [blame]
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +03001/**
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#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#define __STDC_LIMIT_MACROS
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +030034#include <inttypes.h>
35#include <signal.h>
36#include <stdint.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <sys/mman.h>
41#include <sys/time.h>
42#include <sys/types.h>
43#include <unistd.h>
44
45#include <infiniband/verbs.h>
46
47#include "env.h"
48
Artemy Kovalyov4147f622017-02-27 13:11:03 +020049#if HAVE_DECL_IBV_PREFETCH_MR
Artemy Kovalyov441bd412018-02-24 20:55:49 +020050#define HAVE_PREFETCH 1
Artemy Kovalyov4147f622017-02-27 13:11:03 +020051#define IBV_EXP_PREFETCH_WRITE_ACCESS 0
52#elif HAVE_DECL_IBV_EXP_PREFETCH_MR
Artemy Kovalyov441bd412018-02-24 20:55:49 +020053#define HAVE_PREFETCH 1
Artemy Kovalyov4147f622017-02-27 13:11:03 +020054#define ibv_prefetch_attr ibv_exp_prefetch_attr
55#define ibv_prefetch_mr ibv_exp_prefetch_mr
Artemy Kovalyov441bd412018-02-24 20:55:49 +020056#else
57#define HAVE_PREFETCH 0
Artemy Kovalyov4147f622017-02-27 13:11:03 +020058#endif
59
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +030060struct ibvt_mr_implicit : public ibvt_mr {
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +020061 ibvt_mr_implicit(ibvt_env &e, ibvt_pd &p, long a) :
62 ibvt_mr(e, p, 0, 0, a) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +030063
64 virtual void init() {
Artemy Kovalyova5bfe6f2018-06-03 17:25:12 +030065 DO(!(pd.ctx.dev_attr.odp_caps.general_odp_caps & IBV_ODP_SUPPORT_IMPLICIT));
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +030066 EXEC(pd.init());
Artemy Kovalyov207d0742016-09-13 12:54:47 +030067 SET(mr, ibv_reg_mr(pd.pd, 0, UINT64_MAX, IBV_ACCESS_ON_DEMAND | access_flags));
68 if (mr)
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +020069 VERBS_TRACE("\t\t\t\t\tibv_reg_mr(pd, 0, 0, %lx) = %x\n", access_flags, mr->lkey);
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +030070 }
71};
72
Artemy Kovalyov441bd412018-02-24 20:55:49 +020073#if HAVE_PREFETCH
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +020074struct ibvt_mr_pf : public ibvt_mr {
75 ibvt_mr_pf(ibvt_env &e, ibvt_pd &p, size_t s, intptr_t a, long af) :
76 ibvt_mr(e, p, s, a, af) {}
77
78 virtual void init() {
79 EXEC(ibvt_mr::init());
80
Artemy Kovalyova5bfe6f2018-06-03 17:25:12 +030081 if (env.skip)
82 return;
Artemy Kovalyov4147f622017-02-27 13:11:03 +020083 struct ibv_prefetch_attr attr;
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +020084
85 attr.flags = IBV_EXP_PREFETCH_WRITE_ACCESS;
86 attr.addr = buff;
87 attr.length = size;
88 attr.comp_mask = 0;
Artemy Kovalyov4147f622017-02-27 13:11:03 +020089 DO(ibv_prefetch_mr(mr, &attr));
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +020090 }
91};
92#endif
93
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +000094#if HAVE_DECL_IBV_ACCESS_HUGETLB
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +020095struct ibvt_mr_hp : public ibvt_mr {
96 ibvt_mr_hp(ibvt_env &e, ibvt_pd &p, size_t s, intptr_t a, long af) :
97 ibvt_mr(e, p, s, a, af | IBV_ACCESS_HUGETLB) {}
98
99 virtual int mmap_flags() {
100 return MAP_PRIVATE|MAP_ANON|MAP_HUGETLB;
101 }
102};
103#endif
104
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300105struct ibvt_sub_mr : public ibvt_mr {
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200106 ibvt_mr &master;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300107
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200108 ibvt_sub_mr(ibvt_mr &i, intptr_t a, size_t size) :
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200109 ibvt_mr(i.env, i.pd, size, a), master(i) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300110
111 virtual void init() {
Artemy Kovalyov67cef552017-09-27 09:01:02 +0300112 EXEC(init_mmap());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300113 mr = master.mr;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300114 }
115
116 virtual ~ibvt_sub_mr() {
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300117 mr = NULL;
118 }
119};
120
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200121struct odp_side : public ibvt_obj {
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300122 ibvt_ctx &ctx;
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200123 ibvt_pd &pd;
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200124 int access_flags;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300125
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200126 odp_side(ibvt_env &e, ibvt_ctx &c, ibvt_pd &p, int a) :
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300127 ibvt_obj(e),
128 ctx(c),
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200129 pd(p),
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200130 access_flags(a) {}
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300131
132 virtual ibvt_qp &get_qp() = 0;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300133};
134
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300135template<typename QP>
136struct odp_side_qp : public odp_side {
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300137 ibvt_cq cq;
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300138 QP qp;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300139
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300140 odp_side_qp(ibvt_env &e, ibvt_ctx &c, ibvt_pd &p, int a) :
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300141 odp_side(e, c, p, a),
142 cq(e, ctx),
143 qp(e, pd, cq) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300144
145 virtual void init() {
146 EXEC(qp.init());
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200147 }
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300148
149 virtual ibvt_qp &get_qp() { return qp; }
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200150};
151
152struct odp_mem : public ibvt_obj {
153 odp_side &ssrc;
154 odp_side &sdst;
155
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200156 ibvt_abstract_mr *psrc;
157 ibvt_abstract_mr *pdst;
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200158
159 odp_mem(odp_side &s, odp_side &d) : ibvt_obj(s.env), ssrc(s), sdst(d), psrc(NULL), pdst(NULL) {}
160
161 virtual void init() {}
162 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) = 0;
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200163 virtual ibvt_abstract_mr &src() { return *psrc; }
164 virtual ibvt_abstract_mr &dst() { return *pdst; }
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200165 virtual void unreg() {
166 if (psrc)
167 delete psrc;
168 if (pdst)
169 delete pdst;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300170 }
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300171
172 int num_page_fault_pages;
173 int num_invalidation_pages;
174
175 virtual void check_stats_before() {
176 EXEC(ssrc.ctx.check_debugfs("odp_stats/num_odp_mrs", 2));
177 EXEC(ssrc.ctx.check_debugfs("odp_stats/num_odp_mr_pages", 0));
178 EXEC(ssrc.ctx.read_dev_fs("num_page_fault_pages",
179 &num_page_fault_pages));
180 EXEC(ssrc.ctx.read_dev_fs("num_invalidation_pages",
181 &num_invalidation_pages));
182 }
183
184 virtual void check_stats_after(size_t len) {
185 int pages = (len + PAGE - 1) / PAGE * 2;
186 int i;
187 EXEC(ssrc.ctx.check_debugfs("odp_stats/num_odp_mrs", 2));
188 EXEC(ssrc.ctx.check_dev_fs("num_page_fault_pages",
189 num_page_fault_pages + pages));
190 EXEC(ssrc.ctx.read_dev_fs("num_invalidation_pages",
191 &i));
192 pages -= i - num_invalidation_pages;
193 EXEC(ssrc.ctx.check_debugfs("odp_stats/num_odp_mr_pages", pages));
194 }
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300195};
196
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300197struct odp_trans : public ibvt_obj {
198 odp_trans(ibvt_env &e) : ibvt_obj(e) {}
199
200 virtual void send(ibv_sge sge) = 0;
201 virtual void recv(ibv_sge sge) = 0;
202 virtual void rdma_src(ibv_sge src_sge, ibv_sge dst_sge, enum ibv_wr_opcode opcode) {}
203 virtual void rdma_dst(ibv_sge src_sge, ibv_sge dst_sge, enum ibv_wr_opcode opcode) {}
204 virtual void poll_src() = 0;
205 virtual void poll_dst() = 0;
206};
207
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200208template<typename Ctx>
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300209struct odp_base : public testing::Test, public ibvt_env {
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200210 Ctx ctx;
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200211 ibvt_pd pd;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300212 int src_access_flags;
213 int dst_access_flags;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300214
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300215 odp_base(int s, int d) :
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300216 ctx(*this, NULL),
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200217 pd(*this, ctx),
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300218 src_access_flags(s),
219 dst_access_flags(d) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300220
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200221 virtual odp_mem &mem() = 0;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300222 virtual odp_trans &trans() = 0;
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200223 virtual void test(unsigned long src, unsigned long dst, size_t len, int count = 1) = 0;
Artemy Kovalyov67cef552017-09-27 09:01:02 +0300224 virtual void test_page(unsigned long addr) {
225 EXEC(test(addr, addr + PAGE, PAGE));
226 }
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300227
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200228 virtual void init() {
Artemy Kovalyov207d0742016-09-13 12:54:47 +0300229 INIT(ctx.init());
Artemy Kovalyova5bfe6f2018-06-03 17:25:12 +0300230 DO(!(ctx.dev_attr.odp_caps.general_odp_caps & IBV_ODP_SUPPORT));
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300231 INIT(ctx.init_sysfs());
232 EXEC(ctx.check_debugfs("odp_stats/num_odp_mrs", 0));
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300233 }
234
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200235 virtual void SetUp() {
236 INIT(init());
237 }
238
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300239 virtual void TearDown() {
240 ASSERT_FALSE(HasFailure());
241 }
242};
243
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200244template<typename QP, typename Ctx>
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300245struct odp_qp : public odp_trans {
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300246 ibvt_ctx &ctx;
247 ibvt_pd &pd;
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300248 odp_side_qp<QP> src;
249 odp_side_qp<QP> dst;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300250
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200251 odp_qp(odp_base<Ctx> &e) :
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300252 odp_trans(e),
253 ctx(e.ctx),
254 pd(e.pd),
255 src(e, e.ctx, e.pd, e.src_access_flags),
256 dst(e, e.ctx, e.pd, e.dst_access_flags) {}
257
258 virtual void init() {
259 INIT(src.init());
260 INIT(dst.init());
261 INIT(src.qp.connect(&dst.qp));
262 INIT(dst.qp.connect(&src.qp));
263 }
264
265 virtual void send(ibv_sge sge) { src.qp.send(sge); }
266 virtual void recv(ibv_sge sge) { dst.qp.recv(sge); }
267 virtual void rdma_src(ibv_sge src_sge, ibv_sge dst_sge,
268 enum ibv_wr_opcode opcode) {
269 src.qp.rdma(src_sge, dst_sge, opcode);
270 }
271 virtual void rdma_dst(ibv_sge src_sge, ibv_sge dst_sge,
272 enum ibv_wr_opcode opcode) {
273 dst.qp.rdma(src_sge, dst_sge, opcode);
274 }
Artemy Kovalyov3acead42017-09-27 09:07:49 +0300275 virtual void poll_src() { src.cq.poll(); }
276 virtual void poll_dst() { dst.cq.poll(); }
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300277};
278
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200279typedef odp_qp<ibvt_qp_rc, ibvt_ctx> odp_rc;
280//typedef odp_qp<ibvt_qp_rc, ibvt_ctx_devx> odp_rc_devx;
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300281
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200282#if HAVE_INFINIBAND_VERBS_EXP_H
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300283struct odp_side_dci : public odp_side {
284 ibvt_cq cq;
285 ibvt_qp_dc qp;
286
287 odp_side_dci(ibvt_env &e, ibvt_ctx &c, ibvt_pd &p, int a) :
288 odp_side(e, c, p, a),
289 cq(e, ctx),
290 qp(e, pd, cq) {}
291
292 virtual void init() {
293 EXEC(qp.init());
294 }
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300295
296 virtual ibvt_qp &get_qp() { return qp; }
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300297};
298
299struct odp_side_dct : public odp_side {
300 ibvt_cq cq;
301 ibvt_srq srq;
302 ibvt_dct dct;
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300303 ibvt_qp_rc _qp;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300304
305 odp_side_dct(ibvt_env &e, ibvt_ctx &c, ibvt_pd &p, int a) :
306 odp_side(e, c, p, a),
307 cq(e, ctx),
308 srq(e, pd, cq),
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300309 dct(e, pd, cq, srq),
310 _qp(e, p, cq) {}
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300311
312 virtual void init() {
313 EXEC(dct.init());
314 }
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300315
316 virtual ibvt_qp &get_qp() { return _qp; }
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300317};
318
319struct odp_dc : public odp_trans {
320 ibvt_ctx &ctx;
321 ibvt_pd &pd;
322 odp_side_dci src;
323 odp_side_dct dst;
324
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200325 odp_dc(odp_base<ibvt_ctx> &e) :
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300326 odp_trans(e),
327 ctx(e.ctx),
328 pd(e.pd),
329 src(e, e.ctx, e.pd, e.src_access_flags),
330 dst(e, e.ctx, e.pd, e.dst_access_flags) {}
331
332 virtual void init() {
333 INIT(src.init());
334 INIT(dst.init());
335 INIT(src.qp.connect(&dst.dct));
336 }
337
338 virtual void send(ibv_sge sge) { src.qp.send(sge); }
339 virtual void recv(ibv_sge sge) { dst.srq.recv(sge); }
340 virtual void rdma_src(ibv_sge src_sge, ibv_sge dst_sge,
341 enum ibv_wr_opcode opcode) {
342 src.qp.rdma(src_sge, dst_sge, opcode);
343 }
344 virtual void rdma_dst(ibv_sge src_sge, ibv_sge dst_sge,
345 enum ibv_wr_opcode opcode) {
346 FAIL();
347 }
Artemy Kovalyov3acead42017-09-27 09:07:49 +0300348 virtual void poll_src() { src.cq.poll(); }
349 virtual void poll_dst() { dst.cq.poll(); }
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300350
351};
352#endif
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200353
354struct odp_off : public odp_mem {
355 odp_off(odp_side &s, odp_side &d) : odp_mem(s, d) {}
356
357 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
358 SET(psrc, new ibvt_mr(ssrc.env, ssrc.pd, len, src_addr, ssrc.access_flags));
359 SET(pdst, new ibvt_mr(sdst.env, sdst.pd, len, dst_addr, sdst.access_flags));
360 }
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200361
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300362 virtual void check_stats_before() { }
363 virtual void check_stats_after(size_t len) { }
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200364};
365
366struct odp_explicit : public odp_mem {
367 odp_explicit(odp_side &s, odp_side &d) : odp_mem(s, d) {}
368
369 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
370 SET(psrc, new ibvt_mr(ssrc.env, ssrc.pd, len, src_addr, ssrc.access_flags | IBV_ACCESS_ON_DEMAND));
371 SET(pdst, new ibvt_mr(sdst.env, sdst.pd, len, dst_addr, sdst.access_flags | IBV_ACCESS_ON_DEMAND));
372 }
373};
374
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200375#if HAVE_PREFETCH
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200376struct odp_prefetch : public odp_mem {
377 odp_prefetch(odp_side &s, odp_side &d) : odp_mem(s, d) {}
378
379 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
380 SET(psrc, new ibvt_mr_pf(ssrc.env, ssrc.pd, len, src_addr, ssrc.access_flags | IBV_ACCESS_ON_DEMAND));
381 SET(pdst, new ibvt_mr_pf(sdst.env, sdst.pd, len, dst_addr, sdst.access_flags | IBV_ACCESS_ON_DEMAND));
382 }
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300383
384 virtual void check_stats_before() { }
385 virtual void check_stats_after(size_t len) { }
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200386};
387#endif
388
Artemy-Mellanox409fabc2017-02-19 00:32:51 +0200389
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000390#if HAVE_DECL_IBV_ACCESS_HUGETLB
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200391struct odp_hugetlb : public odp_mem {
392 odp_hugetlb(odp_side &s, odp_side &d) : odp_mem(s, d) {}
393
394 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
395 SET(psrc, new ibvt_mr_hp(ssrc.env, ssrc.pd, len, src_addr, ssrc.access_flags | IBV_ACCESS_ON_DEMAND));
396 SET(pdst, new ibvt_mr_hp(sdst.env, sdst.pd, len, dst_addr, sdst.access_flags | IBV_ACCESS_ON_DEMAND));
397 }
398};
399#endif
400
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200401struct odp_implicit : public odp_mem {
402 ibvt_mr_implicit simr;
403 ibvt_mr_implicit dimr;
404 odp_implicit(odp_side &s, odp_side &d) : odp_mem(s, d),
405 simr(s.env, s.pd, s.access_flags),
406 dimr(d.env, d.pd, d.access_flags) {}
407
408 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
409 SET(psrc, new ibvt_sub_mr(simr, src_addr, len));
410 SET(pdst, new ibvt_sub_mr(dimr, dst_addr, len));
411 }
412 virtual void init() {
413 simr.init();
414 dimr.init();
415 }
Artemy Kovalyov67cef552017-09-27 09:01:02 +0300416};
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200417
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200418#if HAVE_INFINIBAND_VERBS_EXP_H
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300419struct ibvt_qp_rc_umr : public ibvt_qp_rc {
420 ibvt_qp_rc_umr(ibvt_env &e, ibvt_pd &p, ibvt_cq &c) :
421 ibvt_qp_rc(e, p, c) {}
422
423 virtual void init_attr(struct ibv_qp_init_attr_ex &attr) {
424 ibvt_qp_rc::init_attr(attr);
425 attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_CREATE_FLAGS;
426 attr.comp_mask |= IBV_EXP_QP_INIT_ATTR_MAX_INL_KLMS;
427 attr.exp_create_flags |= IBV_EXP_QP_CREATE_UMR;
428 attr.max_inl_send_klms = 3;
429 }
430};
431
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200432typedef odp_qp<ibvt_qp_rc_umr, ibvt_ctx> odp_rc_umr;
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300433
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300434struct odp_implicit_mw : public odp_implicit {
435 odp_implicit_mw(odp_side &s, odp_side &d) :
436 odp_implicit(s, d) {};
437
438 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
439 SET(psrc, new ibvt_mw(simr, src_addr, len, ssrc.get_qp()));
440 SET(pdst, new ibvt_mw(dimr, dst_addr, len, sdst.get_qp()));
441 }
442};
443#endif
444
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200445#define ODP_CHK_SUT(len) \
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200446 CHK_SUT(odp); \
Artemy Kovalyova5bfe6f2018-06-03 17:25:12 +0300447 this->check_ram("MemFree:", len * 3); \
448 this->mem().reg(0,0,len); \
449 this->mem().src().init(); \
450 this->mem().dst().init(); \
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200451 this->mem().unreg();
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200452
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200453
454template<typename Ctx>
455struct odp_send : public odp_base<Ctx> {
Artemy Kovalyov207d0742016-09-13 12:54:47 +0300456 odp_send():
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200457 odp_base<Ctx>(0, IBV_ACCESS_LOCAL_WRITE) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300458
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200459 virtual void test(unsigned long src, unsigned long dst, size_t len, int count = 1) {
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200460 EXEC(mem().reg(src, dst, len));
461 EXEC(mem().src().fill());
462 EXEC(mem().dst().init());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300463
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300464 EXEC(mem().check_stats_before());
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200465 for (int i = 0; i < count; i++) {
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200466 EXEC(trans().recv(this->mem().dst().sge(len/count*i, len/count)));
467 EXEC(trans().send(this->mem().src().sge(len/count*i, len/count)));
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300468 EXEC(trans().poll_src());
469 EXEC(trans().poll_dst());
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200470 }
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300471 EXEC(mem().check_stats_after(len));
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200472 EXEC(mem().dst().check());
473 EXEC(mem().unreg());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300474 }
475};
476
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200477template<typename Ctx>
478struct odp_rdma_read : public odp_base<Ctx> {
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300479 odp_rdma_read():
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200480 odp_base<Ctx>(IBV_ACCESS_REMOTE_READ, IBV_ACCESS_LOCAL_WRITE) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300481
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200482 virtual void test(unsigned long src, unsigned long dst, size_t len, int count = 1) {
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200483 EXEC(mem().reg(src, dst, len));
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200484 EXEC(mem().dst().init());
Artemy Kovalyov67cef552017-09-27 09:01:02 +0300485 EXEC(mem().src().fill());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300486
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300487 EXEC(mem().check_stats_before());
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200488 for (int i = 0; i < count; i++) {
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200489 EXEC(trans().rdma_dst(this->mem().dst().sge(len/count*i, len/count),
490 this->mem().src().sge(len/count*i, len/count),
491 IBV_WR_RDMA_READ));
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300492 EXEC(trans().poll_dst());
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200493 }
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300494 EXEC(mem().check_stats_after(len));
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200495 EXEC(mem().dst().check());
496 EXEC(mem().unreg());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300497 }
498};
499
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200500template<typename Ctx>
501struct odp_rdma_write : public odp_base<Ctx> {
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300502 odp_rdma_write():
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200503 odp_base<Ctx>(0, IBV_ACCESS_LOCAL_WRITE|IBV_ACCESS_REMOTE_WRITE) {}
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300504
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200505 virtual void test(unsigned long src, unsigned long dst, size_t len, int count = 1) {
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200506 EXEC(mem().reg(src, dst, len));
507 EXEC(mem().src().fill());
508 EXEC(mem().dst().init());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300509
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300510 EXEC(mem().check_stats_before());
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200511 for (int i = 0; i < count; i++) {
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200512 EXEC(trans().rdma_src(this->mem().src().sge(len/count*i, len/count),
513 this->mem().dst().sge(len/count*i, len/count),
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200514 IBV_WR_RDMA_WRITE));
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300515 EXEC(trans().poll_src());
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200516 }
Artemy Kovalyovc0206e62017-09-13 13:34:04 +0300517 EXEC(mem().check_stats_after(len));
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200518 EXEC(mem().dst().check());
519 EXEC(mem().unreg());
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300520 }
521};
522
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300523template <typename T1, typename T2, typename T3>
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200524struct types {
525 typedef T1 MEM;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300526 typedef T2 TRANS;
527 typedef T3 OP;
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200528};
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300529
530template <typename T>
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200531struct odp : public T::OP {
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300532 typename T::TRANS _trans;
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200533 typename T::MEM _mem;
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300534 odp():
535 T::OP(),
536 _trans(*this),
537 _mem(_trans.src, _trans.dst) {}
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200538 odp_mem &mem() { return _mem; }
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300539 odp_trans &trans() { return _trans; }
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200540 virtual void init() {
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200541 INIT(T::OP::init());
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300542 INIT(_trans.init());
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200543 INIT(_mem.init());
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200544 }
545};
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300546
547typedef testing::Types<
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200548 types<odp_explicit, odp_rc, odp_send<ibvt_ctx> >,
549 types<odp_explicit, odp_rc, odp_rdma_read<ibvt_ctx> >,
550 types<odp_explicit, odp_rc, odp_rdma_write<ibvt_ctx> >,
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200551#if HAVE_PREFETCH
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200552 types<odp_prefetch, odp_rc, odp_send<ibvt_ctx> >,
553 types<odp_prefetch, odp_rc, odp_rdma_read<ibvt_ctx> >,
554 types<odp_prefetch, odp_rc, odp_rdma_write<ibvt_ctx> >,
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200555#endif
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200556 types<odp_implicit, odp_rc, odp_send<ibvt_ctx> >,
557 types<odp_implicit, odp_rc, odp_rdma_read<ibvt_ctx> >,
558 types<odp_implicit, odp_rc, odp_rdma_write<ibvt_ctx> >,
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000559#if HAVE_DECL_IBV_ACCESS_HUGETLB
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200560 types<odp_hugetlb, odp_rc, odp_send<ibvt_ctx> >,
561 types<odp_hugetlb, odp_rc, odp_rdma_read<ibvt_ctx> >,
562 types<odp_hugetlb, odp_rc, odp_rdma_write<ibvt_ctx> >,
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200563#endif
Artemy Kovalyov441bd412018-02-24 20:55:49 +0200564#if HAVE_INFINIBAND_VERBS_EXP_H
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200565 types<odp_explicit, odp_dc, odp_rdma_write<ibvt_ctx> >,
566 types<odp_implicit, odp_dc, odp_rdma_write<ibvt_ctx> >,
567 types<odp_off, odp_dc, odp_send<ibvt_ctx> >,
568 types<odp_off, odp_dc, odp_rdma_write<ibvt_ctx> >,
Artemy Kovalyovfa8102d2017-08-10 15:41:49 +0300569
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200570 types<odp_implicit_mw, odp_rc_umr, odp_send<ibvt_ctx> >,
571 types<odp_implicit_mw, odp_rc_umr, odp_rdma_read<ibvt_ctx> >,
572 types<odp_implicit_mw, odp_rc_umr, odp_rdma_write<ibvt_ctx> >,
Artemy Kovalyova4bd4252017-07-15 12:34:20 +0300573#endif
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200574 types<odp_off, odp_rc, odp_send<ibvt_ctx> >,
575 types<odp_off, odp_rc, odp_rdma_read<ibvt_ctx> >,
576 types<odp_off, odp_rc, odp_rdma_write<ibvt_ctx> >
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300577> odp_env_list;
578
579TYPED_TEST_CASE(odp, odp_env_list);
580
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200581TYPED_TEST(odp, t0_crossbound) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200582 ODP_CHK_SUT(PAGE);
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000583 EXEC(test((1ULL<<(32+1))-PAGE,
584 (1ULL<<(32+2))-PAGE,
Artemy Kovalyov67cef552017-09-27 09:01:02 +0300585 PAGE * 2));
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300586}
587
Artemy Kovalyove69018f2016-11-17 16:17:29 +0200588TYPED_TEST(odp, t1_upper) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200589 ODP_CHK_SUT(PAGE);
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000590 EXEC(test(UP - 0x10000 * 1,
591 UP - 0x10000 * 2,
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300592 0x2000));
593}
594
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200595TYPED_TEST(odp, t2_sequence) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200596 ODP_CHK_SUT(PAGE);
Artemy Kovalyovfc636ed2016-11-27 13:16:39 +0200597 unsigned long p = 0x2000000000;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300598 for (int i = 0; i < 20; i++) {
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000599 EXEC(test(p, p+PAGE, PAGE));
600 p += PAGE * 2;
Artemy Kovalyov062c3ef2016-08-29 11:14:47 +0300601 }
602}
603
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000604TYPED_TEST(odp, t3_1b) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200605 ODP_CHK_SUT(PAGE);
Artemy Kovalyov8b8ef172017-02-13 13:46:22 +0000606 unsigned long p = 0x2000000000;
607 EXEC(test(p, p+PAGE, PAGE, PAGE/0x10));
608}
609
610TYPED_TEST(odp, t4_6M) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200611 ODP_CHK_SUT(0x600000);
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200612 EXEC(test(0,0,0x600000,0x10));
613}
614
Artemy Kovalyov4df9b3b2017-08-27 16:32:13 +0300615template <typename T>
616struct odp_long : public odp<T> { odp_long(): odp<T>() {} };
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200617
Artemy Kovalyov4df9b3b2017-08-27 16:32:13 +0300618typedef testing::Types<
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200619 types<odp_explicit, odp_rc, odp_send<ibvt_ctx> >,
620 types<odp_implicit, odp_rc, odp_send<ibvt_ctx> >,
Artemy Kovalyov4df9b3b2017-08-27 16:32:13 +0300621#if HAVE_DECL_IBV_ACCESS_HUGETLB
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200622 types<odp_hugetlb, odp_rc, odp_send<ibvt_ctx> >,
Artemy Kovalyov4df9b3b2017-08-27 16:32:13 +0300623#endif
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200624 types<odp_off, odp_rc, odp_send<ibvt_ctx> >
Artemy Kovalyov4df9b3b2017-08-27 16:32:13 +0300625> odp_env_list_long;
626
627TYPED_TEST_CASE(odp_long, odp_env_list_long);
628
629TYPED_TEST(odp_long, t5_3G) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200630 ODP_CHK_SUT(0xe0000000);
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200631 EXEC(test(0, 0,
632 0xe0000000,
633 0x10));
634}
635
Artemy Kovalyov4df9b3b2017-08-27 16:32:13 +0300636TYPED_TEST(odp_long, t6_16Gplus) {
Artemy Kovalyov8d830982017-03-09 12:22:04 +0200637 ODP_CHK_SUT(0x400000100);
Artemy Kovalyova36c8fe2017-01-23 21:45:45 +0200638 EXEC(test(0, 0,
639 0x400000100,
640 0x100));
641}
642
Artemy Kovalyov5985a672018-04-28 20:08:24 +0000643#if HAVE_INFINIBAND_VERBS_EXP_H
644struct odp_implicit_mw_1imr : public odp_mem {
645 ibvt_mr_implicit imr;
646
647 odp_implicit_mw_1imr(odp_side &s, odp_side &d) : odp_mem(s, d),
648 imr(s.env, s.pd, s.access_flags | d.access_flags) {}
649
650 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
651 SET(psrc, new ibvt_mw(imr, src_addr, len, ssrc.get_qp()));
652 SET(pdst, new ibvt_mw(imr, dst_addr, len, sdst.get_qp()));
653 }
654
655 virtual void init() {
656 imr.init();
657 }
658};
659
660struct odp_persist : public odp_mem {
661 ibvt_mr *smr;
662 ibvt_mr *dmr;
663
664 odp_persist(odp_side &s, odp_side &d) : odp_mem(s, d), smr(NULL), dmr(NULL) {}
665
666 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
667 if (!smr) {
668 SET(smr, new ibvt_mr(ssrc.env, ssrc.pd, len, src_addr, ssrc.access_flags | IBV_ACCESS_ON_DEMAND));
669 SET(dmr, new ibvt_mr(sdst.env, sdst.pd, len, dst_addr, sdst.access_flags | IBV_ACCESS_ON_DEMAND));
670 smr->init();
671 dmr->init();
672 }
673 SET(psrc, new ibvt_sub_mr(*smr, src_addr, len));
674 SET(pdst, new ibvt_sub_mr(*dmr, dst_addr, len));
675 }
676
677 ~odp_persist() {
678 if (smr)
679 delete smr;
680 if (dmr)
681 delete dmr;
682 }
683};
684
685template <typename T>
686struct odp_spec : public odp<T> { odp_spec(): odp<T>() {} };
687
688typedef testing::Types<
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200689 //types<odp_implicit_mw_1imr, odp_rc_umr, odp_send<ibvt_ctx> >
690 //types<odp_persist, odp_rc, odp_send<ibvt_ctx> >,
691 //types<odp_persist, odp_rc, odp_rdma_read<ibvt_ctx> >,
692 //types<odp_persist, odp_rc, odp_rdma_write<ibvt_ctx> >
693 types<odp_implicit, odp_rc, odp_send<ibvt_ctx> >,
694 types<odp_implicit, odp_rc, odp_rdma_read<ibvt_ctx> >,
695 types<odp_implicit, odp_rc, odp_rdma_write<ibvt_ctx> >
Artemy Kovalyov5985a672018-04-28 20:08:24 +0000696> odp_env_list_spec;
697
698TYPED_TEST_CASE(odp_spec, odp_env_list_spec);
699
700TYPED_TEST(odp_spec, s0) {
701 ODP_CHK_SUT(PAGE);
702 unsigned long p = 0x2000000000;
703 for (int i = 0; i < 20000; i++)
704 EXEC(test(p, p+0x40000, 0x40000));
705}
706#endif
707
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200708#if HAVE_DECL_MLX5DV_CONTEXT_FLAGS_DEVX
709#include "../devx/devx_prm.h"
710
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200711#if 0
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200712enum {
713 MLX5_WQE_UMR_CTRL_FLAG_INLINE = 1 << 7,
714 MLX5_WQE_UMR_CTRL_FLAG_CHECK_FREE = 1 << 5,
715 MLX5_WQE_UMR_CTRL_FLAG_TRNSLATION_OFFSET = 1 << 4,
716 MLX5_WQE_UMR_CTRL_FLAG_CHECK_QPN = 1 << 3,
717};
718
719enum {
720 MLX5_WQE_UMR_CTRL_MKEY_MASK_LEN = 1 << 0,
721 MLX5_WQE_UMR_CTRL_MKEY_MASK_START_ADDR = 1 << 6,
722 MLX5_WQE_UMR_CTRL_MKEY_MASK_MKEY = 1 << 13,
723 MLX5_WQE_UMR_CTRL_MKEY_MASK_QPN = 1 << 14,
724 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_LOCAL_WRITE = 1 << 18,
725 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_REMOTE_READ = 1 << 19,
726 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_REMOTE_WRITE = 1 << 20,
727 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_ATOMIC = 1 << 21,
728 MLX5_WQE_UMR_CTRL_MKEY_MASK_FREE = 1 << 29,
729};
730
731enum {
732 MLX5_UMR_CTRL_INLINE = 1 << 7,
733};
734
735struct mlx5_wqe_umr_ctrl_seg {
736 uint8_t flags;
737 uint8_t rsvd0[3];
738 __be16 klm_octowords;
739 __be16 translation_offset;
740 __be64 mkey_mask;
741 uint8_t rsvd1[32];
742};
743
744struct mlx5_wqe_umr_klm_seg {
745 /* up to 2GB */
746 __be32 byte_count;
747 __be32 mkey;
748 __be64 address;
749};
750
751union mlx5_wqe_umr_inline_seg {
752 struct mlx5_wqe_umr_klm_seg klm;
753};
754
755enum {
756 MLX5_WQE_MKEY_CONTEXT_FREE = 1 << 6
757};
758
759enum {
760 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_ATOMIC = 1 << 6,
761 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_REMOTE_WRITE = 1 << 5,
762 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_REMOTE_READ = 1 << 4,
763 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_LOCAL_WRITE = 1 << 3,
764 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_LOCAL_READ = 1 << 2
765};
766
767struct mlx5_wqe_mkey_context_seg {
768 uint8_t free;
769 uint8_t reserved1;
770 uint8_t access_flags;
771 uint8_t sf;
772 __be32 qpn_mkey;
773 __be32 reserved2;
774 __be32 flags_pd;
775 __be64 start_addr;
776 __be64 len;
777 __be32 bsf_octword_size;
778 __be32 reserved3[4];
779 __be32 translations_octword_size;
780 uint8_t reserved4[3];
781 uint8_t log_page_size;
782 __be32 reserved;
783 union mlx5_wqe_umr_inline_seg inseg[0];
784};
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200785#endif
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200786
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200787static inline int ilog2(int n)
788{
789 int t;
790
791 if (n <= 0)
792 return -1;
793
794 t = 0;
795 while ((1 << t) < n)
796 ++t;
797
798 return t;
799}
800
801struct devx_indirect_mr : public ibvt_abstract_mr {
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200802 struct mlx5dv_devx_obj *dvmr;
803 ibvt_mr &sub_mr;
804 ibvt_qp &umr_qp;
805 uint32_t mkey;
806
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200807 devx_indirect_mr(ibvt_mr &m, ibvt_qp &q) :
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200808 ibvt_abstract_mr(m.env, m.size, m.addr),
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200809 dvmr(NULL),
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200810 sub_mr(m),
811 umr_qp(q) {}
812
813 virtual void init() {
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200814 uint32_t in[DEVX_ST_SZ_DW(create_mkey_in) + 0x20] = {0};
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200815 uint32_t out[DEVX_ST_SZ_DW(create_mkey_out)] = {0};
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200816 sub_mr.init();
817
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200818 buff = (char *)sub_mr.buff;
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200819
820 DEVX_SET(create_mkey_in, in, opcode, MLX5_CMD_OP_CREATE_MKEY);
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200821 set_mkc(DEVX_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry));
822
823 set_klm(in);
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200824
825 SET(dvmr, mlx5dv_devx_obj_create(sub_mr.pd.ctx.ctx, in, sizeof(in), out, sizeof(out)));
826 mkey = DEVX_GET(create_mkey_out, out, mkey_index) << 8 | 0x42;
827
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200828 INIT(umr());
829 }
830
831 virtual void set_mkc(char *mkc) {
832 struct mlx5dv_obj dv = {};
833 struct mlx5dv_pd dvpd = {};
834
835 dv.pd.in = sub_mr.pd.pd;
836 dv.pd.out = &dvpd;
837 mlx5dv_init_obj(&dv, MLX5DV_OBJ_PD);
838
839 DEVX_SET(mkc, mkc, a, 1);
840 DEVX_SET(mkc, mkc, rw, 1);
841 DEVX_SET(mkc, mkc, rr, 1);
842 DEVX_SET(mkc, mkc, lw, 1);
843 DEVX_SET(mkc, mkc, lr, 1);
844 DEVX_SET(mkc, mkc, pd, dvpd.pdn);
845 DEVX_SET(mkc, mkc, translations_octword_size, 2);
846 DEVX_SET(mkc, mkc, qpn, 0xffffff);
847 DEVX_SET(mkc, mkc, mkey_7_0, 0x42);
848 }
849
850 virtual void set_klm(uint32_t *in) {
851 struct mlx5_wqe_data_seg *dseg = (struct mlx5_wqe_data_seg *)DEVX_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
852 mlx5dv_set_data_seg(dseg, size / 2, sub_mr.mr->lkey, (intptr_t)buff);
853 mlx5dv_set_data_seg(dseg + 1, size / 2, sub_mr.mr->lkey, (intptr_t)buff + size / 2);
854
855 DEVX_SET(create_mkey_in, in, translations_octword_actual_size, 2);
856 }
857
858 virtual void umr() {
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200859 struct mlx5_wqe_ctrl_seg *ctrl = (struct mlx5_wqe_ctrl_seg *)umr_qp.get_wqe(0);
860 mlx5dv_set_ctrl_seg(ctrl, umr_qp.sqi, MLX5_OPCODE_UMR, 0, umr_qp.qp->qp_num, 0, 12, 0, htobe32(mkey));
861
862 struct mlx5_wqe_umr_ctrl_seg *umr = (struct mlx5_wqe_umr_ctrl_seg *)(ctrl + 1);
863 umr->flags = MLX5_WQE_UMR_CTRL_FLAG_INLINE;
864 umr->mkey_mask = htobe64(MLX5_WQE_UMR_CTRL_MKEY_MASK_LEN |
865 MLX5_WQE_UMR_CTRL_MKEY_MASK_START_ADDR |
866 MLX5_WQE_UMR_CTRL_MKEY_MASK_MKEY |
867 MLX5_WQE_UMR_CTRL_MKEY_MASK_QPN |
868 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_LOCAL_WRITE |
869 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_REMOTE_READ |
870 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_REMOTE_WRITE |
871 MLX5_WQE_UMR_CTRL_MKEY_MASK_ACCESS_ATOMIC |
872 MLX5_WQE_UMR_CTRL_MKEY_MASK_FREE);
873 umr->klm_octowords = htobe16(4);
874
875 struct mlx5_wqe_mkey_context_seg *mk = (struct mlx5_wqe_mkey_context_seg *)umr_qp.get_wqe(1);
876 mk->access_flags =
877 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_ATOMIC |
878 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_REMOTE_WRITE |
879 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_REMOTE_READ |
880 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_LOCAL_WRITE |
881 MLX5_WQE_MKEY_CONTEXT_ACCESS_FLAGS_LOCAL_READ;
882 mk->qpn_mkey = htobe32(0xffffff42);
883 mk->start_addr = htobe64((intptr_t)buff);
884 mk->len = htobe64(size);
885
886 struct mlx5_wqe_data_seg *dseg = (struct mlx5_wqe_data_seg *)umr_qp.get_wqe(2);
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200887 mlx5dv_set_data_seg(dseg, size / 2, sub_mr.mr->lkey, (intptr_t)buff);
888 mlx5dv_set_data_seg(dseg + 1, size / 2, sub_mr.mr->lkey, (intptr_t)buff + size / 2);
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200889
890 umr_qp.ring_db(3);
891 }
892
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200893 ~devx_indirect_mr() {
894 if (dvmr)
895 mlx5dv_devx_obj_destroy(dvmr);
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200896 }
897
898 virtual uint32_t lkey() {
899 return mkey;
900 }
901};
902
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200903struct devx_klm_umr : public devx_indirect_mr {
904 devx_klm_umr(ibvt_mr &m, ibvt_qp &q) : devx_indirect_mr(m, q) {}
905
906 virtual void set_mkc(char *mkc) {
907 devx_indirect_mr::set_mkc(mkc);
908
909 DEVX_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KLMS);
910 DEVX_SET(mkc, mkc, free, 1);
911 DEVX_SET(mkc, mkc, umr_en, 1);
912 }
913
914 virtual void set_klm(uint32_t *in) {}
915};
916
917struct devx_klm : public devx_indirect_mr {
918 devx_klm(ibvt_mr &m, ibvt_qp &q) : devx_indirect_mr(m, q) {}
919
920 virtual void set_mkc(char *mkc) {
921 devx_indirect_mr::set_mkc(mkc);
922
923 DEVX_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KLMS);
924 DEVX_SET64(mkc, mkc, start_addr, (intptr_t)buff);
925 DEVX_SET64(mkc, mkc, len, size);
926 }
927
928 virtual void umr() {}
929};
930
931struct devx_ksm_umr : public devx_indirect_mr {
932 devx_ksm_umr(ibvt_mr &m, ibvt_qp &q) : devx_indirect_mr(m, q) {}
933
934 virtual void set_mkc(char *mkc) {
935 devx_indirect_mr::set_mkc(mkc);
936
937 DEVX_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KSM);
938 DEVX_SET(mkc, mkc, log_entity_size, ilog2(size));
939 DEVX_SET(mkc, mkc, free, 1);
940 DEVX_SET(mkc, mkc, umr_en, 1);
941 }
942
943 virtual void set_klm(uint32_t *in) {}
944};
945
946struct devx_ksm : public devx_indirect_mr {
947 devx_ksm(ibvt_mr &m, ibvt_qp &q) : devx_indirect_mr(m, q) {}
948
949 virtual void set_mkc(char *mkc) {
950 devx_indirect_mr::set_mkc(mkc);
951
952 DEVX_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KSM);
953 DEVX_SET(mkc, mkc, log_entity_size, ilog2(size));
954 DEVX_SET64(mkc, mkc, start_addr, (intptr_t)buff);
955 DEVX_SET64(mkc, mkc, len, size);
956 }
957
958 virtual void umr() {}
959};
960
961template <typename Mem, typename Mr>
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200962struct odp_mem_devx : public Mem {
963 ibvt_mr *fsrc;
964 ibvt_mr *fdst;
965 ibvt_cq umr_cq;
966 ibvt_qp_rc umr_qp;
967
968 odp_mem_devx(odp_side &s, odp_side &d) : Mem(s, d),
969 fsrc(NULL), fdst(NULL),
970 umr_cq(s.env, s.ctx),
971 umr_qp(s.env, s.pd, umr_cq) {}
972
973 virtual void init() {
974 INIT(Mem::init());
975 if (this->env.skip)
976 return;
977 INIT(umr_cq.init());
978 INIT(umr_qp.init());
979 INIT(umr_qp.connect(&umr_qp));
980 }
981
982 virtual void reg(unsigned long src_addr, unsigned long dst_addr, size_t len) {
983 EXEC(Mem::reg(src_addr, dst_addr, len));
984
985 fsrc = (ibvt_mr *)this->psrc;
986 fdst = (ibvt_mr *)this->pdst;
987
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200988 SET(this->psrc, new Mr(*fsrc, umr_qp));
989 SET(this->pdst, new Mr(*fdst, umr_qp));
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200990 }
991
992 virtual void unreg() {
Artemy Kovalyov9bc15682018-12-17 20:28:28 +0200993 EXEC(Mem::unreg());
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200994 if (fsrc)
995 delete fsrc;
996 if (fdst)
997 delete fdst;
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +0200998 }
999
1000 virtual void check_stats_before() { }
1001 virtual void check_stats_after(size_t len) { }
1002};
1003
1004typedef odp_qp<ibvt_qp_rc, ibvt_ctx_devx> odp_rc_devx;
1005
1006template <typename T>
1007struct odp_devx : public odp<T> { odp_devx(): odp<T>() {} };
1008
1009typedef testing::Types<
Artemy Kovalyov9bc15682018-12-17 20:28:28 +02001010 types<odp_mem_devx<odp_off, devx_klm>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1011 types<odp_mem_devx<odp_off, devx_klm>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1012 types<odp_mem_devx<odp_off, devx_klm>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1013 types<odp_mem_devx<odp_explicit, devx_klm>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1014 types<odp_mem_devx<odp_explicit, devx_klm>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1015 types<odp_mem_devx<odp_explicit, devx_klm>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1016 types<odp_mem_devx<odp_implicit, devx_klm>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1017 types<odp_mem_devx<odp_implicit, devx_klm>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1018 types<odp_mem_devx<odp_implicit, devx_klm>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1019 types<odp_mem_devx<odp_off, devx_ksm>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1020 types<odp_mem_devx<odp_off, devx_ksm>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1021 types<odp_mem_devx<odp_off, devx_ksm>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1022 types<odp_mem_devx<odp_explicit, devx_ksm>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1023 types<odp_mem_devx<odp_explicit, devx_ksm>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1024 types<odp_mem_devx<odp_explicit, devx_ksm>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1025 types<odp_mem_devx<odp_implicit, devx_ksm>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1026 types<odp_mem_devx<odp_implicit, devx_ksm>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1027 types<odp_mem_devx<odp_implicit, devx_ksm>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1028 types<odp_mem_devx<odp_off, devx_klm_umr>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1029 types<odp_mem_devx<odp_off, devx_klm_umr>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1030 types<odp_mem_devx<odp_off, devx_klm_umr>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1031 types<odp_mem_devx<odp_explicit, devx_klm_umr>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1032 types<odp_mem_devx<odp_explicit, devx_klm_umr>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1033 types<odp_mem_devx<odp_explicit, devx_klm_umr>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1034 types<odp_mem_devx<odp_implicit, devx_klm_umr>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1035 types<odp_mem_devx<odp_implicit, devx_klm_umr>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1036 types<odp_mem_devx<odp_implicit, devx_klm_umr>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1037 types<odp_mem_devx<odp_off, devx_ksm_umr>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1038 types<odp_mem_devx<odp_off, devx_ksm_umr>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1039 types<odp_mem_devx<odp_off, devx_ksm_umr>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1040 types<odp_mem_devx<odp_explicit, devx_ksm_umr>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1041 types<odp_mem_devx<odp_explicit, devx_ksm_umr>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1042 types<odp_mem_devx<odp_explicit, devx_ksm_umr>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >,
1043 types<odp_mem_devx<odp_implicit, devx_ksm_umr>, odp_rc_devx, odp_send<ibvt_ctx_devx> >,
1044 types<odp_mem_devx<odp_implicit, devx_ksm_umr>, odp_rc_devx, odp_rdma_read<ibvt_ctx_devx> >,
1045 types<odp_mem_devx<odp_implicit, devx_ksm_umr>, odp_rc_devx, odp_rdma_write<ibvt_ctx_devx> >
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +02001046> odp_devx_list_spec;
1047
1048TYPED_TEST_CASE(odp_devx, odp_devx_list_spec);
1049
1050TYPED_TEST(odp_devx, t0_crossbound) {
1051 ODP_CHK_SUT(PAGE);
1052 EXEC(test((1ULL<<(32+1))-PAGE,
1053 (1ULL<<(32+2))-PAGE,
1054 PAGE * 2));
1055}
Artemy Kovalyov9bc15682018-12-17 20:28:28 +02001056
1057TYPED_TEST(odp_devx, t1_upper) {
1058 ODP_CHK_SUT(PAGE);
1059 EXEC(test(UP - 0x10000 * 1,
1060 UP - 0x10000 * 2,
1061 0x2000));
1062}
1063
1064TYPED_TEST(odp_devx, t2_sequence) {
1065 ODP_CHK_SUT(PAGE);
1066 unsigned long p = 0x2000000000;
1067 for (int i = 0; i < 20; i++) {
1068 EXEC(test(p, p+PAGE, PAGE));
1069 p += PAGE * 2;
1070 }
1071}
1072
1073TYPED_TEST(odp_devx, t3_1b) {
1074 ODP_CHK_SUT(PAGE);
1075 unsigned long p = 0x2000000000;
1076 EXEC(test(p, p+PAGE, PAGE, PAGE/0x10));
1077}
1078
1079TYPED_TEST(odp_devx, t4_6M) {
1080 ODP_CHK_SUT(0x600000);
1081 EXEC(test(0,0,0x600000,0x10));
1082}
1083
Artemy Kovalyovcec4ef92018-12-12 09:41:01 +02001084#endif
1085