root/oshmem/mca/memheap/base/memheap_base_static.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mca_memheap_base_static_init
  2. mca_memheap_base_static_exit
  3. _check_perms
  4. _check_address
  5. _check_pathname
  6. _load_segments

   1 /*
   2  * Copyright (c) 2013      Mellanox Technologies, Inc.
   3  *                         All rights reserved.
   4  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  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     /* read and parse segments from /proc/self/maps */
  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     /* FIXME Linux specific code */
  98 #ifdef __linux__
  99     extern unsigned _end;
 100     void* data_end = &_end;
 101 
 102     /**
 103      * SGI shmem only supports globals&static in main program.
 104      * It does not support them in shared objects or in dlopen()
 105      * (Clarified on PGAS 2011 tutorial)
 106      *
 107      * So ignored any maps that start higher then process _end
 108      * FIXME: make sure we do not register symmetric heap twice
 109      * if we decide to allow shared objects
 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     /* Probably we need to check found path but
 131      * To press check coverity issue following code is disabled
 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     /* FIXME!!! Linux specific code */
 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 }

/* [<][>][^][v][top][bottom][index][help] */