示例#1
0
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;
}
示例#4
0
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;
}