This source file includes following definitions.
- mca_rcache_rgpusm_deregister_lru
- mca_rcache_rgpusm_module_init
- mca_rcache_rgpusm_register
- mca_rcache_rgpusm_find
- registration_is_cachebale
- mca_rcache_rgpusm_deregister
- mca_rcache_rgpusm_deregister_no_lock
- mca_rcache_rgpusm_finalize
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 #define OPAL_DISABLE_ENABLE_MEM_DEBUG 1
81 #include "opal_config.h"
82 #include "opal/align.h"
83 #include "opal/mca/rcache/rgpusm/rcache_rgpusm.h"
84 #include <errno.h>
85 #include <string.h>
86 #ifdef HAVE_MALLOC_H
87 #include <malloc.h>
88 #endif
89 #include "opal/util/proc.h"
90 #include "opal/mca/rcache/rcache.h"
91 #include "opal/mca/rcache/base/base.h"
92 #include "opal/mca/rcache/base/base.h"
93 #include "opal/mca/common/cuda/common_cuda.h"
94
95
96 static int mca_rcache_rgpusm_deregister_no_lock(struct mca_rcache_base_module_t *,
97 mca_rcache_base_registration_t *);
98 static inline bool mca_rcache_rgpusm_deregister_lru (mca_rcache_base_module_t *rcache) {
99 mca_rcache_rgpusm_module_t *rcache_rgpusm = (mca_rcache_rgpusm_module_t *) rcache;
100 mca_rcache_base_registration_t *old_reg;
101 int rc;
102
103
104
105 old_reg = (mca_rcache_base_registration_t*)
106 opal_list_remove_first (&rcache_rgpusm->lru_list);
107 if (NULL == old_reg) {
108 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
109 "RGPUSM: The LRU list is empty. There is nothing to deregister");
110 return false;
111 }
112
113 mca_rcache_base_vma_delete (rcache_rgpusm->vma_module, old_reg);
114
115
116 OPAL_THREAD_UNLOCK(&rcache->lock);
117 assert(old_reg->ref_count == 0);
118 rc = cuda_closememhandle (NULL, old_reg);
119 OPAL_THREAD_LOCK(&rcache->lock);
120
121
122
123
124 if (OPAL_SUCCESS != rc) {
125 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
126 "RGPUSM: Failed to deregister the memory addr=%p, size=%d",
127 old_reg->base, (int)(old_reg->bound - old_reg->base + 1));
128 return false;
129 }
130
131 opal_free_list_return (&rcache_rgpusm->reg_list,
132 (opal_free_list_item_t*)old_reg);
133 rcache_rgpusm->stat_evicted++;
134
135 return true;
136 }
137
138
139
140
141
142 void mca_rcache_rgpusm_module_init(mca_rcache_rgpusm_module_t* rcache)
143 {
144 rcache->super.rcache_component = &mca_rcache_rgpusm_component.super;
145 rcache->super.rcache_register = mca_rcache_rgpusm_register;
146 rcache->super.rcache_find = mca_rcache_rgpusm_find;
147 rcache->super.rcache_deregister = mca_rcache_rgpusm_deregister;
148 rcache->super.rcache_finalize = mca_rcache_rgpusm_finalize;
149 rcache->vma_module = mca_rcache_base_vma_module_alloc ();
150
151 OBJ_CONSTRUCT(&rcache->reg_list, opal_free_list_t);
152 opal_free_list_init (&rcache->reg_list, sizeof(struct mca_rcache_common_cuda_reg_t),
153 opal_cache_line_size,
154 OBJ_CLASS(mca_rcache_base_registration_t),
155 0,opal_cache_line_size,
156 0, -1, 32, NULL, 0, NULL, NULL, NULL);
157 OBJ_CONSTRUCT(&rcache->lru_list, opal_list_t);
158 rcache->stat_cache_hit = rcache->stat_cache_miss = rcache->stat_evicted = 0;
159 rcache->stat_cache_found = rcache->stat_cache_notfound = 0;
160 rcache->stat_cache_valid = rcache->stat_cache_invalid = 0;
161
162 }
163
164
165
166
167
168
169 int mca_rcache_rgpusm_register (mca_rcache_base_module_t *rcache, void *addr,
170 size_t size, uint32_t flags, int32_t access_flags,
171 mca_rcache_base_registration_t **reg)
172 {
173 mca_rcache_rgpusm_module_t *rcache_rgpusm = (mca_rcache_rgpusm_module_t*)rcache;
174 mca_rcache_common_cuda_reg_t *rgpusm_reg;
175 mca_rcache_common_cuda_reg_t *rget_reg;
176 opal_free_list_item_t *item;
177 int rc;
178 int mypeer;
179
180
181
182
183
184 rget_reg = (mca_rcache_common_cuda_reg_t *)*reg;
185
186 mypeer = flags;
187 flags = 0;
188
189 assert(0 == (flags & MCA_RCACHE_FLAGS_CACHE_BYPASS));
190
191
192
193
194
195
196
197 if(!mca_rcache_rgpusm_component.leave_pinned && 0 == mca_rcache_rgpusm_component.rcache_size_limit) {
198 item = opal_free_list_get (&rcache_rgpusm->reg_list);
199 if(NULL == item) {
200 return OPAL_ERR_OUT_OF_RESOURCE;
201 }
202 rgpusm_reg = (mca_rcache_common_cuda_reg_t*)item;
203 rgpusm_reg->base.rcache = rcache;
204 rgpusm_reg->base.base = addr;
205 rgpusm_reg->base.bound = (unsigned char *)addr + size - 1;;
206 rgpusm_reg->base.flags = flags;
207
208
209 memcpy(rgpusm_reg->data.memHandle, rget_reg->data.memHandle, sizeof(rget_reg->data.memHandle));
210
211
212
213
214 rc = cuda_openmemhandle (addr, size, (mca_rcache_base_registration_t *)rgpusm_reg,
215 (mca_rcache_base_registration_t *)rget_reg);
216
217
218 assert(OPAL_ERR_WOULD_BLOCK != rc);
219
220 if(rc != OPAL_SUCCESS) {
221 opal_free_list_return (&rcache_rgpusm->reg_list, item);
222 return rc;
223 }
224 rgpusm_reg->base.ref_count++;
225 *reg = (mca_rcache_base_registration_t *)rgpusm_reg;
226 return OPAL_SUCCESS;
227 }
228
229
230 OPAL_THREAD_LOCK(&rcache->lock);
231 mca_rcache_base_vma_find (rcache_rgpusm->vma_module, addr, size, reg);
232
233
234
235
236
237
238
239
240 if (*reg != NULL) {
241 rcache_rgpusm->stat_cache_hit++;
242 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
243 "RGPUSM: Found addr=%p,size=%d (base=%p,size=%d) in cache",
244 addr, (int)size, (*reg)->base,
245 (int)((*reg)->bound - (*reg)->base));
246
247 if (mca_common_cuda_memhandle_matches((mca_rcache_common_cuda_reg_t *)*reg, rget_reg)) {
248
249 rcache_rgpusm->stat_cache_valid++;
250 } else {
251
252 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
253 "RGPUSM: Mismatched Handle: Evicting/unregistering "
254 "addr=%p,size=%d (base=%p,size=%d) from cache",
255 addr, (int)size, (*reg)->base,
256 (int)((*reg)->bound - (*reg)->base));
257
258
259
260 assert(0 == (*reg)->ref_count);
261 if (mca_rcache_rgpusm_component.leave_pinned) {
262 opal_list_remove_item(&rcache_rgpusm->lru_list,
263 (opal_list_item_t*)(*reg));
264 }
265
266
267 (*reg)->ref_count++;
268
269 (*reg)->flags |= MCA_RCACHE_FLAGS_INVALID;
270 mca_rcache_rgpusm_deregister_no_lock(rcache, *reg);
271 *reg = NULL;
272 rcache_rgpusm->stat_cache_invalid++;
273 }
274 } else {
275
276 rcache_rgpusm->stat_cache_miss++;
277 }
278
279
280 if (*reg != NULL) {
281 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
282 "RGPUSM: CACHE HIT is good: ep=%d, addr=%p, size=%d in cache",
283 mypeer, addr, (int)size);
284
285
286 if ((0 == (*reg)->ref_count) && mca_rcache_rgpusm_component.leave_pinned) {
287 opal_output_verbose(20, mca_rcache_rgpusm_component.output,
288 "RGPUSM: POP OFF LRU: ep=%d, addr=%p, size=%d in cache",
289 mypeer, addr, (int)size);
290 opal_list_remove_item(&rcache_rgpusm->lru_list,
291 (opal_list_item_t*)(*reg));
292 }
293 (*reg)->ref_count++;
294 OPAL_THREAD_UNLOCK(&rcache->lock);
295 opal_output(-1, "reg->ref_count=%d", (int)(*reg)->ref_count);
296 opal_output_verbose(80, mca_rcache_rgpusm_component.output,
297 "RGPUSM: Found entry in cache addr=%p, size=%d", addr, (int)size);
298 return OPAL_SUCCESS;
299 }
300
301
302
303 assert(NULL == *reg);
304 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
305 "RGPUSM: New registration ep=%d, addr=%p, size=%d. Need to register and insert in cache",
306 mypeer, addr, (int)size);
307
308 item = opal_free_list_get (&rcache_rgpusm->reg_list);
309 if(NULL == item) {
310 OPAL_THREAD_UNLOCK(&rcache->lock);
311 return OPAL_ERR_OUT_OF_RESOURCE;
312 }
313 rgpusm_reg = (mca_rcache_common_cuda_reg_t*)item;
314
315 rgpusm_reg->base.rcache = rcache;
316 rgpusm_reg->base.base = addr;
317 rgpusm_reg->base.bound = (unsigned char *)addr + size - 1;
318 rgpusm_reg->base.flags = flags;
319
320
321 memcpy(rgpusm_reg->data.memHandle, rget_reg->data.memHandle, sizeof(rget_reg->data.memHandle));
322
323
324
325
326
327
328 rc = cuda_openmemhandle (addr, size, (mca_rcache_base_registration_t *)rgpusm_reg,
329 (mca_rcache_base_registration_t *)rget_reg);
330
331
332
333
334
335
336
337
338
339
340
341 if (OPAL_ERR_WOULD_BLOCK == rc) {
342 mca_rcache_base_registration_t *oldreg;
343
344
345
346 mca_rcache_base_vma_find (rcache_rgpusm->vma_module, addr, 4, &oldreg);
347
348
349
350
351 if (NULL != oldreg) {
352
353
354 assert(0 == oldreg->ref_count);
355 if (mca_rcache_rgpusm_component.leave_pinned) {
356 opal_list_remove_item(&rcache_rgpusm->lru_list,
357 (opal_list_item_t*)oldreg);
358 }
359
360
361 oldreg->ref_count++;
362
363 oldreg->flags |= MCA_RCACHE_FLAGS_INVALID;
364 mca_rcache_rgpusm_deregister_no_lock(rcache, oldreg);
365 rcache_rgpusm->stat_evicted++;
366
367
368 rc = cuda_openmemhandle (addr, size, (mca_rcache_base_registration_t *)rgpusm_reg,
369 (mca_rcache_base_registration_t *)rget_reg);
370 }
371
372
373
374
375 while (OPAL_SUCCESS != rc) {
376 if (true != mca_rcache_rgpusm_deregister_lru(rcache)) {
377 rc = OPAL_ERROR;
378 break;
379 }
380
381 rc = cuda_openmemhandle (addr, size, (mca_rcache_base_registration_t *)rgpusm_reg,
382 (mca_rcache_base_registration_t *)rget_reg);
383 }
384 }
385
386 if(rc != OPAL_SUCCESS) {
387 OPAL_THREAD_UNLOCK(&rcache->lock);
388 opal_free_list_return (&rcache_rgpusm->reg_list, item);
389 return rc;
390 }
391
392 opal_output_verbose(80, mca_rcache_rgpusm_component.output,
393 "RGPUSM: About to insert in rgpusm cache addr=%p, size=%d", addr, (int)size);
394 rc = mca_rcache_base_vma_insert (rcache_rgpusm->vma_module, (mca_rcache_base_registration_t *)rgpusm_reg,
395 mca_rcache_rgpusm_component.rcache_size_limit);
396 if (OPAL_ERR_TEMP_OUT_OF_RESOURCE == rc) {
397 opal_output_verbose(40, mca_rcache_rgpusm_component.output,
398 "RGPUSM: No room in the cache - boot the first one out");
399 (void)mca_rcache_rgpusm_deregister_lru(rcache);
400 if (mca_rcache_rgpusm_component.empty_cache) {
401 int remNum = 1;
402
403 opal_output_verbose(40, mca_rcache_rgpusm_component.output,
404 "RGPUSM: About to delete all the unused entries in the cache");
405 while (mca_rcache_rgpusm_deregister_lru(rcache)) {
406 remNum++;
407 }
408 opal_output_verbose(40, mca_rcache_rgpusm_component.output,
409 "RGPUSM: Deleted and deregistered %d entries", remNum);
410 rc = mca_rcache_base_vma_insert (rcache_rgpusm->vma_module, (mca_rcache_base_registration_t *)rgpusm_reg,
411 mca_rcache_rgpusm_component.rcache_size_limit);
412 } else {
413
414 while((rc = mca_rcache_base_vma_insert (rcache_rgpusm->vma_module, (mca_rcache_base_registration_t *)rgpusm_reg,
415 mca_rcache_rgpusm_component.rcache_size_limit)) ==
416 OPAL_ERR_TEMP_OUT_OF_RESOURCE) {
417 opal_output_verbose(40, mca_rcache_rgpusm_component.output,
418 "RGPUSM: No room in the cache - boot one out");
419 if (!mca_rcache_rgpusm_deregister_lru(rcache)) {
420 break;
421 }
422 }
423 }
424 }
425
426 if(rc != OPAL_SUCCESS) {
427 OPAL_THREAD_UNLOCK(&rcache->lock);
428 opal_free_list_return (&rcache_rgpusm->reg_list, item);
429
430
431
432
433
434
435 opal_output_verbose(10, mca_rcache_rgpusm_component.output,
436 "RGPUSM: Failed to register addr=%p, size=%d", addr, (int)size);
437 return OPAL_ERROR;
438 }
439
440 rgpusm_reg->base.ref_count++;
441 *reg = (mca_rcache_base_registration_t *)rgpusm_reg;
442 OPAL_THREAD_UNLOCK(&rcache->lock);
443
444 return OPAL_SUCCESS;
445 }
446
447 int mca_rcache_rgpusm_find(struct mca_rcache_base_module_t *rcache, void *addr,
448 size_t size, mca_rcache_base_registration_t **reg)
449 {
450 mca_rcache_rgpusm_module_t *rcache_rgpusm = (mca_rcache_rgpusm_module_t*)rcache;
451 int rc;
452 unsigned char *base, *bound;
453
454 base = addr;
455 bound = base + size - 1;
456
457 OPAL_THREAD_LOCK(&rcache->lock);
458 opal_output(-1, "Looking for addr=%p, size=%d", addr, (int)size);
459 rc = mca_rcache_base_vma_find (rcache_rgpusm->vma_module, addr, size, reg);
460 if(*reg != NULL && mca_rcache_rgpusm_component.leave_pinned) {
461 if(0 == (*reg)->ref_count && mca_rcache_rgpusm_component.leave_pinned) {
462 opal_list_remove_item(&rcache_rgpusm->lru_list, (opal_list_item_t*)(*reg));
463 }
464 rcache_rgpusm->stat_cache_found++;
465 (*reg)->ref_count++;
466 } else {
467 rcache_rgpusm->stat_cache_notfound++;
468 }
469 OPAL_THREAD_UNLOCK(&rcache->lock);
470
471 return rc;
472 }
473
474 static inline bool registration_is_cachebale(mca_rcache_base_registration_t *reg)
475 {
476 return !(reg->flags &
477 (MCA_RCACHE_FLAGS_CACHE_BYPASS |
478 MCA_RCACHE_FLAGS_INVALID));
479 }
480
481 int mca_rcache_rgpusm_deregister(struct mca_rcache_base_module_t *rcache,
482 mca_rcache_base_registration_t *reg)
483 {
484 mca_rcache_rgpusm_module_t *rcache_rgpusm = (mca_rcache_rgpusm_module_t*)rcache;
485 int rc = OPAL_SUCCESS;
486 assert(reg->ref_count > 0);
487
488 OPAL_THREAD_LOCK(&rcache->lock);
489 reg->ref_count--;
490 opal_output(-1, "Deregister: reg->ref_count=%d", (int)reg->ref_count);
491 if(reg->ref_count > 0) {
492 OPAL_THREAD_UNLOCK(&rcache->lock);
493 return OPAL_SUCCESS;
494 }
495 if(mca_rcache_rgpusm_component.leave_pinned && registration_is_cachebale(reg))
496 {
497
498
499 opal_output_verbose(20, mca_rcache_rgpusm_component.output,
500 "RGPUSM: Deregister: addr=%p, size=%d: cacheable and pinned, leave in cache, PUSH IN LRU",
501 reg->base, (int)(reg->bound - reg->base + 1));
502 opal_list_prepend(&rcache_rgpusm->lru_list, (opal_list_item_t*)reg);
503 } else {
504
505 if(!(reg->flags & MCA_RCACHE_FLAGS_CACHE_BYPASS))
506 mca_rcache_base_vma_delete (rcache_rgpusm->vma_module, reg);
507
508
509 OPAL_THREAD_UNLOCK(&rcache->lock);
510
511 {
512 assert(reg->ref_count == 0);
513 rc = cuda_closememhandle (NULL, reg);
514 }
515
516 OPAL_THREAD_LOCK(&rcache->lock);
517
518 if(OPAL_SUCCESS == rc) {
519 opal_free_list_return (&rcache_rgpusm->reg_list,
520 (opal_free_list_item_t*)reg);
521 }
522 }
523 OPAL_THREAD_UNLOCK(&rcache->lock);
524
525 return rc;
526 }
527
528 int mca_rcache_rgpusm_deregister_no_lock(struct mca_rcache_base_module_t *rcache,
529 mca_rcache_base_registration_t *reg)
530 {
531 mca_rcache_rgpusm_module_t *rcache_rgpusm = (mca_rcache_rgpusm_module_t*)rcache;
532 int rc = OPAL_SUCCESS;
533 assert(reg->ref_count > 0);
534
535 reg->ref_count--;
536 opal_output(-1, "Deregister: reg->ref_count=%d", (int)reg->ref_count);
537 if(reg->ref_count > 0) {
538 return OPAL_SUCCESS;
539 }
540 if(mca_rcache_rgpusm_component.leave_pinned && registration_is_cachebale(reg))
541 {
542
543
544 opal_list_prepend(&rcache_rgpusm->lru_list, (opal_list_item_t*)reg);
545 } else {
546
547 if(!(reg->flags & MCA_RCACHE_FLAGS_CACHE_BYPASS))
548 mca_rcache_base_vma_delete (rcache_rgpusm->vma_module, reg);
549
550 assert(reg->ref_count == 0);
551 rc = cuda_closememhandle (NULL, reg);
552
553 if(OPAL_SUCCESS == rc) {
554 opal_free_list_return (&rcache_rgpusm->reg_list,
555 (opal_free_list_item_t*)reg);
556 }
557 }
558
559 return rc;
560 }
561
562 #define RGPUSM_RCACHE_NREGS 100
563
564 void mca_rcache_rgpusm_finalize(struct mca_rcache_base_module_t *rcache)
565 {
566 mca_rcache_rgpusm_module_t *rcache_rgpusm = (mca_rcache_rgpusm_module_t*)rcache;
567 mca_rcache_base_registration_t *reg;
568 mca_rcache_base_registration_t *regs[RGPUSM_RCACHE_NREGS];
569 int reg_cnt, i;
570 int rc;
571
572
573 if(true == mca_rcache_rgpusm_component.print_stats) {
574 opal_output(0, "%s rgpusm: stats "
575 "(hit/valid/invalid/miss/evicted): %d/%d/%d/%d/%d\n",
576 OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
577 rcache_rgpusm->stat_cache_hit, rcache_rgpusm->stat_cache_valid,
578 rcache_rgpusm->stat_cache_invalid, rcache_rgpusm->stat_cache_miss,
579 rcache_rgpusm->stat_evicted);
580 }
581
582 OPAL_THREAD_LOCK(&rcache->lock);
583 do {
584 reg_cnt = mca_rcache_base_vma_find_all (rcache_rgpusm->vma_module, 0, (size_t)-1,
585 regs, RGPUSM_RCACHE_NREGS);
586 opal_output(-1, "Registration size at finalize = %d", reg_cnt);
587
588 for(i = 0; i < reg_cnt; i++) {
589 reg = regs[i];
590
591 if(reg->ref_count) {
592 reg->ref_count = 0;
593 } else if (mca_rcache_rgpusm_component.leave_pinned) {
594 opal_list_remove_item(&rcache_rgpusm->lru_list,
595 (opal_list_item_t*)reg);
596 }
597
598
599 mca_rcache_base_vma_delete (rcache_rgpusm->vma_module, reg);
600
601
602 OPAL_THREAD_UNLOCK(&rcache->lock);
603 assert(reg->ref_count == 0);
604 rc = cuda_closememhandle (NULL, reg);
605 OPAL_THREAD_LOCK(&rcache->lock);
606
607 if(rc != OPAL_SUCCESS) {
608
609
610 continue;
611 }
612
613 opal_free_list_return (&rcache_rgpusm->reg_list,
614 (opal_free_list_item_t *) reg);
615 }
616 } while(reg_cnt == RGPUSM_RCACHE_NREGS);
617
618 OBJ_DESTRUCT(&rcache_rgpusm->lru_list);
619 OBJ_DESTRUCT(&rcache_rgpusm->reg_list);
620 OPAL_THREAD_UNLOCK(&rcache->lock);
621 }