Test(gnix_hashtable_advanced, insert_8K_lookup_128K_random) { int ret, i, index; gnix_test_element_t *test_elements; gnix_test_element_t *found = NULL, *to_find = NULL; gnix_test_element_t *item; gnix_bitmap_t allocated = {0}; int test_size = 8 * 1024; int bitmap_size = 64 * test_size; int lookups = 128 * 1024; test_elements = calloc(test_size, sizeof(gnix_test_element_t)); cr_assert(test_elements != NULL); ret = _gnix_alloc_bitmap(&allocated, bitmap_size); cr_assert(ret == 0); srand(time(NULL)); for (i = 0; i < test_size; ++i) { do { index = rand() % bitmap_size; } while (_gnix_test_and_set_bit(&allocated, index)); item = &test_elements[i]; item->key = index; item->val = rand() % lookups; item->magic = __GNIX_MAGIC_VALUE; } for (i = 0; i < test_size; ++i) { item = &test_elements[i]; ret = _gnix_ht_insert(test_ht, item->key, item); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == (i + 1)); } cr_assert(atomic_get(&test_ht->ht_elements) == test_size); for (i = 0; i < lookups; ++i) { to_find = &test_elements[rand() % test_size]; found = _gnix_ht_lookup(test_ht, to_find->key); cr_assert(found != NULL); cr_assert(found == to_find); cr_assert(found->magic == __GNIX_MAGIC_VALUE); } ret = _gnix_free_bitmap(&allocated); cr_expect(ret == 0); free(test_elements); }
int _gnix_buddy_allocator_create(void *base, uint32_t len, uint32_t max, gnix_buddy_alloc_handle_t **alloc_handle) { char err_buf[256] = {0}, *error = NULL; int fi_errno; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); /* Ensure parameters are valid */ if (unlikely(!base || !len || !max || max > len || !alloc_handle || IS_NOT_POW_TWO(max) || (len % max) || !(len / MIN_BLOCK_SIZE * 2))) { GNIX_WARN(FI_LOG_EP_CTRL, "Invalid parameter to _gnix_buddy_allocator_create." "\n"); return -FI_EINVAL; } *alloc_handle = calloc(1, sizeof(gnix_buddy_alloc_handle_t)); if (unlikely(!alloc_handle)) { error = strerror_r(errno, err_buf, sizeof(err_buf)); GNIX_WARN(FI_LOG_EP_CTRL, "Could not create buddy allocator handle.\n", error); return -FI_ENOMEM; } fastlock_init(&alloc_handle[0]->lock); alloc_handle[0]->base = base; alloc_handle[0]->len = len; alloc_handle[0]->max = max; if (__gnix_buddy_create_lists(alloc_handle[0])) { free(*alloc_handle); return -FI_ENOMEM; } /* The bitmap needs len / MIN_BLOCK_SIZE * 2 bits to flag every possible * block of size: min, min * 2, min * 4, ... , max that fits in the * base. block. The maximum number of bits used would be if max = len. */ if ((fi_errno = _gnix_alloc_bitmap(&alloc_handle[0]->bitmap, len / MIN_BLOCK_SIZE * 2))) { free(&alloc_handle[0]->lists); free(*alloc_handle); } return fi_errno; }
/** * Create a slab from a handle and append to the slab list. * * @param[in] handle Handle to the allocator being used. * * @return FI_SUCCESS On successful slab creation. * * @return -FI_ENOMEM if failure to allocate memory for slab or bitmap. * @return [Unspec] if failure in alloc_bitmap. Will return error code from * alloc_bitmap. * @return [Unspec] if failure in GNI_MemRegister. Converts gni_return_t * status code to FI_ERRNO value. */ static int __create_slab(struct gnix_mbox_alloc_handle *handle) { struct gnix_slab *slab; gni_return_t status; char error_buf[256]; char *error; size_t total_size; int ret; int vmdh_index = -1; int flags = GNI_MEM_READWRITE; struct gnix_auth_key *info; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); slab = calloc(1, sizeof(*slab)); if (!slab) { error = strerror_r(errno, error_buf, sizeof(error_buf)); GNIX_WARN(FI_LOG_EP_CTRL, "Error allocating slab: %s\n", error); ret = -FI_ENOMEM; goto err_slab_calloc; } total_size = handle->page_size * __page_count(handle); GNIX_DEBUG(FI_LOG_EP_CTRL, "total_size requested for mmap: %zu.\n", total_size); slab->used = calloc(1, sizeof(*(slab->used))); if (!slab->used) { error = strerror_r(errno, error_buf, sizeof(error_buf)); GNIX_WARN(FI_LOG_EP_CTRL, "Error allocating bitmap: %s\n", error); ret = -FI_ENOMEM; goto err_bitmap_calloc; } slab->base = mmap(0, total_size, (PROT_READ | PROT_WRITE), MAP_SHARED, handle->fd, handle->last_offset); if (slab->base == MAP_FAILED) { error = strerror_r(errno, error_buf, sizeof(error_buf)); GNIX_WARN(FI_LOG_EP_CTRL, "%s\n", error); ret = -FI_ENOMEM; goto err_mmap; } ret = _gnix_alloc_bitmap(slab->used, __mbox_count(handle), NULL); if (ret) { GNIX_WARN(FI_LOG_EP_CTRL, "Error allocating bitmap.\n"); goto err_alloc_bitmap; } COND_ACQUIRE(handle->nic_handle->requires_lock, &handle->nic_handle->lock); if (handle->nic_handle->using_vmdh) { info = _gnix_auth_key_lookup(GNIX_PROV_DEFAULT_AUTH_KEY, GNIX_PROV_DEFAULT_AUTH_KEYLEN); assert(info); if (!handle->nic_handle->mdd_resources_set) { /* check to see if the ptag registration limit was set * yet or not -- becomes read-only after success */ _gnix_auth_key_enable(info); status = GNI_SetMddResources( handle->nic_handle->gni_nic_hndl, (info->attr.prov_key_limit + info->attr.user_key_limit)); assert(status == GNI_RC_SUCCESS); handle->nic_handle->mdd_resources_set = 1; } vmdh_index = _gnix_get_next_reserved_key(info); if (vmdh_index <= 0) { GNIX_FATAL(FI_LOG_DOMAIN, "failed to get reserved key for mbox " "registration, rc=%d\n", vmdh_index); } flags |= GNI_MEM_USE_VMDH; } status = GNI_MemRegister(handle->nic_handle->gni_nic_hndl, (uint64_t) slab->base, total_size, handle->cq_handle, flags, vmdh_index, &slab->memory_handle); COND_RELEASE(handle->nic_handle->requires_lock, &handle->nic_handle->lock); if (status != GNI_RC_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "GNI_MemRegister failed: %s\n", gni_err_str[status]); ret = gnixu_to_fi_errno(status); goto err_memregister; } slab->allocator = handle; gnix_slist_insert_tail(&slab->list_entry, &handle->slab_list); handle->last_offset += total_size; return ret; err_memregister: _gnix_free_bitmap(slab->used); err_alloc_bitmap: munmap(slab->base, total_size); err_mmap: free(slab->used); err_bitmap_calloc: free(slab); err_slab_calloc: return ret; }
int _gnix_vc_alloc(struct gnix_fid_ep *ep_priv, struct gnix_av_addr_entry *entry, struct gnix_vc **vc) { int ret = FI_SUCCESS; int remote_id; struct gnix_vc *vc_ptr = NULL; struct gnix_cm_nic *cm_nic = NULL; struct gnix_nic *nic = NULL; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); nic = ep_priv->nic; if (nic == NULL) return -FI_EINVAL; cm_nic = ep_priv->cm_nic; if (cm_nic == NULL) return -FI_EINVAL; vc_ptr = calloc(1, sizeof(*vc_ptr)); if (!vc_ptr) return -FI_ENOMEM; vc_ptr->conn_state = GNIX_VC_CONN_NONE; if (entry) { memcpy(&vc_ptr->peer_addr, &entry->gnix_addr, sizeof(struct gnix_address)); vc_ptr->peer_cm_nic_addr.device_addr = entry->gnix_addr.device_addr; vc_ptr->peer_cm_nic_addr.cdm_id = entry->cm_nic_cdm_id; } else { vc_ptr->peer_addr.device_addr = -1; vc_ptr->peer_addr.cdm_id = -1; vc_ptr->peer_cm_nic_addr.device_addr = -1; vc_ptr->peer_cm_nic_addr.cdm_id = -1; } vc_ptr->ep = ep_priv; slist_init(&vc_ptr->work_queue); fastlock_init(&vc_ptr->work_queue_lock); slist_init(&vc_ptr->tx_queue); fastlock_init(&vc_ptr->tx_queue_lock); dlist_init(&vc_ptr->rx_list); dlist_init(&vc_ptr->work_list); dlist_init(&vc_ptr->tx_list); vc_ptr->peer_fi_addr = FI_ADDR_NOTAVAIL; atomic_initialize(&vc_ptr->outstanding_tx_reqs, 0); ret = _gnix_alloc_bitmap(&vc_ptr->flags, 1); assert(!ret); /* * we need an id for the vc to allow for quick lookup * based on GNI_CQ_GET_INST_ID */ ret = _gnix_nic_get_rem_id(nic, &remote_id, vc_ptr); if (ret != FI_SUCCESS) goto err; vc_ptr->vc_id = remote_id; *vc = vc_ptr; return ret; err: if (vc_ptr) free(vc_ptr); return ret; }