/* ////////////////////////////////////////////////////////////////////////// */ static int segment_detach(opal_shmem_ds_t *ds_buf) { int rc = OPAL_SUCCESS; OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_output, "%s: %s: detaching " "(id: %d, size: %"PRIsize_t", name: %s)\n", mca_shmem_windows_component.super.base_version.mca_type_name, mca_shmem_windows_component.super.base_version.mca_component_name, ds_buf->seg_id, ds_buf->seg_size, ds_buf->seg_name) ); if (0 == UnmapViewOfFile((LPVOID)ds_buf->seg_base_addr)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-windows.txt", "sys call fail", 1, hn, "UnmapViewOfFile", "", strerror(err), err); rc = OPAL_ERROR; } /* reset the contents of the opal_shmem_ds_t associated with this * shared memory segment. */ shmem_ds_reset(ds_buf); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_detach(map_segment_t *ds_buf, sshmem_mkey_t *mkey) { int rc = OSHMEM_SUCCESS; assert(ds_buf); OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: detaching " "(id: %d, addr: %p size: %lu, name: %s)\n", mca_sshmem_sysv_component.super.base_version.mca_type_name, mca_sshmem_sysv_component.super.base_version.mca_component_name, ds_buf->seg_id, ds_buf->seg_base_addr, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); if (ds_buf->seg_id != MAP_SEGMENT_SHM_INVALID) { shmctl(ds_buf->seg_id, IPC_RMID, NULL ); } if (mca_sshmem_sysv_component.use_hp > 0) { /** * Workaround kernel panic when detaching huge pages from user space simultanously from several processes * dont detach here instead let kernel do it during process cleanup */ /* shmdt((void *)ds_buf->seg_base_addr); */ } /* reset the contents of the map_segment_t associated with this * shared memory segment. */ shmem_ds_reset(ds_buf); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_detach(opal_shmem_ds_t *ds_buf) { int rc = OPAL_SUCCESS; OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: detaching " "(id: %d, size: %lu, name: %s)\n", mca_shmem_sysv_component.super.base_version.mca_type_name, mca_shmem_sysv_component.super.base_version.mca_component_name, ds_buf->seg_id, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); if (0 != shmdt((char*)ds_buf->seg_base_addr)) { int err = errno; char hn[OPAL_MAXHOSTNAMELEN]; gethostname(hn, sizeof(hn)); opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmdt(2)", "", strerror(err), err); rc = OPAL_ERROR; } /* reset the contents of the opal_shmem_ds_t associated with this * shared memory segment. */ shmem_ds_reset(ds_buf); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_detach(map_segment_t *ds_buf, sshmem_mkey_t *mkey) { int rc = OSHMEM_SUCCESS; assert(ds_buf); OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: detaching " "(id: %d, addr: %p size: %lu)\n", mca_sshmem_mmap_component.super.base_version.mca_type_name, mca_sshmem_mmap_component.super.base_version.mca_component_name, ds_buf->seg_id, ds_buf->super.va_base, (unsigned long)ds_buf->seg_size) ); munmap((void *)ds_buf->super.va_base, ds_buf->seg_size); /* reset the contents of the map_segment_t associated with this * shared memory segment. */ shmem_ds_reset(ds_buf); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(map_segment_t *ds_buf, const char *file_name, size_t size) { int rc = OSHMEM_SUCCESS; void *addr = NULL; int shmid = MAP_SEGMENT_SHM_INVALID; int flags; assert(ds_buf); /* init the contents of map_segment_t */ shmem_ds_reset(ds_buf); /* for sysv shared memory we don't have to worry about the backing store * being located on a network file system... so no check is needed here. */ /* create a new shared memory segment and save the shmid. note the use of * real_size here */ flags = IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR; #if defined (SHM_HUGETLB) flags |= (mca_sshmem_sysv_component.use_hp ? SHM_HUGETLB : 0); #endif /* Create a new shared memory segment and save the shmid. */ shmid = shmget(IPC_PRIVATE, size, flags); if (shmid == MAP_SEGMENT_SHM_INVALID) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "Failed to shmget() %llu bytes (errno=%d)", (unsigned long long)size, errno)); opal_show_help("help-oshmem-sshmem-sysv.txt", "create segment failure", true, orte_process_info.nodename, (unsigned) size, strerror(errno), errno); return OSHMEM_ERROR; } /* Attach to the sement */ addr = shmat(shmid, (void *) mca_sshmem_base_start_address, 0); if (addr == (void *) -1L) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "Failed to shmat() %llu bytes (errno=%d)", (unsigned long long)size, errno) ); shmctl(shmid, IPC_RMID, NULL ); return OSHMEM_ERR_OUT_OF_RESOURCE; } shmctl(shmid, IPC_RMID, NULL ); ds_buf->type = MAP_SEGMENT_ALLOC_SHM; ds_buf->seg_id = shmid; ds_buf->seg_base_addr = addr; ds_buf->seg_size = size; ds_buf->end = (void*)((uintptr_t)ds_buf->seg_base_addr + ds_buf->seg_size); OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: create %s " "(id: %d, addr: %p size: %lu, name: %s)\n", mca_sshmem_sysv_component.super.base_version.mca_type_name, mca_sshmem_sysv_component.super.base_version.mca_component_name, (rc ? "failure" : "successful"), ds_buf->seg_id, ds_buf->seg_base_addr, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(opal_shmem_ds_t *ds_buf, const char *file_name, size_t size) { int rc = OPAL_SUCCESS; pid_t my_pid = getpid(); /* the real size of the shared memory segment. this includes enough space * to store our segment header. */ size_t real_size = size + sizeof(opal_shmem_seg_hdr_t); opal_shmem_seg_hdr_t *seg_hdrp = MAP_FAILED; /* init the contents of opal_shmem_ds_t */ shmem_ds_reset(ds_buf); /* for sysv shared memory we don't have to worry about the backing store * being located on a network file system... so no check is needed here. */ /* create a new shared memory segment and save the shmid. note the use of * real_size here */ if (-1 == (ds_buf->seg_id = shmget(IPC_PRIVATE, real_size, IPC_CREAT | IPC_EXCL | S_IRWXU))) { int err = errno; char hn[OPAL_MAXHOSTNAMELEN]; gethostname(hn, sizeof(hn)); opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmget(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* attach to the sement */ else if ((void *)-1 == (seg_hdrp = shmat(ds_buf->seg_id, NULL, 0))) { int err = errno; char hn[OPAL_MAXHOSTNAMELEN]; gethostname(hn, sizeof(hn)); opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmat(2)", "", strerror(err), err); shmctl(ds_buf->seg_id, IPC_RMID, NULL); rc = OPAL_ERROR; goto out; } /* mark the segment for destruction - if we are here, then the run-time * component selection test detected adequate support for this type of * thing. */ else if (0 != shmctl(ds_buf->seg_id, IPC_RMID, NULL)) { int err = errno; char hn[OPAL_MAXHOSTNAMELEN]; gethostname(hn, sizeof(hn)); opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmctl(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* all is well */ else { /* -- initialize the shared memory segment -- */ opal_atomic_rmb(); /* init segment lock */ opal_atomic_init(&seg_hdrp->lock, OPAL_ATOMIC_UNLOCKED); /* i was the creator of this segment, so note that fact */ seg_hdrp->cpid = my_pid; opal_atomic_wmb(); /* -- initialize the contents of opal_shmem_ds_t -- */ ds_buf->seg_cpid = my_pid; ds_buf->seg_size = real_size; ds_buf->seg_base_addr = (unsigned char *)seg_hdrp; /* notice that we are not setting ds_buf->name here. sysv doesn't use * it, so don't worry about it - shmem_ds_reset took care of * initialization, so we aren't passing garbage around. */ /* set "valid" bit because setment creation was successful */ OPAL_SHMEM_DS_SET_VALID(ds_buf); OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: create successful " "(id: %d, size: %lu, name: %s)\n", mca_shmem_sysv_component.super.base_version.mca_type_name, mca_shmem_sysv_component.super.base_version.mca_component_name, ds_buf->seg_id, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); } out: /* an error occured, so invalidate the shmem object and release any * allocated resources. */ if (OPAL_SUCCESS != rc) { /* best effort to delete the segment. */ if ((void *)-1 != seg_hdrp) { shmdt((char*)seg_hdrp); } shmctl(ds_buf->seg_id, IPC_RMID, NULL); /* always invalidate in this error path */ shmem_ds_reset(ds_buf); } return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(opal_shmem_ds_t *ds_buf, const char *file_name, size_t size) { int rc = OPAL_SUCCESS; char *real_file_name = NULL; pid_t my_pid = getpid(); bool space_available = false; uint64_t amount_space_avail = 0; /* the real size of the shared memory segment. this includes enough space * to store our segment header. */ size_t real_size = size + sizeof(opal_shmem_seg_hdr_t); opal_shmem_seg_hdr_t *seg_hdrp = MAP_FAILED; /* init the contents of opal_shmem_ds_t */ shmem_ds_reset(ds_buf); /* change the path of shmem mmap's backing store? */ if (0 != opal_shmem_mmap_relocate_backing_file) { int err; if (path_usable(opal_shmem_mmap_backing_file_base_dir, &err)) { if (NULL == (real_file_name = get_uniq_file_name(opal_shmem_mmap_backing_file_base_dir, file_name))) { /* out of resources */ return OPAL_ERROR; } } /* a relocated backing store was requested, but the path specified * cannot be used :-(. if the flag is negative, then warn and continue * with the default path. otherwise, fail. */ else if (opal_shmem_mmap_relocate_backing_file < 0) { opal_output(0, "shmem: mmap: WARNING: could not relocate " "backing store to \"%s\" (%s). Continuing with " "default path.\n", opal_shmem_mmap_backing_file_base_dir, strerror(err)); } /* must be positive, so fail */ else { opal_output(0, "shmem: mmap: WARNING: could not relocate " "backing store to \"%s\" (%s). Cannot continue with " "shmem mmap.\n", opal_shmem_mmap_backing_file_base_dir, strerror(err)); return OPAL_ERROR; } } /* are we using the default path? */ if (NULL == real_file_name) { /* use the path specified by the caller of this function */ if (NULL == (real_file_name = strdup(file_name))) { /* out of resources */ return OPAL_ERROR; } } OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: backing store base directory: %s\n", mca_shmem_mmap_component.super.base_version.mca_type_name, mca_shmem_mmap_component.super.base_version.mca_component_name, real_file_name) ); /* determine whether the specified filename is on a network file system. * this is an important check because if the backing store is located on * a network filesystem, the user may see a shared memory performance hit. */ if (opal_shmem_mmap_nfs_warning && opal_path_nfs(real_file_name)) { char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "mmap on nfs", 1, hn, real_file_name); } /* let's make sure we have enough space for the backing file */ if (OPAL_SUCCESS != (rc = enough_space(real_file_name, real_size, &amount_space_avail, &space_available))) { opal_output(0, "shmem: mmap: an error occurred while determining " "whether or not %s could be created.", real_file_name); /* rc is set */ goto out; } if (!space_available) { char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; rc = OPAL_ERR_OUT_OF_RESOURCE; opal_show_help("help-opal-shmem-mmap.txt", "target full", 1, real_file_name, hn, (unsigned long)real_size, (unsigned long long)amount_space_avail); goto out; } /* enough space is available, so create the segment */ if (-1 == (ds_buf->seg_id = open(real_file_name, O_CREAT | O_RDWR, 0600))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "open(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* size backing file - note the use of real_size here */ if (0 != ftruncate(ds_buf->seg_id, real_size)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "ftruncate(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } if (MAP_FAILED == (seg_hdrp = (opal_shmem_seg_hdr_t *) mmap(NULL, real_size, PROT_READ | PROT_WRITE, MAP_SHARED, ds_buf->seg_id, 0))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "mmap(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* all is well */ else { /* -- initialize the shared memory segment -- */ opal_atomic_rmb(); /* init segment lock */ opal_atomic_init(&seg_hdrp->lock, OPAL_ATOMIC_UNLOCKED); /* i was the creator of this segment, so note that fact */ seg_hdrp->cpid = my_pid; opal_atomic_wmb(); /* -- initialize the contents of opal_shmem_ds_t -- */ ds_buf->seg_cpid = my_pid; ds_buf->seg_size = real_size; ds_buf->seg_base_addr = (unsigned char *)seg_hdrp; (void)strncpy(ds_buf->seg_name, real_file_name, OPAL_PATH_MAX - 1); /* set "valid" bit because setment creation was successful */ OPAL_SHMEM_DS_SET_VALID(ds_buf); OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: create successful " "(id: %d, size: %lu, name: %s)\n", mca_shmem_mmap_component.super.base_version.mca_type_name, mca_shmem_mmap_component.super.base_version.mca_component_name, ds_buf->seg_id, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); } out: /* in this component, the id is the file descriptor returned by open. this * check is here to see if it is safe to call close on the file descriptor. * that is, we are making sure that our call to open was successful and * we are not not in an error path. */ if (-1 != ds_buf->seg_id) { if (0 != close(ds_buf->seg_id)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "close(2)", "", strerror(err), err); rc = OPAL_ERROR; } } /* an error occured, so invalidate the shmem object and munmap if needed */ if (OPAL_SUCCESS != rc) { if (MAP_FAILED != seg_hdrp) { munmap((void *)seg_hdrp, real_size); } shmem_ds_reset(ds_buf); } /* safe to free now because its contents have already been copied */ if (NULL != real_file_name) { free(real_file_name); } return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_detach(map_segment_t *ds_buf, sshmem_mkey_t *mkey) { int rc = OSHMEM_SUCCESS; openib_device_t *device = &memheap_device; int i; assert(ds_buf); OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: detaching " "(id: %d, addr: %p size: %lu, name: %s)\n", mca_sshmem_verbs_component.super.base_version.mca_type_name, mca_sshmem_verbs_component.super.base_version.mca_component_name, ds_buf->seg_id, ds_buf->super.va_base, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); if (device) { if (0 < (i = opal_value_array_get_size(&device->ib_mr_array))) { struct ibv_mr** array; struct ibv_mr* ib_mr = NULL; array = OPAL_VALUE_ARRAY_GET_BASE(&device->ib_mr_array, struct ibv_mr *); for (i--;i >= 0; i--) { ib_mr = array[i]; if(ibv_dereg_mr(ib_mr)) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error ibv_dereg_mr(): %d: %s", errno, strerror(errno)) ); rc = OSHMEM_ERROR; } opal_value_array_remove_item(&device->ib_mr_array, i); } if (!rc && device->ib_mr_shared) { device->ib_mr_shared = NULL; } OBJ_DESTRUCT(&device->ib_mr_array); } if (!rc && device->ib_pd) { if (ibv_dealloc_pd(device->ib_pd)) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error ibv_dealloc_pd(): %d: %s", errno, strerror(errno)) ); rc = OSHMEM_ERROR; } else { device->ib_pd = NULL; } } if(!rc && device->ib_dev_context) { if(ibv_close_device(device->ib_dev_context)) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error ibv_close_device(): %d: %s", errno, strerror(errno)) ); rc = OSHMEM_ERROR; } else { device->ib_dev_context = NULL; } } if(!rc && device->ib_devs) { ibv_free_device_list(device->ib_devs); device->ib_devs = NULL; } } /* reset the contents of the map_segment_t associated with this * shared memory segment. */ shmem_ds_reset(ds_buf); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(map_segment_t *ds_buf, const char *file_name, size_t size) { int rc = OSHMEM_SUCCESS; openib_device_t *device = &memheap_device; int num_devs = 0; int i = 0; assert(ds_buf); /* init the contents of map_segment_t */ shmem_ds_reset(ds_buf); memset(device, 0, sizeof(*device)); #ifdef HAVE_IBV_GET_DEVICE_LIST device->ib_devs = ibv_get_device_list(&num_devs); #else #error unsupported ibv_get_device_list in infiniband/verbs.h #endif if (num_devs == 0 || !device->ib_devs) { return OSHMEM_ERR_NOT_SUPPORTED; } /* Open device */ if (NULL != mca_sshmem_verbs_component.hca_name) { for (i = 0; i < num_devs; i++) { if (0 == strcmp(mca_sshmem_verbs_component.hca_name, ibv_get_device_name(device->ib_devs[i]))) { device->ib_dev = device->ib_devs[i]; break; } } } else { device->ib_dev = device->ib_devs[0]; } if (NULL == device->ib_dev) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error getting device says %d: %s", errno, strerror(errno)) ); return OSHMEM_ERR_NOT_FOUND; } if (NULL == (device->ib_dev_context = ibv_open_device(device->ib_dev))) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error obtaining device context for %s errno says %d: %s", ibv_get_device_name(device->ib_dev), errno, strerror(errno)) ); return OSHMEM_ERR_RESOURCE_BUSY; } /* Obtain device attributes */ if (ibv_query_device(device->ib_dev_context, &device->ib_dev_attr)) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error obtaining device attributes for %s errno says %d: %s", ibv_get_device_name(device->ib_dev), errno, strerror(errno)) ); return OSHMEM_ERR_RESOURCE_BUSY; } /* Allocate the protection domain for the device */ device->ib_pd = ibv_alloc_pd(device->ib_dev_context); if (NULL == device->ib_pd) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error allocating protection domain for %s errno says %d: %s", ibv_get_device_name(device->ib_dev), errno, strerror(errno)) ); return OSHMEM_ERR_RESOURCE_BUSY; } /* Allocate memory */ if (!rc) { void *addr = NULL; struct ibv_mr *ib_mr = NULL; uint64_t access_flag = IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ; uint64_t exp_access_flag = 0; OBJ_CONSTRUCT(&device->ib_mr_array, opal_value_array_t); opal_value_array_init(&device->ib_mr_array, sizeof(struct ibv_mr *)); #if (MPAGE_ENABLE > 0) exp_access_flag = IBV_EXP_ACCESS_ALLOCATE_MR | IBV_EXP_ACCESS_SHARED_MR_USER_READ | IBV_EXP_ACCESS_SHARED_MR_USER_WRITE; #endif /* MPAGE_ENABLE */ struct ibv_exp_reg_mr_in in = {device->ib_pd, addr, size, access_flag|exp_access_flag, 0}; #if MPAGE_HAVE_IBV_EXP_REG_MR_CREATE_FLAGS if (0 == mca_sshmem_verbs_component.has_shared_mr) { in.addr = (void *)mca_sshmem_base_start_address; in.comp_mask = IBV_EXP_REG_MR_CREATE_FLAGS; in.create_flags = IBV_EXP_REG_MR_CREATE_CONTIG; in.exp_access = access_flag; } #endif ib_mr = ibv_exp_reg_mr(&in); if (NULL == ib_mr) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error to ibv_exp_reg_mr() %llu bytes errno says %d: %s", (unsigned long long)size, errno, strerror(errno)) ); rc = OSHMEM_ERR_OUT_OF_RESOURCE; } else { device->ib_mr_shared = ib_mr; opal_value_array_append_item(&device->ib_mr_array, &ib_mr); } #if (MPAGE_ENABLE > 0) if (!rc && mca_sshmem_verbs_component.has_shared_mr) { void *addr = NULL; access_flag = IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_READ| IBV_EXP_ACCESS_NO_RDMA; addr = (void *)mca_sshmem_base_start_address; struct ibv_exp_reg_shared_mr_in in; mca_sshmem_verbs_fill_shared_mr(&in, device->ib_pd, device->ib_mr_shared->handle, addr, access_flag); ib_mr = ibv_exp_reg_shared_mr(&in); if (NULL == ib_mr) { OPAL_OUTPUT_VERBOSE( (5, oshmem_sshmem_base_framework.framework_output, "error to ibv_reg_shared_mr() %llu bytes errno says %d: %s has_shared_mr: %d", (unsigned long long)size, errno, strerror(errno), mca_sshmem_verbs_component.has_shared_mr ) ); rc = OSHMEM_ERR_OUT_OF_RESOURCE; } else { opal_value_array_append_item(&device->ib_mr_array, &ib_mr); } } #endif /* MPAGE_ENABLE */ if (!rc) { OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "ibv device %s shared_mr: %d", ibv_get_device_name(device->ib_dev), mca_sshmem_verbs_component.has_shared_mr) ); if (mca_sshmem_verbs_component.has_shared_mr) { assert(size == device->ib_mr_shared->length); ds_buf->type = MAP_SEGMENT_ALLOC_IBV; ds_buf->seg_id = device->ib_mr_shared->handle; } else { ds_buf->type = MAP_SEGMENT_ALLOC_IBV_NOSHMR; ds_buf->seg_id = MAP_SEGMENT_SHM_INVALID; } ds_buf->super.va_base = ib_mr->addr; ds_buf->seg_size = size; ds_buf->super.va_end = (void*)((uintptr_t)ds_buf->super.va_base + ds_buf->seg_size); } } OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: create %s " "(id: %d, addr: %p size: %lu, name: %s)\n", mca_sshmem_verbs_component.super.base_version.mca_type_name, mca_sshmem_verbs_component.super.base_version.mca_component_name, (rc ? "failure" : "successful"), ds_buf->seg_id, ds_buf->super.va_base, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(opal_shmem_ds_t *ds_buf, const char *file_name, size_t size) { int rc = OPAL_SUCCESS; pid_t my_pid = getpid(); /* the real size of the shared memory segment. this includes enough space * to store our segment header. */ size_t real_size = size + sizeof(opal_shmem_seg_hdr_t); opal_shmem_seg_hdr_t *seg_hdrp = MAP_FAILED; /* init the contents of opal_shmem_ds_t */ shmem_ds_reset(ds_buf); /* for posix shared memory we don't have to worry about the backing store * being located on a network file system... so no check is needed here. */ /* calling shmem_posix_shm_open searches for an available posix shared * memory object name and upon successful completion populates the name * buffer */ if (-1 == (ds_buf->seg_id = shmem_posix_shm_open( ds_buf->seg_name, OPAL_SHMEM_POSIX_FILE_LEN_MAX - 1))) { /* snaps! something happened in posix_shm_open. don't report anything * here because posix_shm_open will display all the necessary info. */ rc = OPAL_ERROR; goto out; } /* size backing file - note the use of real_size here */ else if (0 != ftruncate(ds_buf->seg_id, real_size)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-posix.txt", "sys call fail", 1, hn, "ftruncate(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } else if (MAP_FAILED == (seg_hdrp = (opal_shmem_seg_hdr_t*)mmap(NULL, real_size, PROT_READ | PROT_WRITE, MAP_SHARED, ds_buf->seg_id, 0))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-posix.txt", "sys call fail", 1, hn, "mmap(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* all is well */ else { /* -- initialize the shared memory segment -- */ opal_atomic_rmb(); /* init segment lock */ opal_atomic_init(&seg_hdrp->lock, OPAL_ATOMIC_UNLOCKED); /* i was the creator of this segment, so note that fact */ seg_hdrp->cpid = my_pid; opal_atomic_wmb(); /* -- initialize the contents of opal_shmem_ds_t -- */ ds_buf->seg_cpid = my_pid; ds_buf->seg_size = real_size; ds_buf->seg_base_addr = (unsigned char *)seg_hdrp; /* notice that we are not setting ds_buf->name here. at this point, * posix_shm_open was successful, so the contents of ds_buf->name are * already set for us :-) */ /* set "valid" bit because setment creation was successful */ OPAL_SHMEM_DS_SET_VALID(ds_buf); OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: create successful " "(id: %d, size: %lu, name: %s)\n", mca_shmem_posix_component.super.base_version.mca_type_name, mca_shmem_posix_component.super.base_version.mca_component_name, ds_buf->seg_id, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); } out: /* in this component, the id is the file descriptor returned by open. this * check is here to see if it is safe to call close on the file descriptor. * that is, we are making sure that our call to open was successful and * we are not not in an error path. */ if (-1 != ds_buf->seg_id) { if (0 != close(ds_buf->seg_id)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "close(2)", "", strerror(err), err); rc = OPAL_ERROR; } } /* an error occured, so invalidate the shmem object and release any * allocated resources. */ if (OPAL_SUCCESS != rc) { /* posix_shm_open was successful, but something else wasn't. * note: if the id is not equal to -1 and we are here, name will be * valid. that is, we can safely call shm_unlink with ds_buf->name. */ if (-1 != ds_buf->seg_id) { shm_unlink(ds_buf->seg_name); } if (MAP_FAILED != seg_hdrp) { munmap((void*)seg_hdrp, real_size); } /* always invalidate in this error path */ shmem_ds_reset(ds_buf); } return rc; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(opal_shmem_ds_t *ds_buf, const char *file_name, size_t size) { int rc = OPAL_SUCCESS; pid_t my_pid = getpid(); char *temp1 = NULL, *temp2 = NULL; bool space_available = false; uint64_t amount_space_avail = 0; /* the real size of the shared memory segment. this includes enough space * to store our segment header. */ size_t real_size = size + sizeof(opal_shmem_seg_hdr_t); opal_shmem_seg_hdr_t *seg_hdrp = NULL; HANDLE hMapObject = INVALID_HANDLE_VALUE; LPVOID lpvMem = NULL; /* init the contents of opal_shmem_ds_t */ shmem_ds_reset(ds_buf); /* On Windows the shared file will be created by the OS directly on the * system ressources. Therefore, no file get involved in the operation. * However, a unique key should be used as name for the shared memory object * in order to allow all processes to access the same unique shared memory * region. The key will be obtained from the original file_name by replacing * all path separator occurences by '/' (as '\' is not allowed on the object * name). */ temp1 = strdup(file_name); if (NULL == temp1) { return OPAL_ERR_OUT_OF_RESOURCE; } temp2 = temp1; while (NULL != (temp2 = strchr(temp2, OPAL_PATH_SEP[0])) ) { *temp2 = '/'; } /* let's make sure we have enough space for the backing file */ if (OPAL_SUCCESS != (rc = enough_space(temp1, real_size, &amount_space_avail, &space_available))) { opal_output(0, "shmem: windows: an error occurred while determining " "whether or not %s could be created.", temp1); /* rc is set */ free(temp1); goto out; } if (!space_available) { char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; rc = OPAL_ERR_OUT_OF_RESOURCE; opal_show_help("help-opal-shmem-windows.txt", "target full", 1, temp1, hn, (unsigned long)real_size, (unsigned long long)amount_space_avail); free(temp1); goto out; } /* enough space is available, so create the segment */ /* use paging file */ hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, /* no security attributes */ NULL, /* read/write access */ PAGE_READWRITE, /* size: high 32-bits */ 0, /* size: low 32-bits */ (DWORD)real_size, /* name of map object */ temp1); if (NULL == hMapObject) { rc = OPAL_ERROR; goto out; } /* Get a pointer to the file-mapped shared memory. */ lpvMem = MapViewOfFile(hMapObject, /* object to map view of */ FILE_MAP_WRITE, /* read/write access */ 0, /* high offset: map from */ 0, /* low offset: beginning */ 0); /* default: map entire file */ if (NULL == lpvMem) { rc = OPAL_ERROR; goto out; } seg_hdrp = (opal_shmem_seg_hdr_t *)lpvMem; /* all is well */ /* -- initialize the shared memory segment -- */ opal_atomic_rmb(); /* init segment lock */ opal_atomic_init(&seg_hdrp->lock, OPAL_ATOMIC_UNLOCKED); /* i was the creator of this segment, so note that fact */ seg_hdrp->cpid = my_pid; opal_atomic_wmb(); /* -- initialize the contents of opal_shmem_ds_t -- */ ds_buf->seg_cpid = my_pid; ds_buf->seg_size = real_size; ds_buf->seg_base_addr = (unsigned char *)seg_hdrp; /* update path change in ds_buf */ memcpy(ds_buf->seg_name, temp1, OPAL_PATH_MAX); /* relase the temporary file name */ free(temp1); /* set "valid" bit because setment creation was successful */ OPAL_SHMEM_DS_SET_VALID(ds_buf); OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_output, "%s: %s: create successful " "(id: %d, size: %"PRIsize_t", name: %s)\n", mca_shmem_windows_component.super.base_version.mca_type_name, mca_shmem_windows_component.super.base_version.mca_component_name, ds_buf->seg_id, ds_buf->seg_size, ds_buf->seg_name) ); out: /* an error occured, so invalidate the shmem object and munmap if needed */ if (OPAL_SUCCESS != rc) { if (NULL != seg_hdrp) { UnmapViewOfFile((LPVOID)seg_hdrp); } shmem_ds_reset(ds_buf); } return rc; }
static int segment_create(map_segment_t *ds_buf, const char *file_name, size_t size) { int rc = OSHMEM_SUCCESS; void *addr = NULL; assert(ds_buf); /* init the contents of map_segment_t */ shmem_ds_reset(ds_buf); addr = mmap((void *)mca_sshmem_base_start_address, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | #if defined(MAP_ANONYMOUS) MAP_ANONYMOUS | #endif MAP_FIXED, -1, 0); if (MAP_FAILED == addr) { opal_show_help("help-oshmem-sshmem.txt", "create segment failure", true, "mmap", orte_process_info.nodename, (unsigned long long) size, strerror(errno), errno); opal_show_help("help-oshmem-sshmem-mmap.txt", "mmap:create segment failure", true); return OSHMEM_ERR_OUT_OF_RESOURCE; } ds_buf->type = MAP_SEGMENT_ALLOC_MMAP; if (mca_sshmem_mmap_component.is_anonymous) { /* * Segment attach is not called for anonymous mmap */ ds_buf->seg_id = MAP_SEGMENT_SHM_INVALID; } else { /* * Warning: implied that input file name has a fixed format * and pe which is stored as segment identifier is used in file name * generation during segment attachment */ ds_buf->seg_id = oshmem_my_proc_id(); } ds_buf->super.va_base = addr; ds_buf->seg_size = size; ds_buf->super.va_end = (void*)((uintptr_t)ds_buf->super.va_base + ds_buf->seg_size); OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: create %s " "(id: %d, addr: %p size: %lu)\n", mca_sshmem_mmap_component.super.base_version.mca_type_name, mca_sshmem_mmap_component.super.base_version.mca_component_name, (rc ? "failure" : "successful"), ds_buf->seg_id, ds_buf->super.va_base, (unsigned long)ds_buf->seg_size) ); return rc; }
static int segment_create(map_segment_t *ds_buf, const char *file_name, size_t size) { int rc = OSHMEM_SUCCESS; void *addr = NULL; assert(ds_buf); /* init the contents of map_segment_t */ shmem_ds_reset(ds_buf); if (mca_sshmem_mmap_component.is_anonymous) { addr = mmap((void *)(mca_sshmem_mmap_component.is_start_addr_fixed ? mca_sshmem_base_start_address : NULL), size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | (mca_sshmem_mmap_component.is_start_addr_fixed ? MAP_FIXED : 0), -1, 0); } else { memcpy(ds_buf->seg_name, file_name, OPAL_PATH_MAX * sizeof(char)); int fd; if (-1 == (fd = open(ds_buf->seg_name, O_CREAT | O_RDWR, 0600))) { opal_show_help("help-oshmem-sshmem-mmap.txt", "mmap:file open failure", true, ds_buf->seg_name, strerror(errno)); return OSHMEM_ERROR; } if (0 != ftruncate(fd, size)) { opal_show_help("help-oshmem-sshmem-mmap.txt", "mmap:file truncate failure", true, ds_buf->seg_name, (unsigned long long) size, strerror(errno)); return OSHMEM_ERROR; } addr = mmap((void *)(mca_sshmem_mmap_component.is_start_addr_fixed ? mca_sshmem_base_start_address : NULL), size, PROT_READ | PROT_WRITE, MAP_SHARED | (mca_sshmem_mmap_component.is_start_addr_fixed ? MAP_FIXED : 0), fd, 0); if (0 != close(fd)) { OPAL_OUTPUT( (oshmem_sshmem_base_framework.framework_output, "file close failed: %s", strerror(errno)) ); } } if (MAP_FAILED == addr) { opal_show_help("help-oshmem-sshmem.txt", "create segment failure", true, "mmap", orte_process_info.nodename, (unsigned long long) size, strerror(errno), errno); opal_show_help("help-oshmem-sshmem-mmap.txt", "mmap:create segment failure", true); return OSHMEM_ERR_OUT_OF_RESOURCE; } ds_buf->type = MAP_SEGMENT_ALLOC_MMAP; if (mca_sshmem_mmap_component.is_anonymous) { /* * Segment attach is not called for anonymous mmap */ ds_buf->seg_id = MAP_SEGMENT_SHM_INVALID; } else { /* * Warning: implied that input file name has a fixed format * and pe which is stored as segment identifier is used in file name * generation during segment attachment */ ds_buf->seg_id = oshmem_my_proc_id(); } ds_buf->seg_base_addr = addr; ds_buf->seg_size = size; ds_buf->end = (void*)((uintptr_t)ds_buf->seg_base_addr + ds_buf->seg_size); OPAL_OUTPUT_VERBOSE( (70, oshmem_sshmem_base_framework.framework_output, "%s: %s: create %s " "(id: %d, addr: %p size: %lu, name: %s)\n", mca_sshmem_mmap_component.super.base_version.mca_type_name, mca_sshmem_mmap_component.super.base_version.mca_component_name, (rc ? "failure" : "successful"), ds_buf->seg_id, ds_buf->seg_base_addr, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); return rc; }