mirror of https://github.com/F-Stack/f-stack.git
Merge pull request #78 from yuyang0/multiple-nic
Multiple nic enhancement.
This commit is contained in:
commit
3b14d13555
24
config.ini
24
config.ini
|
@ -1,12 +1,7 @@
|
||||||
[dpdk]
|
[dpdk]
|
||||||
## Hexadecimal bitmask of cores to run on.
|
## Hexadecimal bitmask of cores to run on.
|
||||||
lcore_mask=1
|
lcore_mask=1
|
||||||
## Port mask, enable and disable ports.
|
|
||||||
## Default: all ports are enabled.
|
|
||||||
#port_mask=1
|
|
||||||
channel=4
|
channel=4
|
||||||
## Number of ports.
|
|
||||||
nb_ports=1
|
|
||||||
promiscuous=1
|
promiscuous=1
|
||||||
numa_on=1
|
numa_on=1
|
||||||
## TCP segment offload, default: disabled.
|
## TCP segment offload, default: disabled.
|
||||||
|
@ -14,6 +9,20 @@ tso=0
|
||||||
## HW vlan strip, default: enabled.
|
## HW vlan strip, default: enabled.
|
||||||
vlan_strip=1
|
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
|
## Port config section
|
||||||
## According to dpdk.nb_ports: port0, port1...
|
## According to dpdk.nb_ports: port0, port1...
|
||||||
[port0]
|
[port0]
|
||||||
|
@ -21,6 +30,11 @@ addr=192.168.1.2
|
||||||
netmask=255.255.255.0
|
netmask=255.255.255.0
|
||||||
broadcast=192.168.1.255
|
broadcast=192.168.1.255
|
||||||
gateway=192.168.1.1
|
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
|
## Packet capture path, this will hurt performance
|
||||||
#pcap=./a.pcap
|
#pcap=./a.pcap
|
||||||
|
|
||||||
|
|
201
lib/ff_config.c
201
lib/ff_config.c
|
@ -31,6 +31,7 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <rte_config.h>
|
#include <rte_config.h>
|
||||||
|
#include <rte_string_fns.h>
|
||||||
|
|
||||||
#include "ff_config.h"
|
#include "ff_config.h"
|
||||||
#include "ff_ini_parser.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;
|
proc_lcore = cfg->dpdk.proc_lcore;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove all blank characters ahead and after.
|
* Remove all blank characters ahead and after.
|
||||||
* Remove 0x/0X if exists.
|
* Remove 0x/0X if exists.
|
||||||
*/
|
*/
|
||||||
|
@ -190,23 +191,170 @@ freebsd_conf_handler(struct ff_config *cfg, const char *section,
|
||||||
|
|
||||||
return 1;
|
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
|
static int
|
||||||
port_cfg_handler(struct ff_config *cfg, const char *section,
|
port_cfg_handler(struct ff_config *cfg, const char *section,
|
||||||
const char *name, const char *value) {
|
const char *name, const char *value) {
|
||||||
|
|
||||||
if (cfg->dpdk.nb_ports == 0) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg->dpdk.port_cfgs == NULL) {
|
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) {
|
if (pc == NULL) {
|
||||||
fprintf(stderr, "port_cfg_handler malloc failed\n");
|
fprintf(stderr, "port_cfg_handler malloc failed\n");
|
||||||
return 0;
|
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;
|
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 */
|
/* just return true if portid >= nb_ports because it has no effect */
|
||||||
if (portid >= cfg->dpdk.nb_ports) {
|
if (portid > cfg->dpdk.max_portid) {
|
||||||
fprintf(stderr, "port_cfg_handler section[%s] max than nb_ports\n", section);
|
fprintf(stderr, "port_cfg_handler section[%s] bigger than max port id\n", section);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +387,8 @@ port_cfg_handler(struct ff_config *cfg, const char *section,
|
||||||
cur->gateway = strdup(value);
|
cur->gateway = strdup(value);
|
||||||
} else if (strcmp(name, "pcap") == 0) {
|
} else if (strcmp(name, "pcap") == 0) {
|
||||||
cur->pcap = strdup(value);
|
cur->pcap = strdup(value);
|
||||||
|
} else if (strcmp(name, "lcore_list") == 0) {
|
||||||
|
return parse_port_lcore_list(cur, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -262,10 +412,8 @@ ini_parse_handler(void* user, const char* section, const char* name,
|
||||||
} else if (MATCH("dpdk", "lcore_mask")) {
|
} else if (MATCH("dpdk", "lcore_mask")) {
|
||||||
pconfig->dpdk.lcore_mask = strdup(value);
|
pconfig->dpdk.lcore_mask = strdup(value);
|
||||||
return parse_lcore_mask(pconfig, pconfig->dpdk.lcore_mask);
|
return parse_lcore_mask(pconfig, pconfig->dpdk.lcore_mask);
|
||||||
} else if (MATCH("dpdk", "port_mask")) {
|
} else if (MATCH("dpdk", "port_list")) {
|
||||||
pconfig->dpdk.port_mask = atoi(value);
|
return parse_port_list(pconfig, value);
|
||||||
} else if (MATCH("dpdk", "nb_ports")) {
|
|
||||||
pconfig->dpdk.nb_ports = atoi(value);
|
|
||||||
} else if (MATCH("dpdk", "promiscuous")) {
|
} else if (MATCH("dpdk", "promiscuous")) {
|
||||||
pconfig->dpdk.promiscuous = atoi(value);
|
pconfig->dpdk.promiscuous = atoi(value);
|
||||||
} else if (MATCH("dpdk", "numa_on")) {
|
} else if (MATCH("dpdk", "numa_on")) {
|
||||||
|
@ -398,11 +546,43 @@ ff_check_config(struct ff_config *cfg)
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < cfg->dpdk.nb_ports; 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(addr);
|
||||||
CHECK_VALID(netmask);
|
CHECK_VALID(netmask);
|
||||||
CHECK_VALID(broadcast);
|
CHECK_VALID(broadcast);
|
||||||
CHECK_VALID(gateway);
|
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;
|
return 0;
|
||||||
|
@ -451,4 +631,3 @@ ff_load_config(int argc, char *const argv[])
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
// dpdk argc, argv, max argc: 4, member of dpdk_config
|
// dpdk argc, argv, max argc: 4, member of dpdk_config
|
||||||
#define DPDK_CONFIG_NUM 4
|
#define DPDK_CONFIG_NUM 4
|
||||||
#define DPDK_CONFIG_MAXLEN 64
|
#define DPDK_CONFIG_MAXLEN 64
|
||||||
|
#define DPDK_MAX_LCORE 128
|
||||||
|
|
||||||
extern int dpdk_argc;
|
extern int dpdk_argc;
|
||||||
extern char *dpdk_argv[DPDK_CONFIG_NUM + 1];
|
extern char *dpdk_argv[DPDK_CONFIG_NUM + 1];
|
||||||
|
@ -52,6 +53,9 @@ struct ff_port_cfg {
|
||||||
char *broadcast;
|
char *broadcast;
|
||||||
char *gateway;
|
char *gateway;
|
||||||
char *pcap;
|
char *pcap;
|
||||||
|
|
||||||
|
int nb_lcores;
|
||||||
|
uint16_t lcore_list[DPDK_MAX_LCORE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ff_freebsd_cfg {
|
struct ff_freebsd_cfg {
|
||||||
|
@ -64,28 +68,29 @@ struct ff_freebsd_cfg {
|
||||||
|
|
||||||
struct ff_config {
|
struct ff_config {
|
||||||
char *filename;
|
char *filename;
|
||||||
struct {
|
struct {
|
||||||
char *proc_type;
|
char *proc_type;
|
||||||
/* mask of enabled lcores */
|
/* mask of enabled lcores */
|
||||||
char *lcore_mask;
|
char *lcore_mask;
|
||||||
/* mask of current proc on all lcores */
|
/* mask of current proc on all lcores */
|
||||||
char *proc_mask;
|
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 nb_channel;
|
||||||
int memory;
|
int memory;
|
||||||
int no_huge;
|
int no_huge;
|
||||||
int nb_procs;
|
int nb_procs;
|
||||||
int proc_id;
|
int proc_id;
|
||||||
int nb_ports;
|
|
||||||
int promiscuous;
|
int promiscuous;
|
||||||
int numa_on;
|
int numa_on;
|
||||||
int tso;
|
int tso;
|
||||||
int vlan_strip;
|
int vlan_strip;
|
||||||
/* list of proc-lcore */
|
/* list of proc-lcore */
|
||||||
uint16_t *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;
|
struct ff_port_cfg *port_cfgs;
|
||||||
} dpdk;
|
} dpdk;
|
||||||
|
|
||||||
|
|
163
lib/ff_dpdk_if.c
163
lib/ff_dpdk_if.c
|
@ -145,12 +145,13 @@ struct lcore_rx_queue {
|
||||||
|
|
||||||
struct lcore_conf {
|
struct lcore_conf {
|
||||||
uint16_t proc_id;
|
uint16_t proc_id;
|
||||||
uint16_t nb_procs;
|
|
||||||
uint16_t socket_id;
|
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 nb_rx_queue;
|
||||||
uint16_t *proc_lcore;
|
|
||||||
struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_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];
|
struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
|
||||||
char *pcap[RTE_MAX_ETHPORTS];
|
char *pcap[RTE_MAX_ETHPORTS];
|
||||||
} __rte_cache_aligned;
|
} __rte_cache_aligned;
|
||||||
|
@ -231,10 +232,10 @@ check_all_ports_link_status(void)
|
||||||
for (count = 0; count <= MAX_CHECK_TIME; count++) {
|
for (count = 0; count <= MAX_CHECK_TIME; count++) {
|
||||||
all_ports_up = 1;
|
all_ports_up = 1;
|
||||||
for (i = 0; i < nb_ports; i++) {
|
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));
|
memset(&link, 0, sizeof(link));
|
||||||
rte_eth_link_get_nowait(portid, &link);
|
rte_eth_link_get_nowait(portid, &link);
|
||||||
|
|
||||||
/* print link status if flag set */
|
/* print link status if flag set */
|
||||||
if (print_flag == 1) {
|
if (print_flag == 1) {
|
||||||
if (link.link_status) {
|
if (link.link_status) {
|
||||||
|
@ -276,24 +277,31 @@ check_all_ports_link_status(void)
|
||||||
static int
|
static int
|
||||||
init_lcore_conf(void)
|
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");
|
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.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;
|
uint16_t proc_id;
|
||||||
for (proc_id = 0; proc_id < lcore_conf.nb_procs; proc_id++) {
|
for (proc_id = 0; proc_id < ff_global_cfg.dpdk.nb_procs; proc_id++) {
|
||||||
uint16_t lcore_id = lcore_conf.proc_lcore[proc_id];
|
uint16_t lcore_id = ff_global_cfg.dpdk.proc_lcore[proc_id];
|
||||||
if (!lcore_config[lcore_id].detected) {
|
if (!lcore_config[lcore_id].detected) {
|
||||||
rte_exit(EXIT_FAILURE, "lcore %u unavailable\n", lcore_id);
|
rte_exit(EXIT_FAILURE, "lcore %u unavailable\n", lcore_id);
|
||||||
}
|
}
|
||||||
|
@ -306,35 +314,34 @@ init_lcore_conf(void)
|
||||||
|
|
||||||
lcore_conf.socket_id = socket_id;
|
lcore_conf.socket_id = socket_id;
|
||||||
|
|
||||||
/* Currently, proc id 1:1 map to rx/tx queue id per port. */
|
uint16_t lcore_id = ff_global_cfg.dpdk.proc_lcore[lcore_conf.proc_id];
|
||||||
uint8_t port_id, enabled_ports = 0;
|
int j;
|
||||||
for (port_id = 0; port_id < nb_ports; port_id++) {
|
for (j = 0; j < ff_global_cfg.dpdk.nb_ports; ++j) {
|
||||||
if (ff_global_cfg.dpdk.port_mask &&
|
uint16_t port_id = ff_global_cfg.dpdk.portid_list[j];
|
||||||
(ff_global_cfg.dpdk.port_mask & (1 << port_id)) == 0) {
|
struct ff_port_cfg *pconf = &ff_global_cfg.dpdk.port_cfgs[port_id];
|
||||||
printf("\nSkipping disabled port %d\n", 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
printf("lcore: %u, port: %u, queue: %u\n", lcore_id, port_id, queueid);
|
||||||
if (port_id >= ff_global_cfg.dpdk.nb_ports) {
|
|
||||||
printf("\nSkipping non-configured port %d\n", port_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t nb_rx_queue = lcore_conf.nb_rx_queue;
|
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].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.nb_rx_queue++;
|
||||||
|
|
||||||
lcore_conf.tx_queue_id[port_id] = lcore_conf.proc_id;
|
lcore_conf.tx_queue_id[port_id] = queueid;
|
||||||
lcore_conf.pcap[port_id] = ff_global_cfg.dpdk.port_cfgs[enabled_ports].pcap;
|
|
||||||
|
|
||||||
ff_global_cfg.dpdk.port_cfgs[enabled_ports].port_id = port_id;
|
lcore_conf.pcap[port_id] = pconf->pcap;
|
||||||
|
lcore_conf.nb_queue_list[port_id] = pconf->nb_lcores;
|
||||||
enabled_ports++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ff_global_cfg.dpdk.nb_ports = enabled_ports;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,8 +367,8 @@ init_mem_pool(void)
|
||||||
uint16_t i, lcore_id;
|
uint16_t i, lcore_id;
|
||||||
char s[64];
|
char s[64];
|
||||||
|
|
||||||
for (i = 0; i < lcore_conf.nb_procs; i++) {
|
for (i = 0; i < ff_global_cfg.dpdk.nb_procs; i++) {
|
||||||
lcore_id = lcore_conf.proc_lcore[i];
|
lcore_id = ff_global_cfg.dpdk.proc_lcore[i];
|
||||||
if (numa_on) {
|
if (numa_on) {
|
||||||
socketid = rte_lcore_to_socket_id(lcore_id);
|
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;
|
int proc_id = ff_global_cfg.dpdk.proc_id;
|
||||||
|
|
||||||
/* Allocate arp ring ptr according to eth dev count. */
|
/* 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) {
|
for(i = 0; i < nb_procs; ++i) {
|
||||||
snprintf(name_buf, RTE_RING_NAMESIZE, "ring_ptr_%d_%d",
|
snprintf(name_buf, RTE_RING_NAMESIZE, "ring_ptr_%d_%d",
|
||||||
proc_id, i);
|
proc_id, i);
|
||||||
|
|
||||||
arp_ring[i] = rte_zmalloc(name_buf,
|
arp_ring[i] = rte_zmalloc(name_buf,
|
||||||
sizeof(struct rte_ring *) * nb_ports,
|
sizeof(struct rte_ring *) * nb_dev_ports,
|
||||||
RTE_CACHE_LINE_SIZE);
|
RTE_CACHE_LINE_SIZE);
|
||||||
if (arp_ring[i] == NULL) {
|
if (arp_ring[i] == NULL) {
|
||||||
rte_exit(EXIT_FAILURE, "rte_zmalloc(%s (struct rte_ring*)) "
|
rte_exit(EXIT_FAILURE, "rte_zmalloc(%s (struct rte_ring*)) "
|
||||||
|
@ -441,9 +448,9 @@ init_arp_ring(void)
|
||||||
unsigned socketid = lcore_conf.socket_id;
|
unsigned socketid = lcore_conf.socket_id;
|
||||||
|
|
||||||
/* Create ring according to ports actually being used. */
|
/* 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++) {
|
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) {
|
for(i = 0; i < nb_procs; ++i) {
|
||||||
snprintf(name_buf, RTE_RING_NAMESIZE, "arp_ring_%d_%d", i, port_id);
|
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;
|
nb_ports = ff_global_cfg.dpdk.nb_ports;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
for (i = 0; i < nb_ports; 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];
|
||||||
ff_kni_alloc(port_id, socket_id, mbuf_pool, KNI_QUEUE_SIZE);
|
ff_kni_alloc(port_id, socket_id, mbuf_pool, KNI_QUEUE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,26 +574,27 @@ static int
|
||||||
init_port_start(void)
|
init_port_start(void)
|
||||||
{
|
{
|
||||||
int nb_ports = ff_global_cfg.dpdk.nb_ports;
|
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());
|
unsigned socketid = rte_lcore_to_socket_id(rte_lcore_id());
|
||||||
struct rte_mempool *mbuf_pool = pktmbuf_pool[socketid];
|
struct rte_mempool *mbuf_pool = pktmbuf_pool[socketid];
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
for (i = 0; i < nb_ports; 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;
|
struct rte_eth_dev_info dev_info;
|
||||||
rte_eth_dev_info_get(port_id, &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",
|
rte_exit(EXIT_FAILURE, "num_procs[%d] bigger than max_rx_queues[%d]\n",
|
||||||
nb_procs,
|
nb_queues,
|
||||||
dev_info.max_rx_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",
|
rte_exit(EXIT_FAILURE, "num_procs[%d] bigger than max_tx_queues[%d]\n",
|
||||||
nb_procs,
|
nb_queues,
|
||||||
dev_info.max_tx_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[2], addr.addr_bytes[3],
|
||||||
addr.addr_bytes[4], addr.addr_bytes[5]);
|
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);
|
addr.addr_bytes, ETHER_ADDR_LEN);
|
||||||
|
|
||||||
/* Clear txq_flags - we do not need multi-mempool and refcnt */
|
/* 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) {
|
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) {
|
||||||
printf("LRO is supported\n");
|
printf("LRO is supported\n");
|
||||||
port_conf.rxmode.enable_lro = 1;
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -665,24 +673,24 @@ init_port_start(void)
|
||||||
(dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)) {
|
(dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)) {
|
||||||
printf("RX checksum offload supported\n");
|
printf("RX checksum offload supported\n");
|
||||||
port_conf.rxmode.hw_ip_checksum = 1;
|
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)) {
|
if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)) {
|
||||||
printf("TX ip checksum offload supported\n");
|
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) &&
|
if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) &&
|
||||||
(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)) {
|
(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)) {
|
||||||
printf("TX TCP&UDP checksum offload supported\n");
|
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 (ff_global_cfg.dpdk.tso) {
|
||||||
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) {
|
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) {
|
||||||
printf("TSO is supported\n");
|
printf("TSO is supported\n");
|
||||||
ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_tso = 1;
|
pconf->hw_features.tx_tso = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("TSO is disabled\n");
|
printf("TSO is disabled\n");
|
||||||
|
@ -701,14 +709,12 @@ init_port_start(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently, proc id 1:1 map to queue id per port. */
|
int ret = rte_eth_dev_configure(port_id, nb_queues, nb_queues, &port_conf);
|
||||||
int ret = rte_eth_dev_configure(port_id, nb_procs, nb_procs, &port_conf);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t q;
|
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,
|
ret = rte_eth_tx_queue_setup(port_id, q, TX_QUEUE_SIZE,
|
||||||
socketid, &dev_info.default_txconf);
|
socketid, &dev_info.default_txconf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -727,7 +733,7 @@ init_port_start(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nb_procs > 1) {
|
if (nb_queues > 1) {
|
||||||
/* set HW rss hash function to Toeplitz. */
|
/* set HW rss hash function to Toeplitz. */
|
||||||
if (!rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_HASH)) {
|
if (!rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_HASH)) {
|
||||||
struct rte_eth_hash_filter_info info = {0};
|
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. */
|
/* Enable RX in promiscuous mode for the Ethernet device. */
|
||||||
|
@ -756,8 +762,8 @@ init_port_start(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable pcap dump */
|
/* Enable pcap dump */
|
||||||
if (ff_global_cfg.dpdk.port_cfgs[i].pcap) {
|
if (pconf->pcap) {
|
||||||
ff_enable_pcap(ff_global_cfg.dpdk.port_cfgs[i].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
|
* FIXME: should we save pkt->vlan_tci
|
||||||
* if (pkt->ol_flags & PKT_RX_VLAN_PKT)
|
* 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;
|
struct rte_mbuf *mbuf_clone;
|
||||||
if (pkts_from_ring == 0) {
|
if (pkts_from_ring == 0) {
|
||||||
uint16_t i;
|
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)
|
if(i == queue_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned socket_id = 0;
|
unsigned socket_id = 0;
|
||||||
if (numa_on) {
|
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_pool = pktmbuf_pool[socket_id];
|
||||||
mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool);
|
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 nb_ports = ff_global_cfg.dpdk.nb_ports;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nb_ports; 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];
|
||||||
veth_ctx[port_id] = ff_veth_attach(ff_global_cfg.dpdk.port_cfgs + 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) {
|
if (veth_ctx[port_id] == NULL) {
|
||||||
rte_exit(EXIT_FAILURE, "ff_veth_attach failed");
|
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)
|
uint16_t sport, uint16_t dport)
|
||||||
{
|
{
|
||||||
struct lcore_conf *qconf = &lcore_conf;
|
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;
|
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 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) +
|
uint8_t data[sizeof(saddr) + sizeof(daddr) + sizeof(sport) +
|
||||||
sizeof(dport)];
|
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),
|
uint32_t hash = toeplitz_hash(sizeof(default_rsskey_40bytes),
|
||||||
default_rsskey_40bytes, datalen, data);
|
default_rsskey_40bytes, datalen, data);
|
||||||
|
|
||||||
return ((hash & (reta_size - 1)) % qconf->nb_procs) == qconf->proc_id;
|
return ((hash & (reta_size - 1)) % nb_queues) == queueid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue