Merge pull request #78 from yuyang0/multiple-nic

Multiple nic enhancement.
This commit is contained in:
logwang 2017-09-21 13:55:17 +08:00 committed by GitHub
commit 3b14d13555
4 changed files with 309 additions and 96 deletions

View File

@ -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 ::= <num> | <range>
# range ::= <num>"-"<num>
# 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

View File

@ -31,6 +31,7 @@
#include <getopt.h>
#include <ctype.h>
#include <rte_config.h>
#include <rte_string_fns.h>
#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;
}

View File

@ -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;

View File

@ -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;
}