+
+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;
+
+ 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) {
+ if ((nb_tx_queue_stats_mappings >=
+ MAX_TX_QUEUE_STATS_MAPPINGS)) {
+ printf("exceeded max number of TX queue "
+ "statistics mappings: %hu\n",
+ nb_tx_queue_stats_mappings);
+ return -1;
+ }
+ 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 {
+ if ((nb_rx_queue_stats_mappings >=
+ MAX_RX_QUEUE_STATS_MAPPINGS)) {
+ printf("exceeded max number of RX queue "
+ "statistics mappings: %hu\n",
+ nb_rx_queue_stats_mappings);
+ return -1;
+ }
+ 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;
+}
+
+static int
+parse_portnuma_config(const char *q_arg)
+{
+ char s[256];
+ const char *p, *p0 = q_arg;
+ char *end;
+ uint8_t i,port_id,socket_id;
+ unsigned size;
+ enum fieldnames {
+ FLD_PORT = 0,
+ FLD_SOCKET,
+ _NUM_FLD
+ };
+ unsigned long int_fld[_NUM_FLD];
+ char *str_fld[_NUM_FLD];
+ portid_t pid;
+
+ /* 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;
+
+ 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_is_invalid(port_id, ENABLED_WARN)) {
+ printf("Valid port range is [0");
+ RTE_ETH_FOREACH_DEV(pid)
+ printf(", %d", pid);
+ printf("]\n");
+ 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;
+ }
+ port_numa[port_id] = socket_id;
+ }
+
+ return 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];
+ portid_t pid;
+ #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;
+
+ 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_is_invalid(port_id, ENABLED_WARN)) {
+ printf("Valid port range is [0");
+ RTE_ETH_FOREACH_DEV(pid)
+ printf(", %d", pid);
+ printf("]\n");
+ 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;
+}
+