1 /*
2  * Copyright (c) 2004-2011 The Trustees of Indiana University and Indiana
3  *                         University Research and Technology
4  *                         Corporation.  All rights reserved.
5  * Copyright (c) 2004-2005 The University of Tennessee and The University
6  *                         of Tennessee Research Foundation.  All rights
7  *                         reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  *                         University of Stuttgart.  All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  *                         All rights reserved.
12  * Copyright (c) 2009-2012 Cisco Systems, Inc.  All rights reserved.
13  * Copyright (c) 2011-2012 Los Alamos National Security, LLC.
14  *                         All rights reserved.
15  * Copyright (c) 2011-2014 NVIDIA Corporation.  All rights reserved.
16  * Copyright (c) 2015      Intel, Inc. All rights reserved
17  * $COPYRIGHT$
18  *
19  * Additional copyrights may follow
20  *
21  * $HEADER$
22  */
23 
24 #include "opal_config.h"
25 #include <string.h>
26 #include "common_sm_mpool.h"
27 #include "opal/mca/common/sm/common_sm.h"
28 #include "opal/mca/common/cuda/common_cuda.h"
29 #include "opal/mca/allocator/base/base.h"
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33 #include "opal/mca/hwloc/base/base.h"
34 
35 #if OPAL_ENABLE_FT_CR    == 1
36 #include "orte/mca/sstore/sstore.h"
37 #include "opal/mca/mpool/base/base.h"
38 #include "ompi/runtime/ompi_cr.h" /* TODO */
39 #endif
40 
41 static void sm_module_finalize(mca_mpool_base_module_t* module);
42 
43 /*
44  *  Returns base address of shared memory mapping.
45  */
46 static void *mca_common_sm_mpool_base (mca_mpool_base_module_t *mpool);
47 
48 /**
49   *  Allocate block of shared memory.
50   */
51 static void *mca_common_sm_mpool_alloc (mca_mpool_base_module_t *mpool,
52                                         size_t size, size_t align,
53                                         uint32_t flags);
54 
55 /**
56   * free function typedef
57   */
58 static void mca_common_sm_mpool_free(mca_mpool_base_module_t *mpool,
59                                      void *addr);
60 
61 /**
62  * Fault Tolerance Event Notification Function
63  * @param state Checkpoint Stae
64  * @return OPAL_SUCCESS or failure status
65  */
66 static int mca_common_sm_mpool_ft_event (int state);
67 
68 
69 /*
70  *  Initializes the mpool module.
71  */
mca_common_sm_mpool_module_init(mca_common_sm_mpool_module_t * mpool)72 static void mca_common_sm_mpool_module_init(mca_common_sm_mpool_module_t* mpool)
73 {
74     mpool->super.mpool_base = mca_common_sm_mpool_base;
75     mpool->super.mpool_alloc = mca_common_sm_mpool_alloc;
76     mpool->super.mpool_free = mca_common_sm_mpool_free;
77     mpool->super.mpool_finalize = sm_module_finalize;
78     mpool->super.mpool_ft_event = mca_common_sm_mpool_ft_event;
79     mpool->super.flags = 0;
80 
81     mpool->sm_size = 0;
82     mpool->sm_allocator = NULL;
83     mpool->sm_mmap = NULL;
84     mpool->sm_common_module = NULL;
85     mpool->mem_node = -1;
86 }
87 
common_sm_mpool_create(mca_common_sm_mpool_resources_t * resources)88 mca_mpool_base_module_t *common_sm_mpool_create (mca_common_sm_mpool_resources_t *resources)
89 {
90     mca_common_sm_mpool_module_t *mpool_module;
91     mca_allocator_base_component_t* allocator_component;
92 
93     /* Make a new mpool module */
94     mpool_module = (mca_common_sm_mpool_module_t *) malloc (sizeof (*mpool_module));
95     mca_common_sm_mpool_module_init(mpool_module);
96 
97     /* set sm_size */
98     mpool_module->sm_size = resources->size;
99 
100     allocator_component = mca_allocator_component_lookup(resources->allocator);
101 
102     /* if specified allocator cannot be loaded - look for an alternative */
103     if (NULL == allocator_component) {
104         if (opal_list_get_size(&opal_allocator_base_framework.framework_components) == 0) {
105             mca_base_component_list_item_t *item =
106                 (mca_base_component_list_item_t *)
107                 opal_list_get_first(&opal_allocator_base_framework.framework_components);
108             allocator_component =
109                 (mca_allocator_base_component_t *)item->cli_component;
110             opal_output(
111                 0, "mca_common_sm_mpool_init: "
112                 "unable to locate allocator: %s - using %s\n",
113                 resources->allocator,
114                 allocator_component->allocator_version.mca_component_name);
115         } else {
116             opal_output(0, "mca_common_sm_mpool_init: "
117                         "unable to locate allocator: %s\n",
118                         resources->allocator);
119             free(mpool_module);
120             return NULL;
121         }
122     }
123 
124     mpool_module->mem_node = resources->mem_node;
125 
126     if (NULL == (mpool_module->sm_common_module =
127         mca_common_sm_module_attach(&resources->bs_meta_buf,
128                                     sizeof(mca_common_sm_module_t), 8))) {
129         opal_output(0, "mca_common_sm_mpool_init: "
130                     "unable to create shared memory mapping (%s)",
131                     resources->bs_meta_buf.seg_name);
132         free(mpool_module);
133         return NULL;
134     }
135 
136     /* setup allocator */
137     mpool_module->sm_allocator =
138       allocator_component->allocator_init (true, mca_common_sm_seg_alloc,
139                                            NULL, mpool_module->sm_common_module);
140     if (NULL == mpool_module->sm_allocator) {
141         opal_output(0, "mca_common_sm_mpool_init: unable to initialize allocator");
142         free(mpool_module);
143         return NULL;
144     }
145 
146     return &mpool_module->super;
147 }
148 
149 
150 /*
151  * base address of shared memory mapping
152  */
mca_common_sm_mpool_base(mca_mpool_base_module_t * mpool)153 static void *mca_common_sm_mpool_base(mca_mpool_base_module_t *mpool)
154 {
155     mca_common_sm_mpool_module_t *sm_mpool = (mca_common_sm_mpool_module_t *) mpool;
156     return (NULL != sm_mpool->sm_common_module) ?
157         sm_mpool->sm_common_module->module_seg_addr : NULL;
158 }
159 
160 /**
161   * allocate function
162   */
mca_common_sm_mpool_alloc(mca_mpool_base_module_t * mpool,size_t size,size_t align,uint32_t flags)163 static void *mca_common_sm_mpool_alloc (mca_mpool_base_module_t* mpool,
164                                         size_t size, size_t align, uint32_t flags)
165 {
166     mca_common_sm_mpool_module_t* mpool_sm = (mca_common_sm_mpool_module_t*)mpool;
167     opal_hwloc_base_memory_segment_t mseg;
168 
169     mseg.mbs_start_addr =
170         mpool_sm->sm_allocator->alc_alloc(mpool_sm->sm_allocator, size, align);
171 
172     if (mpool_sm->mem_node >= 0) {
173         mseg.mbs_len = size;
174         opal_hwloc_base_membind(&mseg, 1, mpool_sm->mem_node);
175     }
176 
177     return mseg.mbs_start_addr;
178 }
179 
180 /**
181   * free function
182   */
mca_common_sm_mpool_free(mca_mpool_base_module_t * mpool,void * addr)183 void mca_common_sm_mpool_free(mca_mpool_base_module_t *mpool, void *addr)
184 {
185     mca_common_sm_mpool_module_t* mpool_sm = (mca_common_sm_mpool_module_t*)mpool;
186     mpool_sm->sm_allocator->alc_free(mpool_sm->sm_allocator, addr);
187 }
188 
sm_module_finalize(mca_mpool_base_module_t * module)189 static void sm_module_finalize(mca_mpool_base_module_t* module)
190 {
191     mca_common_sm_mpool_module_t *sm_module = (mca_common_sm_mpool_module_t*) module;
192 
193     if (NULL != sm_module->sm_common_module) {
194         if (OPAL_SUCCESS ==
195             mca_common_sm_fini(sm_module->sm_common_module)) {
196 #if OPAL_ENABLE_FT_CR == 1
197             /* Only unlink the file if we are *not* restarting.  If we
198                are restarting the file will be unlinked at a later
199                time. */
200             if (OPAL_CR_STATUS_RESTART_PRE  != opal_cr_checkpointing_state &&
201                 OPAL_CR_STATUS_RESTART_POST != opal_cr_checkpointing_state ) {
202                 unlink(sm_module->sm_common_module->shmem_ds.seg_name);
203             }
204 #else
205             unlink(sm_module->sm_common_module->shmem_ds.seg_name);
206 #endif
207         }
208         OBJ_RELEASE(sm_module->sm_common_module);
209         sm_module->sm_common_module = NULL;
210     }
211 }
212 
213 #if OPAL_ENABLE_FT_CR    == 0
mca_common_sm_mpool_ft_event(int state)214 int mca_common_sm_mpool_ft_event(int state) {
215     return OPAL_SUCCESS;
216 }
217 #else
mca_common_sm_mpool_ft_event(int state)218 int mca_common_sm_mpool_ft_event(int state) {
219     mca_mpool_base_module_t *self_module = NULL;
220     mca_common_sm_mpool_module_t   *self_sm_module = NULL;
221     char * file_name = NULL;
222 
223     if(OPAL_CRS_CHECKPOINT == state) {
224         /* Record the shared memory filename */
225         asprintf( &file_name, "%s"OPAL_PATH_SEP"shared_mem_pool.%s",
226                   opal_process_info.job_session_dir,
227                   opal_proc_local_get()->proc_hostname );
228         /* Disabled to get FT code compiled again
229          * TODO: FIXIT soon
230         orte_sstore.set_attr(orte_sstore_handle_current, SSTORE_METADATA_LOCAL_TOUCH, file_name);
231          */
232         free(file_name);
233         file_name = NULL;
234     }
235     else if(OPAL_CRS_CONTINUE == state) {
236         if (opal_cr_continue_like_restart) {
237             /* Find the sm module */
238             self_module = mca_mpool_base_module_lookup("sm");
239             self_sm_module = (mca_common_sm_mpool_module_t*) self_module;
240 
241             /* Mark the old sm file for eventual removal via CRS */
242             if (NULL != self_sm_module->sm_common_module) {
243                 opal_crs_base_cleanup_append(self_sm_module->sm_common_module->shmem_ds.seg_name, false);
244             }
245 
246             /* Remove self from the list of all modules */
247             mca_mpool_base_module_destroy(self_module);
248         }
249     }
250     else if(OPAL_CRS_RESTART == state ||
251             OPAL_CRS_RESTART_PRE == state) {
252         /* Find the sm module */
253         self_module = mca_mpool_base_module_lookup("sm");
254         self_sm_module = (mca_common_sm_mpool_module_t*) self_module;
255 
256         /* Mark the old sm file for eventual removal via CRS */
257         if (NULL != self_sm_module->sm_common_module) {
258             opal_crs_base_cleanup_append(self_sm_module->sm_common_module->shmem_ds.seg_name, false);
259         }
260 
261         /* Remove self from the list of all modules */
262         mca_mpool_base_module_destroy(self_module);
263     }
264     else if(OPAL_CRS_TERM == state ) {
265         ;
266     }
267     else {
268         ;
269     }
270 
271     return OPAL_SUCCESS;
272 }
273 #endif /* OPAL_ENABLE_FT_CR */
274