Пример #1
0
static int
parse_ringnuma_config(const char *q_arg)
{
	char s[256];
	const char *p, *p0 = q_arg;
	char *end;
	uint8_t i,port_id,ring_flag,socket_id;
	unsigned size;
	enum fieldnames {
		FLD_PORT = 0,
		FLD_FLAG,
		FLD_SOCKET,
		_NUM_FLD
	};
	unsigned long int_fld[_NUM_FLD];
	char *str_fld[_NUM_FLD];	
	#define RX_RING_ONLY 0x1
	#define TX_RING_ONLY 0x2
	#define RXTX_RING    0x3

	/* reset from value set at definition */
	while ((p = strchr(p0,'(')) != NULL) {
		++p;
		if((p0 = strchr(p,')')) == NULL)
			return -1;

		size = p0 - p;
		if(size >= sizeof(s))
			return -1;

		rte_snprintf(s, sizeof(s), "%.*s", size, p);
		if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
			return -1;
		for (i = 0; i < _NUM_FLD; i++) {
			errno = 0;
			int_fld[i] = strtoul(str_fld[i], &end, 0);
			if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
				return -1;
		}
		port_id = (uint8_t)int_fld[FLD_PORT];
		if (port_id >= nb_ports) {
			printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
			return -1;
		}
		socket_id = (uint8_t)int_fld[FLD_SOCKET];
		if (socket_id >= MAX_SOCKET) {
			printf("Invalid socket id, range is [0, %d]\n",
				MAX_SOCKET - 1);
			return -1;
		}
		ring_flag = (uint8_t)int_fld[FLD_FLAG];
		if ((ring_flag < RX_RING_ONLY) || (ring_flag > RXTX_RING)) {
			printf("Invalid ring-flag=%d config for port =%d\n",
				ring_flag,port_id);
			return -1;
		}

		switch (ring_flag & RXTX_RING) {
		case RX_RING_ONLY:
			rxring_numa[port_id] = socket_id;
			break;
		case TX_RING_ONLY:
			txring_numa[port_id] = socket_id;
			break;
		case RXTX_RING:
			rxring_numa[port_id] = socket_id;
			txring_numa[port_id] = socket_id;
			break;
		default:
			printf("Invalid ring-flag=%d config for port=%d\n",
				ring_flag,port_id);
			break;
		}
	}	
	
	return 0;
}
Пример #2
0
static int
parse_queue_stats_mapping_config(const char *q_arg, int is_rx)
{
	char s[256];
	const char *p, *p0 = q_arg;
	char *end;
	enum fieldnames {
		FLD_PORT = 0,
		FLD_QUEUE,
		FLD_STATS_COUNTER,
		_NUM_FLD
	};
	unsigned long int_fld[_NUM_FLD];
	char *str_fld[_NUM_FLD];
	int i;
	unsigned size;

	/* reset from value set at definition */
	is_rx ? (nb_rx_queue_stats_mappings = 0) : (nb_tx_queue_stats_mappings = 0);

	while ((p = strchr(p0,'(')) != NULL) {
		++p;
		if((p0 = strchr(p,')')) == NULL)
			return -1;

		size = p0 - p;
		if(size >= sizeof(s))
			return -1;

		rte_snprintf(s, sizeof(s), "%.*s", size, p);
		if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
			return -1;
		for (i = 0; i < _NUM_FLD; i++){
			errno = 0;
			int_fld[i] = strtoul(str_fld[i], &end, 0);
			if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
				return -1;
		}
		/* Check mapping field is in correct range (0..RTE_ETHDEV_QUEUE_STAT_CNTRS-1) */
		if (int_fld[FLD_STATS_COUNTER] >= RTE_ETHDEV_QUEUE_STAT_CNTRS) {
			printf("Stats counter not in the correct range 0..%d\n",
					RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
			return -1;
		}

		if (is_rx ? (nb_rx_queue_stats_mappings >= MAX_RX_QUEUE_STATS_MAPPINGS) :
		    (nb_tx_queue_stats_mappings >= MAX_TX_QUEUE_STATS_MAPPINGS)) {
			printf("exceeded max number of %s queue statistics mappings: %hu\n",
			       is_rx ? "RX" : "TX",
			       is_rx ? nb_rx_queue_stats_mappings : nb_tx_queue_stats_mappings);
			return -1;
		}
		if (!is_rx) {
			tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].port_id =
				(uint8_t)int_fld[FLD_PORT];
			tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].queue_id =
				(uint8_t)int_fld[FLD_QUEUE];
			tx_queue_stats_mappings_array[nb_tx_queue_stats_mappings].stats_counter_id =
				(uint8_t)int_fld[FLD_STATS_COUNTER];
			++nb_tx_queue_stats_mappings;
		}
		else {
			rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].port_id =
				(uint8_t)int_fld[FLD_PORT];
			rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].queue_id =
				(uint8_t)int_fld[FLD_QUEUE];
			rx_queue_stats_mappings_array[nb_rx_queue_stats_mappings].stats_counter_id =
				(uint8_t)int_fld[FLD_STATS_COUNTER];
			++nb_rx_queue_stats_mappings;
		}

	}
