diff --git a/config.ini b/config.ini index cb649f495..ed2bf3295 100644 --- a/config.ini +++ b/config.ini @@ -1,12 +1,7 @@ [dpdk] ## Hexadecimal bitmask of cores to run on. lcore_mask=1 -## Port mask, enable and disable ports. -## Default: all ports are enabled. -#port_mask=1 channel=4 -## Number of ports. -nb_ports=1 promiscuous=1 numa_on=1 ## TCP segment offload, default: disabled. @@ -14,6 +9,20 @@ tso=0 ## HW vlan strip, default: enabled. vlan_strip=1 +# enabled port list +# +# EBNF grammar: +# +# exp ::= num_list {"," num_list} +# num_list ::= | +# range ::= "-" +# num ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' +# +# examples +# 1-3 ports 1,2,3 are enabled +# 1-3,4,7 ports 1,2,3,4,7 are enabled +port_list=0 + ## Port config section ## According to dpdk.nb_ports: port0, port1... [port0] @@ -21,6 +30,11 @@ addr=192.168.1.2 netmask=255.255.255.0 broadcast=192.168.1.255 gateway=192.168.1.1 +# lcore list used to handle this port +# the format is same as port_list + +# lcore_list= 0 + ## Packet capture path, this will hurt performance #pcap=./a.pcap diff --git a/lib/ff_config.c b/lib/ff_config.c index 860baf969..4ca575cc7 100644 --- a/lib/ff_config.c +++ b/lib/ff_config.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "ff_config.h" #include "ff_ini_parser.h" @@ -85,7 +86,7 @@ parse_lcore_mask(struct ff_config *cfg, const char *coremask) } proc_lcore = cfg->dpdk.proc_lcore; - /* + /* * Remove all blank characters ahead and after. * Remove 0x/0X if exists. */ @@ -190,23 +191,170 @@ freebsd_conf_handler(struct ff_config *cfg, const char *section, return 1; } +// A recursive binary search function. It returns location of x in +// given array arr[l..r] is present, otherwise -1 +static int +uint16_binary_search(uint16_t arr[], int l, int r, uint16_t x) +{ + if (r >= l) { + int mid = l + (r - l)/2; + + // If the element is present at the middle itself + if (arr[mid] == x) return mid; + + // If element is smaller than mid, then it can only be present + // in left subarray + if (arr[mid] > x) return uint16_binary_search(arr, l, mid-1, x); + + // Else the element can only be present in right subarray + return uint16_binary_search(arr, mid+1, r, x); + } + + // We reach here when element is not present in array + return -1; +} + +static int +uint16_cmp (const void * a, const void * b) +{ + return ( *(uint16_t*)a - *(uint16_t*)b ); +} + +static inline void +sort_uint16_array(uint16_t arr[], int n) +{ + qsort(arr, n, sizeof(uint16_t), uint16_cmp); +} + +static inline char * +__strstrip(char *s) +{ + char *end = s + strlen(s) - 1; + while(*s == ' ') s++; + for (; end >= s; --end) { + if (*end != ' ') break; + } + *(++end) = '\0'; + return s; +} + +static int +__parse_config_list(uint16_t *arr, int *sz, const char *value) { + int i, j; + char input[4096]; + char *tokens[128]; + int nTokens = 0; + char *endptr; + int nr_ele = 0; + int max_ele = *sz; + + strncpy(input, value, 4096); + nTokens = rte_strsplit(input, sizeof(input), tokens, 128, ','); + for (i = 0; i < nTokens; i++) { + char *tok = tokens[i]; + char *middle = strchr(tok, '-'); + if (middle == NULL) { + tok = __strstrip(tok); + long v = strtol(tok, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, "%s is not a integer.", tok); + return 0; + } + if (nr_ele > max_ele) { + fprintf(stderr, "too many elements in list %s\n", value); + return 0; + } + arr[nr_ele++] = (uint16_t)v; + } else { + *middle = '\0'; + char *lbound = __strstrip(tok); + char *rbound = __strstrip(middle+1); + long lv = strtol(lbound, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, "%s is not a integer.", lbound); + return 0; + } + long rv = strtol(rbound, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, "%s is not a integer.", rbound); + return 0; + } + for (j = lv; j <= rv; ++j) { + if (nr_ele > max_ele) { + fprintf(stderr, "too many elements in list %s.\n", value); + return 0; + } + arr[nr_ele++] = (uint16_t)j; + } + } + } + if (nr_ele <= 0) { + printf("list %s is empty\n", value); + return 1; + } + sort_uint16_array(arr, nr_ele); + *sz = nr_ele; + return 1; +} + +static int +parse_port_lcore_list(struct ff_port_cfg *cfg, const char *v_str) +{ + cfg->nb_lcores = DPDK_MAX_LCORE; + uint16_t *cores = cfg->lcore_list; + return __parse_config_list(cores, &cfg->nb_lcores, v_str); +} + +static int +parse_port_list(struct ff_config *cfg, const char *v_str) +{ + int res; + uint16_t ports[RTE_MAX_ETHPORTS]; + int sz = RTE_MAX_ETHPORTS; + + res = __parse_config_list(ports, &sz, v_str); + if (! res) return res; + + uint16_t *portid_list = malloc(sizeof(uint16_t)*sz); + + if (portid_list == NULL) { + fprintf(stderr, "parse_port_list malloc failed\n"); + return 0; + } + memcpy(portid_list, ports, sz*sizeof(uint16_t)); + + cfg->dpdk.portid_list = portid_list; + cfg->dpdk.nb_ports = sz; + cfg->dpdk.max_portid = portid_list[sz-1]; + return res; +} static int port_cfg_handler(struct ff_config *cfg, const char *section, const char *name, const char *value) { if (cfg->dpdk.nb_ports == 0) { - fprintf(stderr, "port_cfg_handler: must config dpdk.nb_ports first\n"); + fprintf(stderr, "port_cfg_handler: must config dpdk.port_list first\n"); return 0; } if (cfg->dpdk.port_cfgs == NULL) { - struct ff_port_cfg *pc = calloc(cfg->dpdk.nb_ports, sizeof(struct ff_port_cfg)); + struct ff_port_cfg *pc = calloc(RTE_MAX_ETHPORTS, sizeof(struct ff_port_cfg)); if (pc == NULL) { fprintf(stderr, "port_cfg_handler malloc failed\n"); return 0; } + // initialize lcore list and nb_lcores + int i; + for (i = 0; i < cfg->dpdk.nb_ports; ++i) { + uint16_t portid = cfg->dpdk.portid_list[i]; + struct ff_port_cfg *pconf = &pc[portid]; + pconf->port_id = portid; + pconf->nb_lcores = ff_global_cfg.dpdk.nb_procs; + memcpy(pconf->lcore_list, ff_global_cfg.dpdk.proc_lcore, + pconf->nb_lcores*sizeof(uint16_t)); + } cfg->dpdk.port_cfgs = pc; } @@ -218,8 +366,8 @@ port_cfg_handler(struct ff_config *cfg, const char *section, } /* just return true if portid >= nb_ports because it has no effect */ - if (portid >= cfg->dpdk.nb_ports) { - fprintf(stderr, "port_cfg_handler section[%s] max than nb_ports\n", section); + if (portid > cfg->dpdk.max_portid) { + fprintf(stderr, "port_cfg_handler section[%s] bigger than max port id\n", section); return 1; } @@ -239,6 +387,8 @@ port_cfg_handler(struct ff_config *cfg, const char *section, cur->gateway = strdup(value); } else if (strcmp(name, "pcap") == 0) { cur->pcap = strdup(value); + } else if (strcmp(name, "lcore_list") == 0) { + return parse_port_lcore_list(cur, value); } return 1; @@ -262,10 +412,8 @@ ini_parse_handler(void* user, const char* section, const char* name, } else if (MATCH("dpdk", "lcore_mask")) { pconfig->dpdk.lcore_mask = strdup(value); return parse_lcore_mask(pconfig, pconfig->dpdk.lcore_mask); - } else if (MATCH("dpdk", "port_mask")) { - pconfig->dpdk.port_mask = atoi(value); - } else if (MATCH("dpdk", "nb_ports")) { - pconfig->dpdk.nb_ports = atoi(value); + } else if (MATCH("dpdk", "port_list")) { + return parse_port_list(pconfig, value); } else if (MATCH("dpdk", "promiscuous")) { pconfig->dpdk.promiscuous = atoi(value); } else if (MATCH("dpdk", "numa_on")) { @@ -398,11 +546,43 @@ ff_check_config(struct ff_config *cfg) int i; for (i = 0; i < cfg->dpdk.nb_ports; i++) { - struct ff_port_cfg *pc = &cfg->dpdk.port_cfgs[i]; + uint16_t portid = cfg->dpdk.portid_list[i]; + struct ff_port_cfg *pc = &cfg->dpdk.port_cfgs[portid]; CHECK_VALID(addr); CHECK_VALID(netmask); CHECK_VALID(broadcast); CHECK_VALID(gateway); + // check if the lcores in lcore_list are enabled. + int k; + for (k = 0; k < pc->nb_lcores; k++) { + uint16_t lcore_id = pc->lcore_list[k]; + if (uint16_binary_search(cfg->dpdk.proc_lcore, 0, + cfg->dpdk.nb_procs-1, lcore_id) < 0) { + fprintf(stderr, "lcore %d is not enabled.\n", lcore_id); + return -1; + } + } + /* + * only primary process process KNI, so if KNI enabled, + * primary lcore must stay in every enabled ports' lcore_list + */ + if (cfg->kni.enable && + strcmp(cfg->dpdk.proc_type, "primary") == 0) { + int found = 0; + int j; + uint16_t lcore_id = cfg->dpdk.proc_lcore[cfg->dpdk.proc_id]; + for (j = 0; j < pc->nb_lcores; j++) { + if (pc->lcore_list[j] == lcore_id) { + found = 1; + } + } + if (! found) { + fprintf(stderr, + "primary lcore %d should stay in port %d's lcore_list.\n", + lcore_id, pc->port_id); + return -1; + } + } } return 0; @@ -451,4 +631,3 @@ ff_load_config(int argc, char *const argv[]) return 0; } - diff --git a/lib/ff_config.h b/lib/ff_config.h index 1ac9035f1..f3fbe86c7 100644 --- a/lib/ff_config.h +++ b/lib/ff_config.h @@ -30,6 +30,7 @@ // dpdk argc, argv, max argc: 4, member of dpdk_config #define DPDK_CONFIG_NUM 4 #define DPDK_CONFIG_MAXLEN 64 +#define DPDK_MAX_LCORE 128 extern int dpdk_argc; extern char *dpdk_argv[DPDK_CONFIG_NUM + 1]; @@ -52,6 +53,9 @@ struct ff_port_cfg { char *broadcast; char *gateway; char *pcap; + + int nb_lcores; + uint16_t lcore_list[DPDK_MAX_LCORE]; }; struct ff_freebsd_cfg { @@ -64,28 +68,29 @@ struct ff_freebsd_cfg { struct ff_config { char *filename; - struct { + struct { char *proc_type; /* mask of enabled lcores */ char *lcore_mask; /* mask of current proc on all lcores */ char *proc_mask; - /* mask of enabled ports - * use uint32_t because num of max ports is 32 - */ - uint32_t port_mask; + int nb_channel; int memory; int no_huge; int nb_procs; int proc_id; - int nb_ports; int promiscuous; int numa_on; int tso; int vlan_strip; /* list of proc-lcore */ uint16_t *proc_lcore; + + int nb_ports; + uint16_t *portid_list; + uint16_t max_portid; + // MAP(portid => struct ff_port_cfg*) struct ff_port_cfg *port_cfgs; } dpdk; diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 581435e54..af90825fb 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -145,12 +145,13 @@ struct lcore_rx_queue { struct lcore_conf { uint16_t proc_id; - uint16_t nb_procs; uint16_t socket_id; + int16_t nb_queue_list[RTE_MAX_ETHPORTS]; + struct ff_port_cfg *port_cfgs; + uint16_t nb_rx_queue; - uint16_t *proc_lcore; struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE]; - uint16_t tx_queue_id[RTE_MAX_ETHPORTS]; + int16_t tx_queue_id[RTE_MAX_ETHPORTS]; struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS]; char *pcap[RTE_MAX_ETHPORTS]; } __rte_cache_aligned; @@ -231,10 +232,10 @@ check_all_ports_link_status(void) for (count = 0; count <= MAX_CHECK_TIME; count++) { all_ports_up = 1; for (i = 0; i < nb_ports; i++) { - uint8_t portid = ff_global_cfg.dpdk.port_cfgs[i].port_id; + uint8_t portid = ff_global_cfg.dpdk.portid_list[i]; memset(&link, 0, sizeof(link)); rte_eth_link_get_nowait(portid, &link); - + /* print link status if flag set */ if (print_flag == 1) { if (link.link_status) { @@ -276,24 +277,31 @@ check_all_ports_link_status(void) static int init_lcore_conf(void) { - uint8_t nb_ports = rte_eth_dev_count(); - if (nb_ports == 0) { + /* + * set all elements in tx_queue_id to -1, so we can use this array to check + * if port is processed by this core. + */ + int k; + for (k = 0; k < RTE_MAX_ETHPORTS; ++k) { + lcore_conf.tx_queue_id[k] = -1; + lcore_conf.nb_queue_list[k] = -1; + } + lcore_conf.port_cfgs = ff_global_cfg.dpdk.port_cfgs; + + uint8_t nb_dev_ports = rte_eth_dev_count(); + if (nb_dev_ports == 0) { rte_exit(EXIT_FAILURE, "No probed ethernet devices\n"); } + if (ff_global_cfg.dpdk.max_portid >= nb_dev_ports) { + rte_exit(EXIT_FAILURE, "this machine doesn't have port %d.\n", + ff_global_cfg.dpdk.max_portid); + } lcore_conf.proc_id = ff_global_cfg.dpdk.proc_id; - lcore_conf.nb_procs = ff_global_cfg.dpdk.nb_procs; - lcore_conf.proc_lcore = rte_zmalloc(NULL, - sizeof(uint16_t) * lcore_conf.nb_procs, 0); - if (lcore_conf.proc_lcore == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc proc_lcore failed\n"); - } - rte_memcpy(lcore_conf.proc_lcore, ff_global_cfg.dpdk.proc_lcore, - sizeof(uint16_t) * lcore_conf.nb_procs); uint16_t proc_id; - for (proc_id = 0; proc_id < lcore_conf.nb_procs; proc_id++) { - uint16_t lcore_id = lcore_conf.proc_lcore[proc_id]; + for (proc_id = 0; proc_id < ff_global_cfg.dpdk.nb_procs; proc_id++) { + uint16_t lcore_id = ff_global_cfg.dpdk.proc_lcore[proc_id]; if (!lcore_config[lcore_id].detected) { rte_exit(EXIT_FAILURE, "lcore %u unavailable\n", lcore_id); } @@ -306,35 +314,34 @@ init_lcore_conf(void) lcore_conf.socket_id = socket_id; - /* Currently, proc id 1:1 map to rx/tx queue id per port. */ - uint8_t port_id, enabled_ports = 0; - for (port_id = 0; port_id < nb_ports; port_id++) { - if (ff_global_cfg.dpdk.port_mask && - (ff_global_cfg.dpdk.port_mask & (1 << port_id)) == 0) { - printf("\nSkipping disabled port %d\n", port_id); + uint16_t lcore_id = ff_global_cfg.dpdk.proc_lcore[lcore_conf.proc_id]; + int j; + for (j = 0; j < ff_global_cfg.dpdk.nb_ports; ++j) { + uint16_t port_id = ff_global_cfg.dpdk.portid_list[j]; + struct ff_port_cfg *pconf = &ff_global_cfg.dpdk.port_cfgs[port_id]; + + int queueid = -1; + int i; + for (i = 0; i < pconf->nb_lcores; i++) { + if (pconf->lcore_list[i] == lcore_id) { + queueid = i; + } + } + if (queueid < 0) { continue; } - - if (port_id >= ff_global_cfg.dpdk.nb_ports) { - printf("\nSkipping non-configured port %d\n", port_id); - break; - } - + printf("lcore: %u, port: %u, queue: %u\n", lcore_id, port_id, queueid); uint16_t nb_rx_queue = lcore_conf.nb_rx_queue; lcore_conf.rx_queue_list[nb_rx_queue].port_id = port_id; - lcore_conf.rx_queue_list[nb_rx_queue].queue_id = lcore_conf.proc_id; + lcore_conf.rx_queue_list[nb_rx_queue].queue_id = queueid; lcore_conf.nb_rx_queue++; - lcore_conf.tx_queue_id[port_id] = lcore_conf.proc_id; - lcore_conf.pcap[port_id] = ff_global_cfg.dpdk.port_cfgs[enabled_ports].pcap; + lcore_conf.tx_queue_id[port_id] = queueid; - ff_global_cfg.dpdk.port_cfgs[enabled_ports].port_id = port_id; - - enabled_ports++; + lcore_conf.pcap[port_id] = pconf->pcap; + lcore_conf.nb_queue_list[port_id] = pconf->nb_lcores; } - ff_global_cfg.dpdk.nb_ports = enabled_ports; - return 0; } @@ -360,8 +367,8 @@ init_mem_pool(void) uint16_t i, lcore_id; char s[64]; - for (i = 0; i < lcore_conf.nb_procs; i++) { - lcore_id = lcore_conf.proc_lcore[i]; + for (i = 0; i < ff_global_cfg.dpdk.nb_procs; i++) { + lcore_id = ff_global_cfg.dpdk.proc_lcore[i]; if (numa_on) { socketid = rte_lcore_to_socket_id(lcore_id); } @@ -424,13 +431,13 @@ init_arp_ring(void) int proc_id = ff_global_cfg.dpdk.proc_id; /* Allocate arp ring ptr according to eth dev count. */ - int nb_ports = rte_eth_dev_count(); + int nb_dev_ports = rte_eth_dev_count(); for(i = 0; i < nb_procs; ++i) { snprintf(name_buf, RTE_RING_NAMESIZE, "ring_ptr_%d_%d", proc_id, i); arp_ring[i] = rte_zmalloc(name_buf, - sizeof(struct rte_ring *) * nb_ports, + sizeof(struct rte_ring *) * nb_dev_ports, RTE_CACHE_LINE_SIZE); if (arp_ring[i] == NULL) { rte_exit(EXIT_FAILURE, "rte_zmalloc(%s (struct rte_ring*)) " @@ -441,9 +448,9 @@ init_arp_ring(void) unsigned socketid = lcore_conf.socket_id; /* Create ring according to ports actually being used. */ - nb_ports = ff_global_cfg.dpdk.nb_ports; + int nb_ports = ff_global_cfg.dpdk.nb_ports; for (j = 0; j < nb_ports; j++) { - uint8_t port_id = ff_global_cfg.dpdk.port_cfgs[j].port_id; + uint16_t port_id = ff_global_cfg.dpdk.portid_list[j]; for(i = 0; i < nb_procs; ++i) { snprintf(name_buf, RTE_RING_NAMESIZE, "arp_ring_%d_%d", i, port_id); @@ -531,7 +538,7 @@ init_kni(void) nb_ports = ff_global_cfg.dpdk.nb_ports; int i, ret; for (i = 0; i < nb_ports; i++) { - uint8_t port_id = ff_global_cfg.dpdk.port_cfgs[i].port_id; + uint16_t port_id = ff_global_cfg.dpdk.portid_list[i]; ff_kni_alloc(port_id, socket_id, mbuf_pool, KNI_QUEUE_SIZE); } @@ -567,26 +574,27 @@ static int init_port_start(void) { int nb_ports = ff_global_cfg.dpdk.nb_ports; - uint16_t nb_procs = ff_global_cfg.dpdk.nb_procs; unsigned socketid = rte_lcore_to_socket_id(rte_lcore_id()); struct rte_mempool *mbuf_pool = pktmbuf_pool[socketid]; uint16_t i; for (i = 0; i < nb_ports; i++) { - uint8_t port_id = ff_global_cfg.dpdk.port_cfgs[i].port_id; + uint16_t port_id = ff_global_cfg.dpdk.portid_list[i]; + struct ff_port_cfg *pconf = &ff_global_cfg.dpdk.port_cfgs[port_id]; + uint16_t nb_queues = pconf->nb_lcores; struct rte_eth_dev_info dev_info; rte_eth_dev_info_get(port_id, &dev_info); - if (nb_procs > dev_info.max_rx_queues) { + if (nb_queues > dev_info.max_rx_queues) { rte_exit(EXIT_FAILURE, "num_procs[%d] bigger than max_rx_queues[%d]\n", - nb_procs, + nb_queues, dev_info.max_rx_queues); } - if (nb_procs > dev_info.max_tx_queues) { + if (nb_queues > dev_info.max_tx_queues) { rte_exit(EXIT_FAILURE, "num_procs[%d] bigger than max_tx_queues[%d]\n", - nb_procs, + nb_queues, dev_info.max_tx_queues); } @@ -599,7 +607,7 @@ init_port_start(void) addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); - rte_memcpy(ff_global_cfg.dpdk.port_cfgs[i].mac, + rte_memcpy(pconf->mac, addr.addr_bytes, ETHER_ADDR_LEN); /* Clear txq_flags - we do not need multi-mempool and refcnt */ @@ -655,7 +663,7 @@ init_port_start(void) if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) { printf("LRO is supported\n"); port_conf.rxmode.enable_lro = 1; - ff_global_cfg.dpdk.port_cfgs[i].hw_features.rx_lro = 1; + pconf->hw_features.rx_lro = 1; } #endif @@ -665,24 +673,24 @@ init_port_start(void) (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)) { printf("RX checksum offload supported\n"); port_conf.rxmode.hw_ip_checksum = 1; - ff_global_cfg.dpdk.port_cfgs[i].hw_features.rx_csum = 1; + pconf->hw_features.rx_csum = 1; } if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)) { printf("TX ip checksum offload supported\n"); - ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_csum_ip = 1; + pconf->hw_features.tx_csum_ip = 1; } if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) && (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)) { printf("TX TCP&UDP checksum offload supported\n"); - ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_csum_l4 = 1; + pconf->hw_features.tx_csum_l4 = 1; } if (ff_global_cfg.dpdk.tso) { if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) { printf("TSO is supported\n"); - ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_tso = 1; + pconf->hw_features.tx_tso = 1; } } else { printf("TSO is disabled\n"); @@ -701,14 +709,12 @@ init_port_start(void) continue; } - /* Currently, proc id 1:1 map to queue id per port. */ - int ret = rte_eth_dev_configure(port_id, nb_procs, nb_procs, &port_conf); + int ret = rte_eth_dev_configure(port_id, nb_queues, nb_queues, &port_conf); if (ret != 0) { return ret; } - uint16_t q; - for (q = 0; q < nb_procs; q++) { + for (q = 0; q < nb_queues; q++) { ret = rte_eth_tx_queue_setup(port_id, q, TX_QUEUE_SIZE, socketid, &dev_info.default_txconf); if (ret < 0) { @@ -727,7 +733,7 @@ init_port_start(void) return ret; } - if (nb_procs > 1) { + if (nb_queues > 1) { /* set HW rss hash function to Toeplitz. */ if (!rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_HASH)) { struct rte_eth_hash_filter_info info = {0}; @@ -741,7 +747,7 @@ init_port_start(void) } } - set_rss_table(port_id, dev_info.reta_size, nb_procs); + set_rss_table(port_id, dev_info.reta_size, nb_queues); } /* Enable RX in promiscuous mode for the Ethernet device. */ @@ -756,8 +762,8 @@ init_port_start(void) } /* Enable pcap dump */ - if (ff_global_cfg.dpdk.port_cfgs[i].pcap) { - ff_enable_pcap(ff_global_cfg.dpdk.port_cfgs[i].pcap); + if (pconf->pcap) { + ff_enable_pcap(pconf->pcap); } } @@ -838,7 +844,7 @@ ff_veth_input(const struct ff_dpdk_if_context *ctx, struct rte_mbuf *pkt) } } - /* + /* * FIXME: should we save pkt->vlan_tci * if (pkt->ol_flags & PKT_RX_VLAN_PKT) */ @@ -917,13 +923,17 @@ process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs, struct rte_mbuf *mbuf_clone; if (pkts_from_ring == 0) { uint16_t i; - for(i = 0; i < qconf->nb_procs; ++i) { + int16_t nb_queues = qconf->nb_queue_list[port_id]; + assert(nb_queues != -1); + + for(i = 0; i < nb_queues; ++i) { if(i == queue_id) continue; unsigned socket_id = 0; if (numa_on) { - socket_id = rte_lcore_to_socket_id(qconf->proc_lcore[i]); + uint16_t lcore_id = qconf->port_cfgs[port_id].lcore_list[i]; + socket_id = rte_lcore_to_socket_id(lcore_id); } mbuf_pool = pktmbuf_pool[socket_id]; mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool); @@ -1333,8 +1343,13 @@ ff_dpdk_if_up(void) { int nb_ports = ff_global_cfg.dpdk.nb_ports; int i; for (i = 0; i < nb_ports; i++) { - uint8_t port_id = ff_global_cfg.dpdk.port_cfgs[i].port_id; - veth_ctx[port_id] = ff_veth_attach(ff_global_cfg.dpdk.port_cfgs + i); + uint16_t port_id = ff_global_cfg.dpdk.portid_list[i]; + // if port's lcore list does't contain current core, just skip this port + if (lcore_conf.tx_queue_id[port_id] < 0) { + continue; + } + struct ff_port_cfg *pconf = &ff_global_cfg.dpdk.port_cfgs[port_id]; + veth_ctx[port_id] = ff_veth_attach(pconf); if (veth_ctx[port_id] == NULL) { rte_exit(EXIT_FAILURE, "ff_veth_attach failed"); } @@ -1388,13 +1403,15 @@ ff_rss_check(void *softc, uint32_t saddr, uint32_t daddr, uint16_t sport, uint16_t dport) { struct lcore_conf *qconf = &lcore_conf; + struct ff_dpdk_if_context *ctx = ff_veth_softc_to_hostc(softc); + uint16_t nb_queues = qconf->nb_queue_list[ctx->port_id]; - if (qconf->nb_procs == 1) { + if (nb_queues == 1) { return 1; } - struct ff_dpdk_if_context *ctx = ff_veth_softc_to_hostc(softc); uint16_t reta_size = rss_reta_size[ctx->port_id]; + uint16_t queueid = qconf->tx_queue_id[ctx->port_id]; uint8_t data[sizeof(saddr) + sizeof(daddr) + sizeof(sport) + sizeof(dport)]; @@ -1416,7 +1433,5 @@ ff_rss_check(void *softc, uint32_t saddr, uint32_t daddr, uint32_t hash = toeplitz_hash(sizeof(default_rsskey_40bytes), default_rsskey_40bytes, datalen, data); - return ((hash & (reta_size - 1)) % qconf->nb_procs) == qconf->proc_id; + return ((hash & (reta_size - 1)) % nb_queues) == queueid; } - -