This source file includes following definitions.
- btl_portals4_init_interface
- create_endpoint
- create_peer_and_endpoint
- create_maptable
- mca_btl_portals4_add_procs
- mca_btl_portals4_del_procs
- mca_btl_portals4_alloc
- mca_btl_portals4_free
- mca_btl_portals4_prepare_src
- mca_btl_portals4_register_mem
- mca_btl_portals4_deregister_mem
- mca_btl_portals4_finalize
- mca_btl_portals4_free_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "opal_config.h"
26
27 #include <sys/types.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include "opal_stdint.h"
31
32 #include "opal/class/opal_bitmap.h"
33 #include "opal/constants.h"
34 #include "opal/mca/btl/btl.h"
35 #include "opal/datatype/opal_convertor.h"
36 #include "opal/util/proc.h"
37 #include "opal/mca/pmix/pmix.h"
38
39 #include "btl_portals4.h"
40 #include "btl_portals4_recv.h"
41
42
43 mca_btl_base_registration_handle_t *
44 mca_btl_portals4_register_mem(mca_btl_base_module_t *btl,
45 mca_btl_base_endpoint_t *endpoint,
46 void *base,
47 size_t size,
48 uint32_t flags);
49
50 int mca_btl_portals4_deregister_mem(mca_btl_base_module_t *btl,
51 mca_btl_base_registration_handle_t *handle);
52
53 mca_btl_portals4_module_t mca_btl_portals4_module = {
54 .super = {
55 .btl_component = &mca_btl_portals4_component.super,
56
57
58
59
60 .btl_add_procs = mca_btl_portals4_add_procs,
61 .btl_del_procs = mca_btl_portals4_del_procs,
62 .btl_finalize = mca_btl_portals4_finalize,
63 .btl_alloc = mca_btl_portals4_alloc,
64 .btl_free = mca_btl_portals4_free,
65 .btl_prepare_src = mca_btl_portals4_prepare_src,
66 .btl_register_mem = mca_btl_portals4_register_mem,
67 .btl_deregister_mem = mca_btl_portals4_deregister_mem,
68 .btl_send = mca_btl_portals4_send,
69 .btl_get = mca_btl_portals4_get,
70 .btl_dump = mca_btl_base_dump,
71 },
72 };
73
74 static int
75 btl_portals4_init_interface(void)
76 {
77 mca_btl_portals4_module_t *portals4_btl;
78 unsigned int ret, interface;
79 ptl_md_t md;
80 ptl_me_t me;
81
82
83 for (interface=0; interface<mca_btl_portals4_component.num_btls; interface++) {
84 portals4_btl = mca_btl_portals4_component.btls[interface];
85
86
87 ret = PtlEQAlloc(portals4_btl->portals_ni_h,
88 mca_btl_portals4_component.recv_queue_size,
89 &portals4_btl->recv_eq_h);
90 if (PTL_OK != ret) {
91 opal_output_verbose(1, opal_btl_base_framework.framework_output,
92 "%s:%d: PtlEQAlloc failed for NI %d: %d",
93 __FILE__, __LINE__, interface, ret);
94 goto error;
95 }
96 mca_btl_portals4_component.eqs_h[interface] = portals4_btl->recv_eq_h;
97 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
98 "PtlEQAlloc (recv_eq=%d) OK for NI %d\n", portals4_btl->recv_eq_h, interface));
99
100
101 ret = PtlPTAlloc(portals4_btl->portals_ni_h,
102 PTL_PT_ONLY_TRUNCATE,
103 portals4_btl->recv_eq_h,
104 REQ_BTL_TABLE_ID,
105 &portals4_btl->recv_idx);
106 if (PTL_OK != ret) {
107 opal_output_verbose(1, opal_btl_base_framework.framework_output,
108 "%s:%d: PtlPTAlloc failed for NI %d: %d",
109 __FILE__, __LINE__, interface, ret);
110 goto error;
111 }
112 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
113 "PtlPTAlloc (recv_idx) OK for NI %d recv_idx=%d", interface, portals4_btl->recv_idx));
114
115 if (portals4_btl->recv_idx != REQ_BTL_TABLE_ID) {
116 opal_output_verbose(1, opal_btl_base_framework.framework_output,
117 "%s:%d: PtlPTAlloc did not allocate the requested PT: %d",
118 __FILE__, __LINE__, portals4_btl->recv_idx);
119 goto error;
120 }
121
122
123 md.start = NULL;
124 md.length = 0;
125 md.options = 0;
126 md.eq_handle = PTL_EQ_NONE;
127 md.ct_handle = PTL_CT_NONE;
128
129 ret = PtlMDBind(portals4_btl->portals_ni_h,
130 &md,
131 &portals4_btl->zero_md_h);
132 if (PTL_OK != ret) {
133 opal_output_verbose(1, opal_btl_base_framework.framework_output,
134 "%s:%d: PtlMDBind failed for NI %d: %d",
135 __FILE__, __LINE__, interface, ret);
136 goto error;
137 }
138 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
139 "PtlMDBind (zero-length md=%d) OK for NI %d", portals4_btl->zero_md_h, interface));
140
141
142 md.start = 0;
143 md.length = PTL_SIZE_MAX;
144 md.options = 0;
145 md.eq_handle = portals4_btl->recv_eq_h;
146 md.ct_handle = PTL_CT_NONE;
147
148 ret = PtlMDBind(portals4_btl->portals_ni_h,
149 &md,
150 &portals4_btl->send_md_h);
151 if (PTL_OK != ret) {
152 opal_output_verbose(1, opal_btl_base_framework.framework_output,
153 "%s:%d: PtlMDBind failed for NI %d: %d\n",
154 __FILE__, __LINE__, interface, ret);
155 goto error;
156 }
157
158
159 me.start = NULL;
160 me.length = 0;
161 me.ct_handle = PTL_CT_NONE;
162 me.min_free = 0;
163 me.uid = PTL_UID_ANY;
164 me.options = PTL_ME_OP_PUT |
165 PTL_ME_EVENT_LINK_DISABLE |
166 PTL_ME_EVENT_COMM_DISABLE |
167 PTL_ME_EVENT_UNLINK_DISABLE;
168 if (mca_btl_portals4_component.use_logical) {
169 me.match_id.rank = PTL_RANK_ANY;
170 } else {
171 me.match_id.phys.nid = PTL_NID_ANY;
172 me.match_id.phys.pid = PTL_PID_ANY;
173 }
174 me.match_bits = BTL_PORTALS4_LONG_MSG;
175 me.ignore_bits = BTL_PORTALS4_CONTEXT_MASK |
176 BTL_PORTALS4_SOURCE_MASK |
177 BTL_PORTALS4_TAG_MASK;
178 ret = PtlMEAppend(portals4_btl->portals_ni_h,
179 portals4_btl->recv_idx,
180 &me,
181 PTL_OVERFLOW_LIST,
182 NULL,
183 &portals4_btl->long_overflow_me_h);
184 if (PTL_OK != ret) {
185 opal_output_verbose(1, opal_btl_base_framework.framework_output,
186 "%s:%d: PtlMEAppend failed for NI %d: %d",
187 __FILE__, __LINE__, interface, ret);
188 goto error;
189 }
190 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlMEAppend (overflow list) OK for NI %d", interface));
191 }
192
193 ret = mca_btl_portals4_recv_enable(portals4_btl);
194 if (PTL_OK != ret) {
195 opal_output_verbose(1, opal_btl_base_framework.framework_output,
196 "%s:%d: Initialization of recv buffer failed: %d",
197 __FILE__, __LINE__, ret);
198 goto error;
199 }
200
201 return OPAL_SUCCESS;
202
203 error:
204 opal_output_verbose(1, opal_btl_base_framework.framework_output, "Error in btl_portals4_init_interface");
205
206 for (interface=0; interface<mca_btl_portals4_component.num_btls; interface++) {
207 portals4_btl = mca_btl_portals4_component.btls[interface];
208 if (NULL != portals4_btl) mca_btl_portals4_free_module(portals4_btl);
209 }
210 mca_btl_portals4_component.num_btls = 0;
211 if (NULL != mca_btl_portals4_component.btls) free(mca_btl_portals4_component.btls);
212 if (NULL != mca_btl_portals4_component.eqs_h) free(mca_btl_portals4_component.eqs_h);
213 mca_btl_portals4_component.btls = NULL;
214 mca_btl_portals4_component.eqs_h = NULL;
215
216 return OPAL_ERROR;
217 }
218
219 static int
220 create_endpoint(int interface,
221 opal_proc_t *proc,
222 mca_btl_base_endpoint_t **endpoint)
223 {
224 int ret;
225 size_t size;
226 ptl_process_t *id;
227
228 OPAL_MODEX_RECV(ret, &mca_btl_portals4_component.super.btl_version,
229 &proc->proc_name, (void**) &id, &size);
230
231 if (OPAL_ERR_NOT_FOUND == ret) {
232 OPAL_OUTPUT_VERBOSE((30, opal_btl_base_framework.framework_output,
233 "btl/portals4: Portals 4 BTL not available on peer: %s", opal_strerror(ret)));
234 return ret;
235 } else if (OPAL_SUCCESS != ret) {
236 opal_output_verbose(0, opal_btl_base_framework.framework_output,
237 "btl/portals4: opal_modex_recv failed: %s", opal_strerror(ret));
238 return ret;
239 }
240 if (size < sizeof(ptl_process_t)) {
241 return OPAL_ERROR;
242 }
243 if ((size % sizeof(ptl_process_t)) != 0) {
244 opal_output_verbose(0, opal_btl_base_framework.framework_output,
245 "btl/portals4: invalid format in modex");
246 return OPAL_ERROR;
247 }
248 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
249 "btl/portals4: %d NI(s) declared in the modex", (int) (size/sizeof(ptl_process_t))));
250
251 *endpoint = malloc(sizeof(mca_btl_base_endpoint_t));
252 if (NULL == *endpoint) {
253 return OPAL_ERR_OUT_OF_RESOURCE;
254 }
255
256 (*endpoint)->ptl_proc = id[interface];
257
258 return OPAL_SUCCESS;
259 }
260
261 static int
262 create_peer_and_endpoint(int interface,
263 opal_proc_t *proc,
264 ptl_process_t *phys_peer,
265 mca_btl_base_endpoint_t **endpoint)
266 {
267 int ret;
268 size_t size;
269 ptl_process_t *id;
270
271 OPAL_MODEX_RECV(ret, &mca_btl_portals4_component.super.btl_version,
272 &proc->proc_name, (void**) &id, &size);
273
274 if (OPAL_ERR_NOT_FOUND == ret) {
275 OPAL_OUTPUT_VERBOSE((30, opal_btl_base_framework.framework_output,
276 "btl/portals4: Portals 4 BTL not available on peer: %s", opal_strerror(ret)));
277 return ret;
278 } else if (OPAL_SUCCESS != ret) {
279 opal_output_verbose(0, opal_btl_base_framework.framework_output,
280 "btl/portals4: opal_modex_recv failed: %s", opal_strerror(ret));
281 return ret;
282 }
283 if (size < sizeof(ptl_process_t)) {
284 return OPAL_ERROR;
285 }
286 if ((size % sizeof(ptl_process_t)) != 0) {
287 opal_output_verbose(0, opal_btl_base_framework.framework_output,
288 "btl/portals4: invalid format in modex");
289 return OPAL_ERROR;
290 }
291 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
292 "btl/portals4: %d NI(s) declared in the modex", (int) (size/sizeof(ptl_process_t))));
293
294
295
296
297
298 if (NULL == *endpoint) {
299 *endpoint = malloc(sizeof(mca_btl_base_endpoint_t));
300 if (NULL == *endpoint) {
301 return OPAL_ERR_OUT_OF_RESOURCE;
302 }
303 }
304
305
306
307
308 (*endpoint)->ptl_proc.rank = proc->proc_name.vpid;
309
310 phys_peer->phys.pid = id[interface].phys.pid;
311 phys_peer->phys.nid = id[interface].phys.nid;
312 opal_output_verbose(50, opal_btl_base_framework.framework_output,
313 "logical: global rank=%d pid=%d nid=%d\n",
314 proc->proc_name.vpid, phys_peer->phys.pid, phys_peer->phys.nid);
315
316 return OPAL_SUCCESS;
317 }
318
319 static int
320 create_maptable(struct mca_btl_portals4_module_t *portals4_btl,
321 size_t nprocs,
322 opal_proc_t **procs,
323 mca_btl_base_endpoint_t **endpoint)
324 {
325 int ret;
326 ptl_process_t *maptable;
327
328 maptable = malloc(sizeof(ptl_process_t) * nprocs);
329 if (NULL == maptable) {
330 opal_output_verbose(1, opal_btl_base_framework.framework_output,
331 "%s:%d: malloc failed\n",
332 __FILE__, __LINE__);
333 return OPAL_ERR_OUT_OF_RESOURCE;
334 }
335
336 for (uint32_t i = 0 ; i < nprocs ; i++) {
337 struct opal_proc_t *curr_proc;
338
339 curr_proc = procs[i];
340
341
342 if (opal_proc_local_get()->proc_arch != curr_proc->proc_arch) {
343 opal_output_verbose(1, opal_btl_base_framework.framework_output,
344 "Portals 4 BTL does not support heterogeneous operations.");
345 opal_output_verbose(1, opal_btl_base_framework.framework_output,
346 "Proc %s architecture %x, mine %x.",
347 OPAL_NAME_PRINT(curr_proc->proc_name),
348 curr_proc->proc_arch, opal_proc_local_get()->proc_arch);
349 return OPAL_ERR_NOT_SUPPORTED;
350 }
351
352 ret = create_peer_and_endpoint(portals4_btl->interface_num,
353 curr_proc,
354 &maptable[i],
355 &endpoint[i]);
356 if (OPAL_SUCCESS != ret) {
357 opal_output_verbose(1, opal_btl_base_framework.framework_output,
358 "%s:%d: create_maptable::create_peer_and_endpoint failed: %d\n",
359 __FILE__, __LINE__, ret);
360 return ret;
361 }
362 }
363
364 ret = PtlSetMap(portals4_btl->portals_ni_h,
365 nprocs,
366 maptable);
367 if (OPAL_SUCCESS != ret) {
368 opal_output_verbose(1, opal_btl_base_framework.framework_output,
369 "%s:%d: logical mapping failed: %d\n",
370 __FILE__, __LINE__, ret);
371 return ret;
372 }
373 opal_output_verbose(90, opal_btl_base_framework.framework_output,
374 "logical mapping OK\n");
375 free(maptable);
376
377 return OPAL_SUCCESS;
378 }
379
380 #define NEED_ALL_PROCS (mca_btl_portals4_component.use_logical)
381
382 int
383 mca_btl_portals4_add_procs(struct mca_btl_base_module_t* btl_base,
384 size_t nprocs,
385 struct opal_proc_t **procs,
386 struct mca_btl_base_endpoint_t** btl_peer_data,
387 opal_bitmap_t* reachable)
388 {
389 struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
390 int ret;
391 size_t i;
392
393 opal_output_verbose(50, opal_btl_base_framework.framework_output,
394 "mca_btl_portals4_add_procs: Adding %d procs (%d) for NI %d",
395 (int) nprocs,
396 (int) portals4_btl->portals_num_procs,
397 portals4_btl->interface_num);
398
399
400
401
402
403 for (i = 0 ; i < nprocs ; ++i) {
404 struct opal_proc_t *curr_proc = procs[i];
405
406
407 if (opal_proc_local_get()->proc_arch != curr_proc->proc_arch) {
408 opal_output_verbose(1, opal_btl_base_framework.framework_output,
409 "Portals 4 BTL does not support heterogeneous operations.");
410 opal_output_verbose(1, opal_btl_base_framework.framework_output,
411 "Proc %s architecture %x, mine %x.",
412 OPAL_NAME_PRINT(curr_proc->proc_name),
413 curr_proc->proc_arch, opal_proc_local_get()->proc_arch);
414 return OPAL_ERR_NOT_SUPPORTED;
415 }
416
417 ret = create_endpoint(portals4_btl->interface_num,
418 curr_proc,
419 &btl_peer_data[i]);
420
421 OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_num_procs, 1);
422
423 opal_bitmap_set_bit(reachable, i);
424
425 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
426 "add_procs: rank=%lx nid=%x pid=%x for NI %d",
427 i,
428 btl_peer_data[i]->ptl_proc.phys.nid,
429 btl_peer_data[i]->ptl_proc.phys.pid,
430 portals4_btl->interface_num));
431 }
432
433 if (mca_btl_portals4_component.need_init && portals4_btl->portals_num_procs > 0) {
434 if (mca_btl_portals4_component.use_logical) {
435 ret = create_maptable(portals4_btl, nprocs, procs, btl_peer_data);
436 if (OPAL_SUCCESS != ret) {
437 opal_output_verbose(1, opal_btl_base_framework.framework_output,
438 "%s:%d: mca_btl_portals4_add_procs::create_maptable() failed: %d\n",
439 __FILE__, __LINE__, ret);
440 return ret;
441 }
442 }
443
444 ret = btl_portals4_init_interface();
445 if (OPAL_SUCCESS != ret) {
446 opal_output_verbose(1, opal_btl_base_framework.framework_output,
447 "%s:%d: portals4 interface initialization failed: %d",
448 __FILE__, __LINE__, ret);
449 return ret;
450 }
451 mca_btl_portals4_component.need_init = 0;
452 }
453
454 return OPAL_SUCCESS;
455 }
456
457
458 int
459 mca_btl_portals4_del_procs(struct mca_btl_base_module_t *btl,
460 size_t nprocs,
461 struct opal_proc_t **procs,
462 struct mca_btl_base_endpoint_t **btl_peer_data)
463 {
464 struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl;
465 size_t i;
466
467 opal_output_verbose(50, opal_btl_base_framework.framework_output,
468 "mca_btl_portals4_del_procs: Removing %d procs (%d)", (int) nprocs,
469 (int) portals4_btl->portals_num_procs);
470
471
472
473 for (i = 0 ; i < nprocs ; ++i) {
474 free(btl_peer_data[i]);
475 OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_num_procs, -1);
476 }
477
478 return OPAL_SUCCESS;
479 }
480
481 mca_btl_base_descriptor_t*
482 mca_btl_portals4_alloc(struct mca_btl_base_module_t* btl_base,
483 struct mca_btl_base_endpoint_t* endpoint,
484 uint8_t order,
485 size_t size,
486 uint32_t flags)
487 {
488 struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
489 mca_btl_portals4_frag_t* frag;
490
491 if (size <= portals4_btl->super.btl_eager_limit) {
492 OPAL_BTL_PORTALS4_FRAG_ALLOC_EAGER(portals4_btl, frag);
493 if (NULL == frag) return NULL;
494 frag->segments[0].base.seg_len = size;
495 } else {
496 OPAL_BTL_PORTALS4_FRAG_ALLOC_MAX(portals4_btl, frag);
497 if (NULL == frag) return NULL;
498 frag->segments[0].base.seg_len =
499 size <= portals4_btl->super.btl_max_send_size ?
500 size : portals4_btl->super.btl_max_send_size ;
501 }
502
503 frag->base.des_segment_count = 1;
504 frag->base.des_flags = flags | MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
505 frag->base.order = MCA_BTL_NO_ORDER;
506
507 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
508 "mca_btl_portals4_alloc: %p\n", (void *) &frag->base));
509 return &frag->base;
510 }
511
512 int
513 mca_btl_portals4_free(struct mca_btl_base_module_t* btl_base,
514 mca_btl_base_descriptor_t* des)
515 {
516 struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
517 mca_btl_portals4_frag_t* frag = (mca_btl_portals4_frag_t*) des;
518
519 if (BTL_PORTALS4_FRAG_TYPE_EAGER == frag->type) {
520
521 OPAL_BTL_PORTALS4_FRAG_RETURN_EAGER(portals4_btl, frag);
522
523 } else if (BTL_PORTALS4_FRAG_TYPE_MAX == frag->type) {
524 if (frag->me_h != PTL_INVALID_HANDLE) {
525 frag->me_h = PTL_INVALID_HANDLE;
526 }
527 OPAL_BTL_PORTALS4_FRAG_RETURN_MAX(portals4_btl, frag);
528
529 } else if (BTL_PORTALS4_FRAG_TYPE_USER == frag->type) {
530 if (frag->me_h != PTL_INVALID_HANDLE) {
531 frag->me_h = PTL_INVALID_HANDLE;
532 }
533 OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_outstanding_ops, -1);
534 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
535 "mca_btl_portals4_free: Decrementing portals_outstanding_ops=%d\n", portals4_btl->portals_outstanding_ops));
536 OPAL_BTL_PORTALS4_FRAG_RETURN_USER(portals4_btl, frag);
537 } else {
538 return OPAL_ERR_BAD_PARAM;
539 }
540
541 return OPAL_SUCCESS;
542 }
543
544
545
546
547
548
549
550
551
552 mca_btl_base_descriptor_t*
553 mca_btl_portals4_prepare_src(struct mca_btl_base_module_t* btl_base,
554 struct mca_btl_base_endpoint_t* peer,
555 struct opal_convertor_t* convertor,
556 uint8_t order,
557 size_t reserve,
558 size_t* size,
559 uint32_t flags)
560 {
561 struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
562 mca_btl_portals4_frag_t* frag;
563 size_t max_data = *size;
564 struct iovec iov;
565 uint32_t iov_count = 1;
566 int ret;
567
568 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
569 "mca_btl_portals4_prepare_src NI=%d reserve=%ld size=%ld max_data=%ld\n", portals4_btl->interface_num, reserve, *size, max_data));
570
571 if (0 != reserve || 0 != opal_convertor_need_buffers(convertor)) {
572 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "mca_btl_portals4_prepare_src NEED BUFFERS or RESERVE\n"));
573 frag = (mca_btl_portals4_frag_t*) mca_btl_portals4_alloc(btl_base, peer, MCA_BTL_NO_ORDER, max_data + reserve, flags);
574 if (NULL == frag) {
575 return NULL;
576 }
577
578 if (max_data + reserve > frag->size) {
579 max_data = frag->size - reserve;
580 }
581 iov.iov_len = max_data;
582 iov.iov_base = (unsigned char*) frag->segments[0].base.seg_addr.pval + reserve;
583 ret = opal_convertor_pack(convertor, &iov, &iov_count, &max_data );
584
585 *size = max_data;
586 if (ret < 0) {
587 mca_btl_portals4_free(btl_base, (mca_btl_base_descriptor_t *) frag);
588 return NULL;
589 }
590
591 frag->segments[0].base.seg_len = max_data + reserve;
592 frag->base.des_segment_count = 1;
593 }
594
595 frag->base.des_segments = &frag->segments[0].base;
596 frag->base.des_flags = flags | MCA_BTL_DES_SEND_ALWAYS_CALLBACK;
597 frag->base.order = MCA_BTL_NO_ORDER;
598 return &frag->base;
599 }
600
601 mca_btl_base_registration_handle_t *
602 mca_btl_portals4_register_mem(mca_btl_base_module_t *btl_base,
603 mca_btl_base_endpoint_t *endpoint,
604 void *base,
605 size_t size,
606 uint32_t flags)
607 {
608 struct mca_btl_portals4_module_t *portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
609 mca_btl_base_registration_handle_t *handle = NULL;
610 ptl_me_t me;
611 int ret;
612
613 handle = (mca_btl_base_registration_handle_t *)malloc(sizeof(mca_btl_base_registration_handle_t));
614 if (!handle) {
615 return NULL;
616 }
617
618 handle->key = OPAL_THREAD_ADD_FETCH64(&(portals4_btl->portals_rdma_key), 1);
619 handle->remote_offset = 0;
620
621 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
622 "mca_btl_portals4_register_mem NI=%d base=%p size=%ld handle=%p key=%ld flags=%d",
623 portals4_btl->interface_num, base, size, (void *)handle, handle->key, flags));
624
625
626 me.start = base;
627 me.length = size;
628 me.ct_handle = PTL_CT_NONE;
629 me.min_free = 0;
630 me.uid = PTL_UID_ANY;
631 me.options = PTL_ME_OP_GET |
632 PTL_ME_EVENT_LINK_DISABLE |
633 PTL_ME_EVENT_COMM_DISABLE |
634 PTL_ME_EVENT_UNLINK_DISABLE;
635
636 if (mca_btl_portals4_component.use_logical) {
637 me.match_id.rank = endpoint->ptl_proc.rank;
638 } else {
639 me.match_id.phys.nid = endpoint->ptl_proc.phys.nid;
640 me.match_id.phys.pid = endpoint->ptl_proc.phys.pid;
641 }
642 me.match_bits = handle->key;
643 me.ignore_bits = BTL_PORTALS4_PROTOCOL_MASK |
644 BTL_PORTALS4_CONTEXT_MASK |
645 BTL_PORTALS4_SOURCE_MASK;
646 me.ignore_bits = 0;
647
648 ret = PtlMEAppend(portals4_btl->portals_ni_h,
649 portals4_btl->recv_idx,
650 &me,
651 PTL_PRIORITY_LIST,
652 handle,
653 &(handle->me_h));
654 if (PTL_OK != ret) {
655 opal_output_verbose(1, opal_btl_base_framework.framework_output,
656 "%s:%d: PtlMEAppend failed: %d\n",
657 __FILE__, __LINE__, ret);
658 OPAL_THREAD_ADD_FETCH32(&portals4_btl->portals_outstanding_ops, -1);
659 return NULL;
660 }
661 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
662 "PtlMEAppend (mca_btl_portals4_register_mem) handle=%p, me_h=%d start=%p length=%ld rank=%x nid=%x pid=%x match_bits=%lx\n",
663 (void *)handle, handle->me_h, me.start, me.length,
664 me.match_id.rank, me.match_id.phys.nid, me.match_id.phys.pid, me.match_bits));
665 return handle;
666 }
667
668 int
669 mca_btl_portals4_deregister_mem(mca_btl_base_module_t *btl_base,
670 mca_btl_base_registration_handle_t *handle)
671 {
672 int ret;
673 struct mca_btl_portals4_module_t *portals4_btl = (struct mca_btl_portals4_module_t*) btl_base;
674
675 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
676 "mca_btl_portals4_deregister_mem NI=%d handle=%p key=%ld me_h=%d\n",
677 portals4_btl->interface_num, (void *)handle, handle->key, handle->me_h));
678
679 if (!PtlHandleIsEqual(handle->me_h, PTL_INVALID_HANDLE)) {
680 ret = PtlMEUnlink(handle->me_h);
681 if (PTL_OK != ret) {
682 opal_output_verbose(1, opal_btl_base_framework.framework_output,
683 "%s:%d: PtlMEUnlink failed: %d\n",__FILE__, __LINE__, ret);
684 return OPAL_ERROR;
685 }
686 handle->me_h = PTL_INVALID_HANDLE;
687 }
688
689 free(handle);
690
691 return OPAL_SUCCESS;
692 }
693
694 int
695 mca_btl_portals4_finalize(struct mca_btl_base_module_t *btl)
696 {
697 struct mca_btl_portals4_module_t* portals4_btl = (struct mca_btl_portals4_module_t*) btl;
698
699 mca_btl_portals4_free_module(portals4_btl);
700
701 OBJ_DESTRUCT(&portals4_btl->portals_frag_eager);
702 OBJ_DESTRUCT(&portals4_btl->portals_frag_max);
703 OBJ_DESTRUCT(&portals4_btl->portals_frag_user);
704 OBJ_DESTRUCT(&portals4_btl->portals_recv_blocks);
705
706 free(portals4_btl);
707
708 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
709 "mca_btl_portals4_finalize NI %d: OK\n", portals4_btl->interface_num));
710
711 return OPAL_SUCCESS;
712 }
713
714 void mca_btl_portals4_free_module(mca_btl_portals4_module_t *portals4_btl)
715 {
716 int ret;
717
718 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
719 "mca_btl_portals4_free_module portals_outstanding_ops=%d\n", portals4_btl->portals_outstanding_ops));
720
721
722 assert(portals4_btl->portals_outstanding_ops >= 0);
723
724
725 while (portals4_btl->portals_outstanding_ops > 0) {
726 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output,
727 "mca_btl_portals4_free_module portals_outstanding_ops: %d",
728 portals4_btl->portals_outstanding_ops));
729
730 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Call to mca_btl_portals4_component_progress (3)\n"));
731 mca_btl_portals4_component_progress();
732 }
733
734 if (!PtlHandleIsEqual(portals4_btl->send_md_h, PTL_INVALID_HANDLE)) {
735 PtlMDRelease(portals4_btl->send_md_h);
736 portals4_btl->send_md_h = PTL_INVALID_HANDLE;
737 }
738 if (!PtlHandleIsEqual(portals4_btl->zero_md_h, PTL_INVALID_HANDLE)) {
739 PtlMDRelease(portals4_btl->zero_md_h);
740 portals4_btl->zero_md_h = PTL_INVALID_HANDLE;
741 }
742
743 if (!PtlHandleIsEqual(portals4_btl->long_overflow_me_h, PTL_INVALID_HANDLE)) {
744 PtlMEUnlink(portals4_btl->long_overflow_me_h);
745 portals4_btl->long_overflow_me_h = PTL_INVALID_HANDLE;
746 }
747
748 if ((ptl_pt_index_t) ~0UL != mca_btl_portals4_module.recv_idx) {
749 PtlPTFree(portals4_btl->portals_ni_h, portals4_btl->recv_idx);
750 portals4_btl->recv_idx= (ptl_pt_index_t) ~0UL;
751 }
752
753 if (PTL_EQ_NONE != portals4_btl->recv_eq_h) {
754 ret = PtlEQFree(portals4_btl->recv_eq_h);
755 if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error freeing EQ recv: %d", ret));
756 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlEQFree: recv_eq_h=%d portals4_btl=%p",
757 portals4_btl->recv_eq_h, (void*)portals4_btl));
758
759 portals4_btl->recv_eq_h = PTL_EQ_NONE;
760 }
761 if (!PtlHandleIsEqual(portals4_btl->portals_ni_h, PTL_INVALID_HANDLE)) {
762 ret = PtlNIFini(portals4_btl->portals_ni_h);
763 if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error returned by PtlNIFini: %d\n", ret));
764 OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "PtlNIFini: portals_ni_h=%d portals4_btl=%p",
765 portals4_btl->portals_ni_h, (void*)portals4_btl));
766
767 portals4_btl->portals_ni_h = PTL_INVALID_HANDLE;
768 }
769 ret = mca_btl_portals4_recv_disable(portals4_btl);
770 if (PTL_OK != ret) OPAL_OUTPUT_VERBOSE((90, opal_btl_base_framework.framework_output, "Error freeing recv list: %d", ret));
771 }