/* Reassign the rx/tx_queue_stats_mappings pointer to point to this newly populated array rather */
/* than to the default array (that was set at its definition) */
	is_rx ? (rx_queue_stats_mappings = rx_queue_stats_mappings_array) :
		(tx_queue_stats_mappings = tx_queue_stats_mappings_array);
	return 0;
}
Пример #3
0
static int
test_rte_strsplit(void)
{
	int i;
	do {
		/* =======================================================
		 * split a mac address correct number of splits requested
		 * =======================================================*/
		char test_string[] = "54:65:76:87:98:90";
		char *splits[6];

		LOG("Source string: '%s', to split on ':'\n", test_string);
		if (rte_strsplit(test_string, sizeof(test_string),
				splits, 6, ':') != 6) {
			LOG("Error splitting mac address\n");
			return -1;
		}
		for (i = 0; i < 6; i++)
			LOG("Token %d = %s\n", i + 1, splits[i]);
	} while (0);


	do {
		/* =======================================================
		 * split on spaces smaller number of splits requested
		 * =======================================================*/
		char test_string[] = "54 65 76 87 98 90";
		char *splits[6];

		LOG("Source string: '%s', to split on ' '\n", test_string);
		if (rte_strsplit(test_string, sizeof(test_string),
				splits, 3, ' ') != 3) {
			LOG("Error splitting mac address for max 2 splits\n");
			return -1;
		}
		for (i = 0; i < 3; i++)
			LOG("Token %d = %s\n", i + 1, splits[i]);
	} while (0);

	do {
		/* =======================================================
		 * split on commas - more splits than commas requested
		 * =======================================================*/
		char test_string[] = "a,b,c,d";
		char *splits[6];

		LOG("Source string: '%s', to split on ','\n", test_string);
		if (rte_strsplit(test_string, sizeof(test_string),
				splits, 6, ',') != 4) {
			LOG("Error splitting %s on ','\n", test_string);
			return -1;
		}
		for (i = 0; i < 4; i++)
			LOG("Token %d = %s\n", i + 1, splits[i]);
	} while(0);

	do {
		/* =======================================================
		 * Try splitting on non-existent character.
		 * =======================================================*/
		char test_string[] = "a,b,c,d";
		char *splits[6];

		LOG("Source string: '%s', to split on ' '\n", test_string);
		if (rte_strsplit(test_string, sizeof(test_string),
				splits, 6, ' ') != 1) {
			LOG("Error splitting %s on ' '\n", test_string);
			return -1;
		}
		LOG("String not split\n");
	} while(0);

	do {
		/* =======================================================
		 * Invalid / edge case parameter checks
		 * =======================================================*/
		char test_string[] = "a,b,c,d";
		char *splits[6];

		if (rte_strsplit(NULL, 0, splits, 6, ',') >= 0
				|| errno != EINVAL){
			LOG("Error: rte_strsplit accepted NULL string parameter\n");
			return -1;
		}

		if (rte_strsplit(test_string, sizeof(test_string), NULL, 0, ',') >= 0
				|| errno != EINVAL){
			LOG("Error: rte_strsplit accepted NULL array parameter\n");
			return -1;
		}

		errno = 0;
		if (rte_strsplit(test_string, 0, splits, 6, ',') != 0 || errno != 0) {
			LOG("Error: rte_strsplit did not accept 0 length string\n");
			return -1;
		}

		if (rte_strsplit(test_string, sizeof(test_string), splits, 0, ',') != 0
				|| errno != 0) {
			LOG("Error: rte_strsplit did not accept 0 length array\n");
			return -1;
		}

		LOG("Parameter test cases passed\n");
	} while(0);

	LOG("%s - PASSED\n", __func__);
	return 0;
}
Пример #4
0
struct rte_cfgfile *
rte_cfgfile_load(const char *filename, int flags)
{
	int allocated_sections = CFG_ALLOC_SECTION_BATCH;
	int allocated_entries = 0;
	int curr_section = -1;
	int curr_entry = -1;
	char buffer[256];
	int lineno = 0;
	struct rte_cfgfile *cfg = NULL;

	FILE *f = fopen(filename, "r");
	if (f == NULL)
		return NULL;

	cfg = malloc(sizeof(*cfg) + sizeof(cfg->sections[0]) *
		allocated_sections);
	if (cfg == NULL)
		goto error2;

	memset(cfg->sections, 0, sizeof(cfg->sections[0]) * allocated_sections);

	while (fgets(buffer, sizeof(buffer), f) != NULL) {
		char *pos = NULL;
		size_t len = strnlen(buffer, sizeof(buffer));
		lineno++;
		if ((len >= sizeof(buffer) - 1) && (buffer[len-1] != '\n')) {
			printf("Error line %d - no \\n found on string. "
					"Check if line too long\n", lineno);
			goto error1;
		}
		pos = memchr(buffer, ';', sizeof(buffer));
		if (pos != NULL) {
			*pos = '\0';
			len = pos -  buffer;
		}

		len = _strip(buffer, len);
		if (buffer[0] != '[' && memchr(buffer, '=', len) == NULL)
			continue;

		if (buffer[0] == '[') {
			/* section heading line */
			char *end = memchr(buffer, ']', len);
			if (end == NULL) {
				printf("Error line %d - no terminating '['"
					"character found\n", lineno);
				goto error1;
			}
			*end = '\0';
			_strip(&buffer[1], end - &buffer[1]);

			/* close off old section and add start new one */
			if (curr_section >= 0)
				cfg->sections[curr_section]->num_entries =
					curr_entry + 1;
			curr_section++;

			/* resize overall struct if we don't have room for more
			sections */
			if (curr_section == allocated_sections) {
				allocated_sections += CFG_ALLOC_SECTION_BATCH;
				struct rte_cfgfile *n_cfg = realloc(cfg,
					sizeof(*cfg) + sizeof(cfg->sections[0])
					* allocated_sections);
				if (n_cfg == NULL) {
					printf("Error - no more memory\n");
					goto error1;
				}
				cfg = n_cfg;
			}

			/* allocate space for new section */
			allocated_entries = CFG_ALLOC_ENTRY_BATCH;
			curr_entry = -1;
			cfg->sections[curr_section] = malloc(
				sizeof(*cfg->sections[0]) +
				sizeof(cfg->sections[0]->entries[0]) *
				allocated_entries);
			if (cfg->sections[curr_section] == NULL) {
				printf("Error - no more memory\n");
				goto error1;
			}

			snprintf(cfg->sections[curr_section]->name,
					sizeof(cfg->sections[0]->name),
					"%s", &buffer[1]);
		} else {
			/* value line */
			if (curr_section < 0) {
				printf("Error line %d - value outside of"
					"section\n", lineno);
				goto error1;
			}

			struct rte_cfgfile_section *sect =
				cfg->sections[curr_section];
			char *split[2];
			if (rte_strsplit(buffer, sizeof(buffer), split, 2, '=')
				!= 2) {
				printf("Error at line %d - cannot split "
					"string\n", lineno);
				goto error1;
			}

			curr_entry++;
			if (curr_entry == allocated_entries) {
				allocated_entries += CFG_ALLOC_ENTRY_BATCH;
				struct rte_cfgfile_section *n_sect = realloc(
					sect, sizeof(*sect) +
					sizeof(sect->entries[0]) *
					allocated_entries);
				if (n_sect == NULL) {
					printf("Error - no more memory\n");
					goto error1;
				}
				sect = cfg->sections[curr_section] = n_sect;
			}

			sect->entries[curr_entry] = malloc(
				sizeof(*sect->entries[0]));
			if (sect->entries[curr_entry] == NULL) {
				printf("Error - no more memory\n");
				goto error1;
			}

			struct rte_cfgfile_entry *entry = sect->entries[
				curr_entry];
			snprintf(entry->name, sizeof(entry->name), "%s",
				split[0]);
			snprintf(entry->value, sizeof(entry->value), "%s",
				split[1]);
			_strip(entry->name, strnlen(entry->name,
				sizeof(entry->name)));
			_strip(entry->value, strnlen(entry->value,
				sizeof(entry->value)));
		}
	}
	fclose(f);
	cfg->flags = flags;
	cfg->sections[curr_section]->num_entries = curr_entry + 1;
	cfg->num_sections = curr_section + 1;
	return cfg;

error1:
	rte_cfgfile_close(cfg);
error2:
	fclose(f);
	return NULL;
}
Пример #5
0
/*
 * Parse a grant node.
 * @param domid
 *  Guest domain id.
 * @param path
 *  Full path string for a grant node, like for the following (key, val) pair
 *  idx#_mempool_gref = "gref#, gref#, gref#"
 *  path = 'local/domain/domid/control/dpdk/idx#_mempool_gref'
 *  gref# is a shared page contain packed (gref,pfn) entries
 * @return
 *  Returns the pointer to xen_gntnode
 */
