This source file includes following definitions.
- mca_memheap_base_static_init
- mca_memheap_base_static_exit
- _check_perms
- _check_address
- _check_pathname
- _load_segments
1
2
3
4
5
6
7
8
9
10
11 #include "oshmem_config.h"
12
13 #include "oshmem/util/oshmem_util.h"
14 #include "oshmem/proc/proc.h"
15 #include "oshmem/mca/memheap/memheap.h"
16 #include "oshmem/mca/memheap/base/base.h"
17 #include "oshmem/util/oshmem_util.h"
18
19 #include <stdio.h>
20
21 struct map_segment_desc {
22 void* start;
23 void* end;
24 char perms[8];
25 uint64_t offset;
26 char dev[8];
27 uint64_t inode;
28 char pathname[MAXPATHLEN];
29 };
30
31 typedef struct memheap_static_context {
32 struct {
33 void* start;
34 void* end;
35 } mem_segs[MCA_MEMHEAP_MAX_SEGMENTS];
36 int n_segments;
37 } memheap_static_context_t;
38
39 static memheap_static_context_t memheap_context;
40
41 static int _load_segments(void);
42 static int _check_perms(struct map_segment_desc *seg);
43 static int _check_address(struct map_segment_desc *seg);
44 static int _check_pathname(struct map_segment_desc *seg);
45
46 int mca_memheap_base_static_init(mca_memheap_map_t *map)
47 {
48
49 int ret = OSHMEM_SUCCESS;
50
51 assert(map);
52 assert(HEAP_SEG_INDEX < map->n_segments);
53
54 ret = _load_segments();
55
56 if (OSHMEM_SUCCESS == ret) {
57 int i;
58 size_t total_mem;
59
60 for (i = 0, total_mem = 0; i < memheap_context.n_segments; i++) {
61 map_segment_t *s = &map->mem_segs[map->n_segments];
62
63 memset(s, 0, sizeof(*s));
64 MAP_SEGMENT_RESET_FLAGS(s);
65 s->seg_id = MAP_SEGMENT_SHM_INVALID;
66 s->super.va_base = memheap_context.mem_segs[i].start;
67 s->super.va_end = memheap_context.mem_segs[i].end;
68 s->seg_size = ((uintptr_t)s->super.va_end - (uintptr_t)s->super.va_base);
69 s->type = MAP_SEGMENT_STATIC;
70 map->n_segments++;
71
72 total_mem += ((uintptr_t)s->super.va_end - (uintptr_t)s->super.va_base);
73 }
74 MEMHEAP_VERBOSE(1,
75 "Memheap static memory: %llu byte(s), %d segments",
76 (unsigned long long)total_mem, map->n_segments);
77 }
78
79 return ret;
80 }
81
82 void mca_memheap_base_static_exit(mca_memheap_map_t *map)
83 {
84 assert(map);
85 }
86
87 static int _check_perms(struct map_segment_desc *seg)
88 {
89 if (!strcmp(seg->perms, "rw-p") || !strcmp(seg->perms, "rwxp"))
90 return OSHMEM_SUCCESS;
91
92 return OSHMEM_ERROR;
93 }
94
95 static int _check_address(struct map_segment_desc *seg)
96 {
97
98 #ifdef __linux__
99 extern unsigned _end;
100 void* data_end = &_end;
101
102
103
104
105
106
107
108
109
110
111 if ((uintptr_t)seg->start > (uintptr_t)data_end) {
112 MEMHEAP_VERBOSE(100,
113 "skip segment: data _end < segment start (%p < %p)",
114 data_end, seg->start);
115 return OSHMEM_ERROR;
116 }
117
118 if ((uintptr_t)seg->end > (uintptr_t)data_end) {
119 MEMHEAP_VERBOSE(100,
120 "adjust segment: data _end < segment end (%p < %p",
121 data_end, seg->end);
122 seg->end = data_end;
123 }
124 #endif
125 return OSHMEM_SUCCESS;
126 }
127
128 static int _check_pathname(struct map_segment_desc *seg)
129 {
130
131
132
133 #if 0
134 char *p;
135 if ('\0' == seg->pathname[0])
136 return OSHMEM_SUCCESS;
137
138 if (0 == strncmp(seg->pathname, "/lib", 4))
139 return OSHMEM_ERROR;
140
141 if (0 == strncmp(seg->pathname, "/usr/lib", 8))
142 return OSHMEM_ERROR;
143
144 if (0 == strncmp(seg->pathname, "/dev", 4))
145 return OSHMEM_ERROR;
146
147 if (0 == strcmp(seg->pathname, "[stack]"))
148 return OSHMEM_ERROR;
149
150 if (0 == strcmp(seg->pathname, "[vdso]"))
151 return OSHMEM_ERROR;
152
153 if (0 == strcmp(seg->pathname, "[vsyscall]"))
154 return OSHMEM_ERROR;
155
156 p = rindex(seg->pathname, '/');
157 if (p) {
158 if (0 == strncmp(p+1, "libshmem.so", 11))
159 return OSHMEM_ERROR;
160
161 if (0 == strncmp(p+1, "lib" OMPI_LIBMPI_NAME ".so", 9))
162 return OSHMEM_ERROR;
163
164 if (0 == strncmp(p+1, "libmca_common_sm.so", 19))
165 return OSHMEM_ERROR;
166 }
167 #endif
168 return OSHMEM_SUCCESS;
169 }
170
171 static int _load_segments(void)
172 {
173 FILE *fp;
174 char line[1024];
175 struct map_segment_desc seg;
176
177 memheap_context.n_segments = 0;
178
179 fp = fopen("/proc/self/maps", "r");
180 if (NULL == fp) {
181 MEMHEAP_ERROR("Failed to open /proc/self/maps");
182 return OSHMEM_ERROR;
183 }
184
185 while (NULL != fgets(line, sizeof(line), fp)) {
186 memset(&seg, 0, sizeof(seg));
187 if (3 > sscanf(line,
188 "%llx-%llx %s %llx %s %llx %s",
189 (unsigned long long *) &seg.start,
190 (unsigned long long *) &seg.end,
191 seg.perms,
192 (unsigned long long *) &seg.offset,
193 seg.dev,
194 (unsigned long long *) &seg.inode,
195 seg.pathname)) {
196 MEMHEAP_ERROR("Failed to sscanf /proc/self/maps output %s", line);
197 fclose(fp);
198 return OSHMEM_ERROR;
199 }
200
201 if (OSHMEM_ERROR == _check_address(&seg))
202 continue;
203
204 if (OSHMEM_ERROR == _check_pathname(&seg))
205 continue;
206
207 if (OSHMEM_ERROR == _check_perms(&seg))
208 continue;
209
210 MEMHEAP_VERBOSE(5, "add: %s", line);
211 if (MCA_MEMHEAP_MAX_SEGMENTS <= memheap_context.n_segments) {
212 MEMHEAP_ERROR("too many segments (max = %d): skip %s",
213 MCA_MEMHEAP_MAX_SEGMENTS, line);
214 continue;
215 }
216 if (memheap_context.n_segments > 0
217 && seg.start
218 == memheap_context.mem_segs[memheap_context.n_segments
219 - 1].end) {
220 MEMHEAP_VERBOSE(5, "Coalescing segment");
221 memheap_context.mem_segs[memheap_context.n_segments - 1].end =
222 seg.end;
223 } else {
224 memheap_context.mem_segs[memheap_context.n_segments].start =
225 seg.start;
226 memheap_context.mem_segs[memheap_context.n_segments].end = seg.end;
227 memheap_context.n_segments++;
228 }
229 }
230
231 fclose(fp);
232 return OSHMEM_SUCCESS;
233 }