Ejemplo n.º 1
0
static int
test_misc(void)
{
	char memdump[] = "memdump_test";
	if (rte_bsf32(129))
		FAIL("rte_bsf32");

	rte_memdump(stdout, "test", memdump, sizeof(memdump));
	rte_hexdump(stdout, "test", memdump, sizeof(memdump));

	rte_pause();

	return 0;
}
static struct _mempool_gntalloc_info
_create_mempool(const char *name, unsigned elt_num, unsigned elt_size,
		   unsigned cache_size, unsigned private_data_size,
		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
		   int socket_id, unsigned flags)
{
	struct _mempool_gntalloc_info mgi;
	struct rte_mempool *mp = NULL;
	struct rte_mempool_objsz  objsz;
	uint32_t pg_num, rpg_num, pg_shift, pg_sz;
	char *va, *orig_va, *uv; /* uv: from which, the pages could be freed */
	ssize_t sz, usz; /* usz: unused size */
	/*
	 * for each page allocated through xen_gntalloc driver,
	 * gref_arr:stores grant references,
	 * pa_arr: stores physical address,
	 * gnt_arr: stores all meta dat
	 */
	uint32_t *gref_arr = NULL;
	phys_addr_t *pa_arr = NULL;
	struct _gntarr *gnt_arr = NULL;
	/* start index of the grant referances, used for dealloc*/
	uint64_t start_index;
	uint32_t i, j;
	int rv = 0;
	struct ioctl_gntalloc_dealloc_gref arg;

	mgi.mp = NULL;
	va = orig_va = uv = NULL;
	pg_num = rpg_num = 0;
	sz = 0;

	pg_sz = getpagesize();
	if (rte_is_power_of_2(pg_sz) == 0) {
		goto out;
	}
	pg_shift = rte_bsf32(pg_sz);

	rte_mempool_calc_obj_size(elt_size, flags, &objsz);
	sz = rte_mempool_xmem_size(elt_num, objsz.total_size, pg_shift);
	pg_num = sz >> pg_shift;

	pa_arr = calloc(pg_num, sizeof(pa_arr[0]));
	gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
	gnt_arr  = calloc(pg_num, sizeof(gnt_arr[0]));
	if ((gnt_arr == NULL) || (gref_arr == NULL) || (pa_arr == NULL))
		goto out;

	/* grant index is continuous in ascending order */
	orig_va = gntalloc(sz, gref_arr, &start_index);
	if (orig_va == NULL)
		goto out;

	get_phys_map(orig_va, pa_arr, pg_num, pg_sz);
	for (i = 0; i < pg_num; i++) {
		gnt_arr[i].index = start_index + i * pg_sz;
		gnt_arr[i].gref = gref_arr[i];
		gnt_arr[i].pa = pa_arr[i];
		gnt_arr[i].va  = RTE_PTR_ADD(orig_va, i * pg_sz);
	}
	qsort(gnt_arr, pg_num, sizeof(struct _gntarr), compare);

	va = get_xen_virtual(sz, pg_sz);
	if (va == NULL) {
		goto out;
	}

	/*
	 * map one by one, as index isn't continuous now.
	 * pg_num VMAs, doesn't linux has a limitation on this?
	 */
	for (i = 0; i < pg_num; i++) {
	/* update gref_arr and pa_arr after sort */
		gref_arr[i] = gnt_arr[i].gref;
		pa_arr[i]   = gnt_arr[i].pa;
		gnt_arr[i].va = mmap(va + i * pg_sz, pg_sz, PROT_READ | PROT_WRITE,
			MAP_SHARED | MAP_FIXED, gntalloc_fd, gnt_arr[i].index);
		if ((gnt_arr[i].va == MAP_FAILED) || (gnt_arr[i].va != (va + i * pg_sz))) {
			RTE_LOG(ERR, PMD, "failed to map %d pages\n", i);
			goto mmap_failed;
		}
	}

	/*
	 * Check that allocated size is big enough to hold elt_num
	 * objects and a calcualte how many bytes are actually required.
	 */
	usz = rte_mempool_xmem_usage(va, elt_num, objsz.total_size, pa_arr, pg_num, pg_shift);
	if (usz < 0) {
		mp = NULL;
		i = pg_num;
		goto mmap_failed;
	} else {
		/* unmap unused pages if any */
		uv = RTE_PTR_ADD(va, usz);
		if ((usz = va + sz - uv) > 0) {

			RTE_LOG(ERR, PMD,
				"%s(%s): unmap unused %zu of %zu "
				"mmaped bytes @%p orig:%p\n",
				__func__, name, usz, sz, uv, va);
			munmap(uv, usz);
			i = (sz - usz) / pg_sz;
			for (; i < pg_num; i++) {
				arg.count = 1;
				arg.index = gnt_arr[i].index;
				rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg);
				if (rv) {
					/* shouldn't fail here */
					RTE_LOG(ERR, PMD, "va=%p pa=%"PRIu64"x index=%"PRIu64" %s\n",
						gnt_arr[i].va,
						gnt_arr[i].pa,
						arg.index, strerror(errno));
					rte_panic("gntdealloc failed when freeing pages\n");
				}
			}

			rpg_num = (sz - usz) >> pg_shift;
		} else
Ejemplo n.º 3
0
int
grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size)
{
	uint64_t start_index;
	int pg_size;
	uint32_t pg_shift;
	void *ptr = NULL;
	uint32_t count, entries_per_pg;
	uint32_t i, j = 0, k = 0;
	uint32_t *gref_tmp;
	int first = 1;
	char tmp_str[PATH_MAX] = {0};
	int rv = -1;

	pg_size = getpagesize();
	if (rte_is_power_of_2(pg_size) == 0) {
		return -1;
	}
	pg_shift = rte_bsf32(pg_size);
	if (pg_size % sizeof(struct grant_node_item)) {
		RTE_LOG(ERR, PMD, "pg_size isn't a multiple of grant node item\n");
		return -1;
	}

	entries_per_pg = pg_size / sizeof(struct grant_node_item);
	count  = (pg_num +  entries_per_pg - 1 ) / entries_per_pg;
	gref_tmp = malloc(count * sizeof(uint32_t));
	if (gref_tmp == NULL)
		return -1;
	ptr = gntalloc(pg_size * count, gref_tmp, &start_index);
	if (ptr == NULL) {
		RTE_LOG(ERR, PMD, "%s: gntalloc error of %d pages\n", __func__, count);
		free(gref_tmp);
		return -1;
	}

	while (j < pg_num) {
		if (first) {
			rv = snprintf(val_str, str_size, "%u", gref_tmp[k]);
			first = 0;
		} else {
			snprintf(tmp_str, PATH_MAX, "%s", val_str);
			rv = snprintf(val_str, str_size, "%s,%u", tmp_str, gref_tmp[k]);
		}
		k++;
		if (rv == -1)
			break;

		for (i = 0; i < entries_per_pg && j < pg_num ; i++) {
			((struct grant_node_item *)ptr)->gref = gref_arr[j];
			((struct grant_node_item *)ptr)->pfn =  pa_arr[j] >> pg_shift;
			ptr = RTE_PTR_ADD(ptr, sizeof(struct grant_node_item));
			j++;
		}
	}
	if (rv == -1) {
		gntfree(ptr, pg_size * count, start_index);
	} else
		rv = 0;
	free(gref_tmp);
	return rv;
}