static struct xen_gntnode *
parse_gntnode(int dom_id, char *path)
{
	char **gref_list = NULL;
	uint32_t i, len, gref_num;
	void *addr = NULL;
	char *buf = NULL;
	struct xen_gntnode *gntnode = NULL;
	struct xen_gnt *gnt = NULL;
	int pg_sz = getpagesize();
	char *end;
	uint64_t index;

	if ((buf = xen_read_node(path, &len)) == NULL)
		goto err;

	gref_list = malloc(MAX_GREF_PER_NODE * sizeof(char *));
	if (gref_list == NULL)
		goto err;

	gref_num = rte_strsplit(buf, len, gref_list, MAX_GREF_PER_NODE,
			XEN_GREF_SPLITTOKEN);
	if (gref_num == 0) {
		RTE_LOG(ERR, XENHOST, "  %s: invalid grant node format\n", __func__);
		goto err;
	}

	gntnode = calloc(1, sizeof(struct xen_gntnode));
	gnt = calloc(gref_num, sizeof(struct xen_gnt));
	if (gnt == NULL || gntnode == NULL)
		goto err;

	for (i = 0; i < gref_num; i++) {
		errno = 0;
		gnt[i].gref = strtol(gref_list[i], &end, 0);
		if (errno != 0 || end == NULL || end == gref_list[i] ||
			(*end != '\0' &&  *end != XEN_GREF_SPLITTOKEN)) {
			RTE_LOG(ERR, XENHOST, "  %s: parse grant node item failed\n", __func__);
			goto err;
		}
		addr = xen_grant_mmap(NULL, dom_id, gnt[i].gref, &index);
		if (addr == NULL) {
			RTE_LOG(ERR, XENHOST, "  %s: map gref %u failed\n", __func__, gnt[i].gref);
			goto err;
		}
		RTE_LOG(INFO, XENHOST, "      %s: map gref %u to %p\n", __func__, gnt[i].gref, addr);
		memcpy(gnt[i].gref_pfn, addr, pg_sz);
		if (munmap(addr, pg_sz)) {
			RTE_LOG(INFO, XENHOST, "  %s: unmap gref %u failed\n", __func__, gnt[i].gref);
			goto err;
		}
		if (xen_unmap_grant_ref(index)) {
			RTE_LOG(INFO, XENHOST, "  %s: release gref %u failed\n", __func__, gnt[i].gref);
			goto err;
		}

	}

	gntnode->gnt_num  = gref_num;
	gntnode->gnt_info = gnt;

	free(buf);
	free(gref_list);
	return gntnode;

err:
	free(gnt);
	free(gntnode);
	free(gref_list);
	free(buf);
	return NULL;
}