uint64_t wr_parse_coremask( const char * coremask ) { uint64_t cm; uint32_t lcore, n, i; char * sct[4]; char * arr[MAX_CORE_MATRIX_ENTRIES], * p; char buff[COREMASK_STRING_SIZE], * str; memset(arr, 0, sizeof(arr)); memset(sct, 0, sizeof(sct)); // Get a private copy so we can modify the string. strncpy(buff, &coremask[1], sizeof(buff)-1); str = buff; num_cores = wr_coremap("array", core_map, CORE_MAP_COUNT, NULL); if ( num_cores == 0xFFFF ) return 0; n = wr_strparse(str, ",", arr, MAX_CORE_MATRIX_ENTRIES); for(i = 0, cm = 0; i < n; i++) { if ( (p = arr[i]) == NULL ) return 0; if ( strchr(p, '/') ) { // Process the S/C/T format */ if ( wr_strparse(p, "/", sct, 4) != 3 ) return 0; // Handle converting the S/C/T to a lcore number. lcore = wr_sct_convert(sct); if ( lcore == 0xFFFF ) return 0; cm |= (1 << lcore); } else if ( *p == '[' ) { // We have a bit range uint32_t hi, lo; // decode the [lo-hi] format string. lo = strtoul(++p, NULL, 10); p = strchr(p, '-'); hi = (p != NULL) ? strtoul(++p, NULL, 10) : lo; while( lo <= hi ) cm |= (1ULL << lo++); } else { // We have a lcore number lcore = strtoul(p, NULL, 10); cm |= (1ULL << lcore); } } return cm; }
static int32_t wr_parse_lp_list( char * list, uint64_t * rt) { char * arr[3]; int32_t k; // Split up the string based on the ':' for Rx:Tx pairs k = wr_strparse( list, ":", arr, countof(arr) ); if ( (k == 0) || (k == 3) ) { fprintf(stderr, "*** Invalid string (%s)\n", list); return 1; } if ( k == 1 ) { // Must be a lcore/port number only wr_parse_rt_list(arr[0], &rt[0]); // Parse the list with no ':' character rt[1] = rt[0]; // Update the tx bitmap too. } else /* k == 2 */ { // Must be a <rx-list>:<tx-list> pair if ( wr_parse_rt_list(arr[0], &rt[0]) ) // parse <rx-list> return 1; if ( wr_parse_rt_list(arr[1], &rt[1]) ) // parse <tx-list> return 1; } return 0; }
static int32_t wr_parse_rt_list(char * list, uint64_t * map) { char * p; int32_t k, i; char * arr[33]; if ( list == NULL ) return 1; p = wr_strtrimset(list, "[]{}"); // trim the two character sets from the front/end of string. if ( (p == NULL) || (*p == '\0') ) return 1; // Split up the string by '/' for each list or range set k = wr_strparse(p, "/", arr, countof(arr)); if ( k == 0 ) return 1; for(i = 0; (i < k) && arr[i]; i++) { p = strchr(arr[i], '-'); if ( p != NULL ) { // Found a range list uint32_t l, h; *p++ = '\0'; l = strtol(arr[i], NULL, 10); h = strtol(p, NULL, 10); do { map[0] |= (1ULL << l); } while( ++l <= h ); } else // Must be a single value map[0] |= (1ULL << strtol(arr[i], NULL, 10)); } return 0; }
static int32_t wr_parse_port_list(char *list, ps_t *ps) { char *arr[3]; int32_t k; /* Split up the string based on the ':' for Rx:Tx pairs */ k = wr_strparse(list, ":", arr, countof(arr) ); if ( (k == 0) || (k == 3) ) { fprintf(stderr, "*** Invalid string (%s)\n", list); return 1; } if (k == 1) { /* Must be a lcore/port number only */ wr_parse_rt_list(arr[0], ps[RX_IDX].ps); /* Parse the list with no ':' character */ memcpy(ps[TX_IDX].ps, ps[RX_IDX].ps, sizeof(ps_t)); /* Update the tx bitmap too. */ } else { /* k == 2 */ /* Must be a <rx-list>:<tx-list> pair */ if (wr_parse_rt_list(arr[0], ps[RX_IDX].ps) ) /* parse <rx-list> */ return 1; if (wr_parse_rt_list(arr[1], ps[TX_IDX].ps) ) /* parse <tx-list> */ return 1; } return 0; }
int wr_parse_matrix(l2p_t * l2p, char * str) { char * lcore_port[MAX_MATRIX_ENTRIES]; char buff[256]; int i, m, k, lid_type, pid_type; uint32_t pid, lid; lp_t lp; rxtx_t cnt, n; wr_strccpy(buff, str, " \r\n\t\""); // Split up the string into <lcore-port>, ... k = wr_strparse(buff, ",", lcore_port, countof(lcore_port)); if ( k <= 0 ) { fprintf(stderr, "%s: could not parse (%s) string\n", __FUNCTION__, buff); return 0; } for(i = 0; (i < k) && lcore_port[i]; i++) { char * arr[3]; char str[64]; // Grab a private copy of the string. strncpy(str, lcore_port[i], sizeof(str)); // Parse the string into <lcore-list> and <port-list> m = wr_strparse( lcore_port[i], ".", arr, 3 ); if ( m != 2 ) { fprintf(stderr, "%s: could not parse <lcore-list>.<port-list> (%s) string\n", __FUNCTION__, lcore_port[i]); return 0; } memset(&lp, '\0', sizeof(lp)); if ( wr_parse_lp_list(arr[0], lp.lcores) ) { fprintf(stderr, "%s: could not parse <lcore-list> (%s) string\n", __FUNCTION__, arr[0]); return 0; } if ( wr_parse_lp_list(arr[1], lp.ports) ) { fprintf(stderr, "%s: could not parse <port-list> (%s) string\n", __FUNCTION__, arr[1]); return 0; } // Handle the lcore and port list maps fprintf(stderr, "%-16s = lcores(rx %016lx, tx %016lx) ports(rx %016lx, tx %016lx)\n", str, lp.lcores[RX_IDX], lp.lcores[TX_IDX], lp.ports[RX_IDX], lp.ports[TX_IDX]); for(lid = 0; lid < RTE_MAX_LCORE; lid++) { lid_type = 0; if ( (lp.lcores[RX_IDX] & (1ULL << lid)) != 0 ) lid_type |= RX_TYPE; if ( (lp.lcores[TX_IDX] & (1ULL << lid)) != 0 ) lid_type |= TX_TYPE; if ( lid_type == 0 ) continue; for(pid = 0; pid < RTE_MAX_ETHPORTS; pid++) { pid_type = 0; if ( (lp.ports[RX_IDX] & (1ULL << pid)) != 0 ) pid_type |= RX_TYPE; if ( (lp.ports[TX_IDX] & (1ULL << pid)) != 0 ) pid_type |= TX_TYPE; if ( pid_type == 0 ) continue; wr_l2p_connect(l2p, pid, lid, lid_type); } } } for(pid = 0; pid < RTE_MAX_ETHPORTS; pid++) { n.rxtx = 0; for(lid = 0; lid < RTE_MAX_LCORE; lid++) { if ( (cnt.rxtx = wr_get_map(l2p, pid, lid)) > 0) { if ( cnt.tx > 0 ) n.tx++; if ( cnt.rx > 0 ) n.rx++; } } l2p->map[pid][lid].rxtx = n.rxtx; // Update the lcores per port } for(lid = 0; lid < RTE_MAX_LCORE; lid++) { n.rxtx = 0; for(pid = 0; pid < RTE_MAX_ETHPORTS; pid++) { if ( (cnt.rxtx = wr_get_map(l2p, pid, lid)) > 0) { if ( cnt.tx > 0 ) n.tx++; if ( cnt.rx > 0 ) n.rx++; } } l2p->map[pid][lid].rxtx = n.rxtx; // Update the ports per lcore } return 0; }