|
22 | 22 |
|
23 | 23 | int mca_btl_vader_xpmem_init (void) |
24 | 24 | { |
25 | | - mca_btl_vader_component.my_seg_id = xpmem_make (0, VADER_MAX_ADDRESS, XPMEM_PERMIT_MODE, (void *)0666); |
| 25 | + /* Any attachment that goes past the Linux TASK_SIZE will always fail. To prevent this we need to |
| 26 | + * determine the value of TASK_SIZE. On x86_64 the value was hard-coded in vader to be |
| 27 | + * 0x7ffffffffffful but this approach does not work with AARCH64 (and possibly other architectures). |
| 28 | + * Since there is really no way to directly determine the value we can (in all cases?) look through |
| 29 | + * the mapping for this process to determine what the largest address is. This should be the top |
| 30 | + * of the stack. No heap allocations should be larger than this value. Since the largest address |
| 31 | + * may differ between processes the value must be shared as part of the modex and stored in the |
| 32 | + * endpoint. */ |
| 33 | + FILE *fh = fopen("/proc/self/maps", "r"); |
| 34 | + if (NULL == fh) { |
| 35 | + BTL_ERROR(("could not open /proc/self/maps for reading. disabling XPMEM")); |
| 36 | + return OPAL_ERR_NOT_AVAILABLE; |
| 37 | + } |
| 38 | + |
| 39 | + char buffer[1024]; |
| 40 | + uintptr_t address_max = 0; |
| 41 | + while (fgets(buffer, sizeof(buffer), fh)) { |
| 42 | + uintptr_t low, high; |
| 43 | + char *tmp; |
| 44 | + /* each line of /proc/self/maps starts with low-high in hexidecimal (without a 0x) */ |
| 45 | + low = strtoul(buffer, &tmp, 16); |
| 46 | + high = strtoul(tmp+1, NULL, 16); |
| 47 | + if (address_max < high) { |
| 48 | + address_max = high; |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + fclose (fh); |
| 53 | + |
| 54 | + if (0 == address_max) { |
| 55 | + BTL_ERROR(("could not determine the address max")); |
| 56 | + return OPAL_ERR_NOT_AVAILABLE; |
| 57 | + } |
| 58 | + |
| 59 | + /* save the calcuated maximum */ |
| 60 | + mca_btl_vader_component.my_address_max = address_max - 1; |
| 61 | + |
| 62 | + /* it is safe to use XPMEM_MAXADDR_SIZE here (which is always (size_t)-1 even though |
| 63 | + * it is not safe for attach */ |
| 64 | + mca_btl_vader_component.my_seg_id = xpmem_make (0, XPMEM_MAXADDR_SIZE, XPMEM_PERMIT_MODE, |
| 65 | + (void *)0666); |
26 | 66 | if (-1 == mca_btl_vader_component.my_seg_id) { |
27 | 67 | return OPAL_ERR_NOT_AVAILABLE; |
28 | 68 | } |
@@ -110,8 +150,8 @@ mca_rcache_base_registration_t *vader_get_registation (struct mca_btl_base_endpo |
110 | 150 |
|
111 | 151 | base = OPAL_DOWN_ALIGN((uintptr_t) rem_ptr, attach_align, uintptr_t); |
112 | 152 | bound = OPAL_ALIGN((uintptr_t) rem_ptr + size - 1, attach_align, uintptr_t) + 1; |
113 | | - if (OPAL_UNLIKELY(bound > VADER_MAX_ADDRESS)) { |
114 | | - bound = VADER_MAX_ADDRESS; |
| 153 | + if (OPAL_UNLIKELY(bound > ep->segment_data.xpmem.address_max)) { |
| 154 | + bound = ep->segment_data.xpmem.address_max; |
115 | 155 | } |
116 | 156 |
|
117 | 157 | check_ctx.base = base; |
|
0 commit comments