From bf52ccc344ef6fe2eca228d5c8c1e140533d0e16 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 6 Dec 2016 17:16:37 +0200 Subject: Fix to Mellanox recevie all mode Signed-off-by: Ido Barnea --- src/main_dpdk.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index f92d18c4..fb937ca9 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -6613,6 +6613,7 @@ int CTRexExtendedDriverBaseMlnx5G::set_rcv_all(CPhyEthIF * _if, bool set_on) { add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 2, 17, MAIN_DPDK_RX_Q); } else { add_del_rules(RTE_ETH_FILTER_DELETE, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 2, 17, MAIN_DPDK_RX_Q); + add_del_rx_filter_rules(_if, true); } return 0; -- cgit 1.2.3-korg From 0f604284e8eb2c9b942e204e088693985ca06e4e Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Thu, 8 Dec 2016 23:40:01 +0200 Subject: Add prints about link down for stateless Change-Id: I1c32ab854ff2bbaaacb32e9aececfd67afba887b Signed-off-by: Yaroslav Brustinov --- src/main_dpdk.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index fb937ca9..a88d4a7c 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2615,6 +2615,8 @@ public: float m_total_rx_pps; float m_cpu_util; + bool m_link_up = true; + bool m_link_was_down = false; }; class CGlobalStats { @@ -2885,8 +2887,11 @@ void CGlobalStats::Dump(FILE *fd,DumpFormat mode){ fprintf (fd," --------------- \n"); for (i=0; i<(int)port_to_show; i++) { CPerPortStats * lp=&m_port[i]; - fprintf(fd,"port : %d \n",(int)i); - fprintf(fd,"------------\n"); + fprintf(fd,"port : %d ",(int)i); + if ( ! lp->m_link_up ) { + fprintf(fd," (link DOWN)"); + } + fprintf(fd,"\n------------\n"); #define GS_DP_A4(f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)lp->f) #define GS_DP_A(f) if (lp->f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)lp->f) GS_DP_A4(opackets); @@ -2900,7 +2905,13 @@ void CGlobalStats::Dump(FILE *fd,DumpFormat mode){ }else{ fprintf(fd," %10s ","ports"); for (i=0; i<(int)port_to_show; i++) { - fprintf(fd,"| %15d ",i); + CPerPortStats * lp=&m_port[i]; + if ( lp->m_link_up ) { + fprintf(fd,"| %15d ",i); + } else { + std::string port_with_state = "(link DOWN) " + std::to_string(i); + fprintf(fd,"| %15s ",port_with_state.c_str()); + } } fprintf(fd,"\n"); fprintf(fd," -----------------------------------------------------------------------------------------\n"); @@ -3971,6 +3982,11 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){ } else fprintf (fd, " Total-pkt-drop : %llu pkts \n", (unsigned long long) (pkt_out - pkt_in)); + for (i=0; im_total_tx_pps = _if->get_last_tx_pps_rate(); stp->m_total_rx_bps = _if->get_last_rx_rate()*_1Mb_DOUBLE; stp->m_total_rx_pps = _if->get_last_rx_pps_rate(); + stp->m_link_up = _if->get_port_attr()->is_link_up(); + stp->m_link_was_down |= ! _if->get_port_attr()->is_link_up(); stats.m_total_tx_pkts += st.opackets; stats.m_total_rx_pkts += st.ipackets; -- cgit 1.2.3-korg From fd9485d62a78e027b107717476a9b0df005a012d Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Sun, 11 Dec 2016 13:56:24 +0200 Subject: Cisco VIC card - support for receive all mode, and work around for IPv6 issues Signed-off-by: Ido Barnea --- src/dpdk/drivers/net/enic/base/vnic_dev.c | 5 ++ src/dpdk/drivers/net/enic/enic_clsf.c | 55 +++++++++++++- src/main_dpdk.cpp | 121 +++++++++++++----------------- 3 files changed, 109 insertions(+), 72 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/dpdk/drivers/net/enic/base/vnic_dev.c b/src/dpdk/drivers/net/enic/base/vnic_dev.c index 713b6089..e50b90e7 100644 --- a/src/dpdk/drivers/net/enic/base/vnic_dev.c +++ b/src/dpdk/drivers/net/enic/base/vnic_dev.c @@ -667,7 +667,12 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); +#define TREX_PATCH +#ifdef TREX_PATCH + err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait); +#else err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait); +#endif if (err) pr_err("Can't set packet filter\n"); diff --git a/src/dpdk/drivers/net/enic/enic_clsf.c b/src/dpdk/drivers/net/enic/enic_clsf.c index 23cb0124..8f68faab 100644 --- a/src/dpdk/drivers/net/enic/enic_clsf.c +++ b/src/dpdk/drivers/net/enic/enic_clsf.c @@ -107,6 +107,7 @@ enic_set_layer(struct filter_generic_1 *gp, unsigned int flag, memcpy(gp->layer[layer].val, val, len); } + /* Copy Flow Director filter to a VIC ipv4 filter (for Cisco VICs * without advanced filter support. */ @@ -132,6 +133,28 @@ copy_fltr_v1(struct filter_v2 *fltr, struct rte_eth_fdir_input *input, fltr->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE; } +#define TREX_PATCH +#ifdef TREX_PATCH +void +copy_fltr_recv_all(struct filter_v2 *fltr, struct rte_eth_fdir_input *input, + struct rte_eth_fdir_masks *masks) { + struct filter_generic_1 *gp = &fltr->u.generic_1; + memset(gp, 0, sizeof(*gp)); + + struct ether_hdr eth_mask, eth_val; + memset(ð_mask, 0, sizeof(eth_mask)); + memset(ð_val, 0, sizeof(eth_val)); + + eth_val.ether_type = 0x0806; + eth_mask.ether_type = 0; + + gp->position = 0; + enic_set_layer(gp, 0, FILTER_GENERIC_1_L2, + ð_mask, ð_val, sizeof(struct ether_hdr)); + +} +#endif + /* Copy Flow Director filter to a VIC generic filter (requires advanced * filter support. */ @@ -146,6 +169,11 @@ copy_fltr_v2(struct filter_v2 *fltr, struct rte_eth_fdir_input *input, fltr->type = FILTER_DPDK_1; memset(gp, 0, sizeof(*gp)); +#ifdef TREX_PATCH + // important for this to be below 2. + // If added with position 2, IPv6 UDP and ICMP seems to be caught by some other rule + gp->position = 1; +#endif if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) { struct udp_hdr udp_mask, udp_val; @@ -344,11 +372,23 @@ int enic_fdir_del_fltr(struct enic *enic, struct rte_eth_fdir_filter *params) case -EINVAL: case -ENOENT: enic->fdir.stats.f_remove++; +#ifdef TREX_PATCH + return pos; +#else return -EINVAL; +#endif default: /* The entry is present in the table */ key = enic->fdir.nodes[pos]; +#ifdef TREX_PATCH + switch (params->soft_id) { + case 100: + // remove promisc when we delete 'receive all' filter + vnic_dev_packet_filter(enic->vdev, 1, 1, 1, 0, 1); + break; + } +#endif /* Delete the filter */ vnic_dev_classifier(enic->vdev, CLSF_DEL, &key->fltr_id, NULL); @@ -455,8 +495,19 @@ int enic_fdir_add_fltr(struct enic *enic, struct rte_eth_fdir_filter *params) key->filter = *params; key->rq_index = queue; - enic->fdir.copy_fltr_fn(&fltr, ¶ms->input, - &enic->rte_dev->data->dev_conf.fdir_conf.mask); +#ifdef TREX_PATCH + switch (params->soft_id) { + case 100: + vnic_dev_packet_filter(enic->vdev, 1, 1, 1, 1, 1); + copy_fltr_recv_all(&fltr, ¶ms->input, &enic->rte_dev->data->dev_conf.fdir_conf.mask); + break; + default: +#endif + enic->fdir.copy_fltr_fn(&fltr, ¶ms->input, + &enic->rte_dev->data->dev_conf.fdir_conf.mask); +#ifdef TREX_PATCH + } +#endif if (!vnic_dev_classifier(enic->vdev, CLSF_ADD, &queue, &fltr)) { key->fltr_id = queue; diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index a88d4a7c..6d78719f 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -443,8 +443,8 @@ public: private: - virtual void add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, uint8_t ttl - , uint16_t ip_id, uint8_t l4_proto, int queue); + virtual void add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, uint16_t id + , uint8_t l4_proto, uint8_t tos, int queue); virtual int add_del_eth_type_rule(uint8_t port_id, enum rte_filter_op op, uint16_t eth_type); virtual int configure_rx_filter_rules_statefull(CPhyEthIF * _if); @@ -6583,7 +6583,7 @@ void CTRexExtendedDriverBaseMlnx5G::add_del_rules(enum rte_filter_op op, uint8_t memset(&filter,0,sizeof(struct rte_eth_fdir_filter)); #if 0 - printf("40g::%s rules: port:%d type:%d ip_id:%x l4:%d q:%d\n" + printf("MLNX add_del_rules::%s rules: port:%d type:%d ip_id:%x l4:%d q:%d\n" , (op == RTE_ETH_FILTER_ADD) ? "add" : "del" , port_id, type, ip_id, l4_proto, queue); #endif @@ -6599,7 +6599,6 @@ void CTRexExtendedDriverBaseMlnx5G::add_del_rules(enum rte_filter_op op, uint8_t case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: - // filter.input.flow.ip4_flow.ttl = ttl; filter.input.flow.ip4_flow.ip_id = ip_id; if (l4_proto != 0) filter.input.flow.ip4_flow.proto = l4_proto; @@ -6607,7 +6606,6 @@ void CTRexExtendedDriverBaseMlnx5G::add_del_rules(enum rte_filter_op op, uint8_t case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: - // filter.input.flow.ipv6_flow.hop_limits=ttl; filter.input.flow.ipv6_flow.flow_label = ip_id; filter.input.flow.ipv6_flow.proto = l4_proto; break; @@ -6745,30 +6743,13 @@ void CTRexExtendedDriverBaseVIC::update_configuration(port_cfg_t * cfg){ cfg->m_tx_conf.tx_thresh.hthresh = TX_HTHRESH; cfg->m_tx_conf.tx_thresh.wthresh = TX_WTHRESH; cfg->m_port_conf.rxmode.max_rx_pkt_len =9*1000-10; - - if (get_is_stateless()) { - /* work in TOS mode */ - cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos = 0x01; - cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc = 0x01; - }else{ - #ifdef VIC_TTL_FILTER - cfg->m_port_conf.fdir_conf.mask.ipv4_mask.ttl = 0xff; - cfg->m_port_conf.fdir_conf.mask.ipv6_mask.hop_limits = 0xff; - #else - cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos = 0x01; - cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc = 0x01; - #endif - } + cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos = 0x0f; + cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc = 0x0f; } - -/* Add rule to send packets with protocol 'type', and ttl 'ttl' to rx queue 1 */ -// ttl is used in statefull mode, and ip_id in stateless. We configure the driver registers so that only one of them applies. -// So, the rule will apply if packet has either the correct ttl or IP ID, depending if we are in statfull or stateless. -void CTRexExtendedDriverBaseVIC::add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, uint8_t ttl - , uint16_t ip_id, uint8_t l4_proto, int queue) { +void CTRexExtendedDriverBaseVIC::add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type + , uint16_t id, uint8_t l4_proto, uint8_t tos, int queue) { int ret=rte_eth_dev_filter_supported(port_id, RTE_ETH_FILTER_FDIR); - static int filter_soft_id = 0; if ( ret != 0 ){ rte_exit(EXIT_FAILURE, "rte_eth_dev_filter_supported " @@ -6781,15 +6762,15 @@ void CTRexExtendedDriverBaseVIC::add_del_rules(enum rte_filter_op op, uint8_t po memset(&filter,0,sizeof(struct rte_eth_fdir_filter)); #if 0 - printf("40g::%s rules: port:%d type:%d ttl:%d ip_id:%x l4:%d q:%d\n" + printf("VIC add_del_rules::%s rules: port:%d type:%d id:%d l4:%d tod:%d, q:%d\n" , (op == RTE_ETH_FILTER_ADD) ? "add" : "del" - , port_id, type, ttl, ip_id, l4_proto, queue); + , port_id, type, id, l4_proto, tos, queue); #endif filter.action.rx_queue = queue; - filter.action.behavior =RTE_ETH_FDIR_ACCEPT; - filter.action.report_status =RTE_ETH_FDIR_NO_REPORT_STATUS; - filter.soft_id = filter_soft_id++; + filter.action.behavior = RTE_ETH_FDIR_ACCEPT; + filter.action.report_status = RTE_ETH_FDIR_NO_REPORT_STATUS; + filter.soft_id = id; filter.input.flow_type = type; switch (type) { @@ -6797,22 +6778,22 @@ void CTRexExtendedDriverBaseVIC::add_del_rules(enum rte_filter_op op, uint8_t po case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP: case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER: - filter.input.flow.ip4_flow.tos=ttl; - filter.input.flow.ip4_flow.ip_id = ip_id; - if (l4_proto != 0) - filter.input.flow.ip4_flow.proto = l4_proto; + filter.input.flow.ip4_flow.tos = tos; + filter.input.flow.ip4_flow.proto = l4_proto; break; case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER: - filter.input.flow.ipv6_flow.tc=ttl; - filter.input.flow.ipv6_flow.flow_label = ip_id; + filter.input.flow.ipv6_flow.tc = tos; filter.input.flow.ipv6_flow.proto = l4_proto; break; } ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, op, (void*)&filter); if ( ret != 0 ) { + if (((op == RTE_ETH_FILTER_ADD) && (ret == -EEXIST)) || ((op == RTE_ETH_FILTER_DELETE) && (ret == -ENOENT))) + return; + rte_exit(EXIT_FAILURE, "rte_eth_dev_filter_ctrl: err=%d, port=%u\n", ret, port_id); } @@ -6831,38 +6812,46 @@ int CTRexExtendedDriverBaseVIC::add_del_eth_type_rule(uint8_t port_id, enum rte_ return ret; } -extern "C" int rte_eth_fdir_stats_reset(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len); - int CTRexExtendedDriverBaseVIC::configure_rx_filter_rules_statefull(CPhyEthIF * _if) { uint32_t port_id = _if->get_port_id(); -#ifndef VIC_TTL_FILTER - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 0x1, 0, 17, MAIN_DPDK_RX_Q); /*TCP/UDP */ - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, 0x1, 0, 6, MAIN_DPDK_RX_Q); - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_SCTP, 0x1, 0, 132, MAIN_DPDK_RX_Q); /*SCTP*/ - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, 0x1, 0, 1, MAIN_DPDK_RX_Q); /*ICMP*/ - - /* Ipv6*/ - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, 0x1, 0, 0, MAIN_DPDK_RX_Q); /*Any protocol on Ipv6*/ -#else - uint16_t hops = get_rx_check_hops(); - int i; - for (i = 0; i < 2; i++) { - uint8_t ttl = TTL_RESERVE_DUPLICATE - i - hops; - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, ttl, 0, 17, MAIN_DPDK_RX_Q); - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, ttl, 0, 6, MAIN_DPDK_RX_Q); - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, ttl, 0, RX_CHECK_V6_OPT_TYPE, MAIN_DPDK_RX_Q); - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_TCP, ttl, 0, RX_CHECK_V6_OPT_TYPE, MAIN_DPDK_RX_Q); - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, ttl, 0, RX_CHECK_V6_OPT_TYPE, MAIN_DPDK_RX_Q); - /* Rules for latency measurement packets */ - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, ttl, 0, IPPROTO_ICMP, MAIN_DPDK_RX_Q); - add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_SCTP, ttl, 0, 138, MAIN_DPDK_RX_Q); - } -#endif + + set_rcv_all(_if, false); + + // Rules to direct all IP packets with tos lsb bit 1 to RX Q. + // IPv4 + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 1, 17, 0x1, MAIN_DPDK_RX_Q); + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, 1, 6, 0x1, MAIN_DPDK_RX_Q); + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_SCTP, 1, 132, 0x1, MAIN_DPDK_RX_Q); /*SCTP*/ + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, 1, 1, 0x1, MAIN_DPDK_RX_Q); /*ICMP*/ + // Ipv6 + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, 1, 6, 0x1, MAIN_DPDK_RX_Q); + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, 1, 17, 0x1, MAIN_DPDK_RX_Q); + + // Because of some issue with VIC firmware, IPv6 UDP and ICMP go by default to q 1, so we + // need these rules to make them go to q 0. + // rule appply to all packets with 0 on tos lsb. + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, 1, 6, 0, MAIN_DPDK_DATA_Q); + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, 1, 17, 0, MAIN_DPDK_DATA_Q); return 0; } +int CTRexExtendedDriverBaseVIC::set_rcv_all(CPhyEthIF * _if, bool set_on) { + uint8_t port_id = _if->get_rte_port_id(); + + // soft ID 100 tells VIC driver to add rule for all ether types. + // Added with highest priority (implicitly in the driver), so if it exists, it applies before all other rules + if (set_on) { + add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 100, 30, 0, MAIN_DPDK_RX_Q); + } else { + add_del_rules(RTE_ETH_FILTER_DELETE, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 100, 30, 0, MAIN_DPDK_RX_Q); + } + + return 0; + +} + void CTRexExtendedDriverBaseVIC::clear_extended_stats(CPhyEthIF * _if){ rte_eth_stats_reset(_if->get_port_id()); } @@ -6895,7 +6884,6 @@ void CTRexExtendedDriverBaseVIC::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSta prev_stats->rx_nombuf = stats1.rx_nombuf; } - int CTRexExtendedDriverBaseVIC::verify_fw_ver(int port_id) { struct rte_eth_fdir_info fdir_info; @@ -6916,7 +6904,6 @@ int CTRexExtendedDriverBaseVIC::verify_fw_ver(int port_id) { exit(1); } - int CTRexExtendedDriverBaseVIC::configure_rx_filter_rules(CPhyEthIF * _if) { if (get_is_stateless()) { @@ -6944,18 +6931,12 @@ int CTRexExtendedDriverBaseVIC::dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd return (0); } - CFlowStatParser *CTRexExtendedDriverBaseVIC::get_flow_stat_parser() { CFlowStatParser *parser = new CFlowStatParser(); assert (parser); return parser; } -int CTRexExtendedDriverBaseVIC::set_rcv_all(CPhyEthIF * _if, bool set_on) { - //printf(" NOT supported yet \n"); - return 0; -} - ///////////////////////////////////////////////////////////////////////////////////// -- cgit 1.2.3-korg From 296951010f94dbadba90d06ee4f56e1b221afd67 Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Sun, 11 Dec 2016 15:31:28 +0200 Subject: mlx5 add RSS improve RX drop MPPS Signed-off-by: Hanoh Haim --- src/main_dpdk.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/main_dpdk.h | 3 ++ 2 files changed, 115 insertions(+), 10 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 6d78719f..6421b5c2 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -96,6 +96,7 @@ extern "C" { #define RTE_TEST_RX_DESC_DEFAULT 64 #define RTE_TEST_RX_LATENCY_DESC_DEFAULT (1*1024) +#define RTE_TEST_RX_DESC_DEFAULT_MLX 8 #define RTE_TEST_RX_DESC_VM_DEFAULT 512 #define RTE_TEST_TX_DESC_VM_DEFAULT 512 @@ -177,6 +178,15 @@ public: virtual bool drop_packets_incase_of_linkdown() { return (false); } + + /* Mellanox ConnectX-4 can drop only 35MPPS per Rx queue. to workaround this issue we will create multi rx queue and enable RSS. for Queue1 we will disable RSS + return zero for disable patch and rx queues number for enable + */ + + virtual uint16_t enable_rss_drop_workaround(void) { + return (0); + } + }; @@ -493,6 +503,10 @@ public: virtual CFlowStatParser *get_flow_stat_parser(); virtual int set_rcv_all(CPhyEthIF * _if, bool set_on); + virtual uint16_t enable_rss_drop_workaround(void) { + return (5); + } + private: virtual void add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, uint16_t ip_id, uint8_t l4_proto , int queue); @@ -3549,6 +3563,7 @@ int CGlobalTRex::ixgbe_start(void){ assert(CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); CPhyEthIF * _if=&m_ports[i]; _if->Create((uint8_t)i); + uint16_t rx_rss = get_ex_drv()->enable_rss_drop_workaround(); if ( get_vm_one_queue_enable() ) { /* VMXNET3 does claim to support 16K but somehow does not work */ @@ -3566,23 +3581,50 @@ int CGlobalTRex::ixgbe_start(void){ } else { // 2 rx queues. // TX queues: 1 for each core handling the port pair + 1 for latency pkts + 1 for use by RX core - _if->configure(2, m_cores_to_dual_ports + 2, &m_port_cfg.m_port_conf); + + uint16_t rx_queues; + + if (rx_rss==0) { + rx_queues=2; + }else{ + rx_queues=rx_rss; + } + + _if->configure(rx_queues, m_cores_to_dual_ports + 2, &m_port_cfg.m_port_conf); m_rx_core_tx_q_id = m_cores_to_dual_ports; - // setup RX drop queue - _if->rx_queue_setup(MAIN_DPDK_DATA_Q, - RTE_TEST_RX_DESC_DEFAULT, - socket_id, - &m_port_cfg.m_rx_conf, - CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); - // setup RX filter queue - _if->set_rx_queue(MAIN_DPDK_RX_Q); + if ( rx_rss ) { + int j=0; + for (j=0;jrx_queue_setup(j, + RTE_TEST_RX_DESC_DEFAULT_MLX, + socket_id, + &m_port_cfg.m_rx_conf, + CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); + + + } + }else{ + // setup RX drop queue + _if->rx_queue_setup(MAIN_DPDK_DATA_Q, + RTE_TEST_RX_DESC_DEFAULT, + socket_id, + &m_port_cfg.m_rx_conf, + CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_2048); + // setup RX filter queue + _if->set_rx_queue(MAIN_DPDK_RX_Q); + } + _if->rx_queue_setup(MAIN_DPDK_RX_Q, RTE_TEST_RX_LATENCY_DESC_DEFAULT, socket_id, &m_port_cfg.m_rx_conf, CGlobalInfo::m_mem_pool[socket_id].m_mbuf_pool_9k); - // setup TX queues + for (int qid = 0; qid < m_max_queues_per_port; qid++) { _if->tx_queue_setup((uint16_t)qid, RTE_TEST_TX_DESC_DEFAULT , @@ -3591,6 +3633,10 @@ int CGlobalTRex::ixgbe_start(void){ } } + if ( rx_rss ){ + _if->configure_rss_redirect_table(rx_rss,MAIN_DPDK_RX_Q); + } + _if->stats_clear(); _if->start(); _if->configure_rx_duplicate_rules(); @@ -4875,6 +4921,57 @@ int CGlobalTRex::start_master_statefull() { //////////////////////////////////////////// static CGlobalTRex g_trex; + +void CPhyEthIF::configure_rss_redirect_table(uint16_t numer_of_queues, + uint16_t skip_queue){ + + + struct rte_eth_dev_info dev_info; + + rte_eth_dev_info_get(m_port_id,&dev_info); + assert(dev_info.reta_size>0); + + int reta_conf_size = + std::max(1, dev_info.reta_size / RTE_RETA_GROUP_SIZE); + + struct rte_eth_rss_reta_entry64 reta_conf[reta_conf_size]; + + rte_eth_dev_rss_reta_query(m_port_id,&reta_conf[0],dev_info.reta_size); + + int i,j; + + for (j=0; jget_extended_stats(this, &m_stats); CRXCoreIgnoreStat ign_stats; @@ -6562,6 +6659,11 @@ void CTRexExtendedDriverBaseMlnx5G::update_configuration(port_cfg_t * cfg){ cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos=0x01; cfg->m_port_conf.fdir_conf.mask.ipv6_mask.proto=0xff; cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc=0x01; + + /* enable RSS */ + cfg->m_port_conf.rxmode.mq_mode =ETH_MQ_RX_RSS; + cfg->m_port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP; + } /* diff --git a/src/main_dpdk.h b/src/main_dpdk.h index 6402d106..25b19471 100644 --- a/src/main_dpdk.h +++ b/src/main_dpdk.h @@ -109,6 +109,9 @@ class CPhyEthIF { void dump_stats(FILE *fd); void set_ignore_stats_base(CPreTestStats &pre_stats); void update_counters(); + void configure_rss_redirect_table(uint16_t numer_of_queues, + uint16_t skip_queue); + void stats_clear(); uint8_t get_port_id(){ return (m_port_id); -- cgit 1.2.3-korg From 6c31c0534acf57fc3e0e26fe964bbc67d9d7d63c Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 12 Dec 2016 18:11:49 +0200 Subject: Added VIC tests + VIC small fix + fail tests if latency packets fail Signed-off-by: Ido Barnea --- scripts/automation/regression/setups/trex11/benchmark.yaml | 13 +++++++++++++ .../regression/stateful_tests/trex_general_test.py | 13 +++++++++++-- src/main_dpdk.cpp | 4 ++-- 3 files changed, 26 insertions(+), 4 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/scripts/automation/regression/setups/trex11/benchmark.yaml b/scripts/automation/regression/setups/trex11/benchmark.yaml index a4969d2d..5ebcdd55 100644 --- a/scripts/automation/regression/setups/trex11/benchmark.yaml +++ b/scripts/automation/regression/setups/trex11/benchmark.yaml @@ -40,6 +40,19 @@ test_rx_check_http: &rx_http rx_sample_rate : 128 bw_per_core : 49.464 +test_rx_check_http_ipv6: + << : *rx_http + bw_per_core : 49.237 + +test_rx_check_sfr: &rx_sfr + multiplier : 8 + cores : 1 + rx_sample_rate : 128 + bw_per_core : 20.9 + +test_rx_check_sfr_ipv6: + << : *rx_sfr + bw_per_core : 23.9 ### stateless ### diff --git a/scripts/automation/regression/stateful_tests/trex_general_test.py b/scripts/automation/regression/stateful_tests/trex_general_test.py index 1843af00..5c1649e7 100755 --- a/scripts/automation/regression/stateful_tests/trex_general_test.py +++ b/scripts/automation/regression/stateful_tests/trex_general_test.py @@ -257,7 +257,7 @@ class CTRexGeneral_Test(unittest.TestCase): allowed_latency = 1000 if max(trex_res.get_max_latency().values()) > allowed_latency: self.fail('LatencyError: Maximal latency exceeds %s (usec)' % allowed_latency) - + # check that avg latency does not exceed 1 msec if self.is_VM: allowed_latency = 9999999 @@ -266,6 +266,15 @@ class CTRexGeneral_Test(unittest.TestCase): if max(trex_res.get_avg_latency().values()) > allowed_latency: self.fail('LatencyError: Average latency exceeds %s (usec)' % allowed_latency) + ports_names = trex_res.get_last_value('trex-latecny-v2.data', 'port\-\d+') + if not ports_names: + raise AbnormalResultError('Could not find ports info in TRex results, path: trex-latecny-v2.data.port-*') + for port_name in ports_names: + path = 'trex-latecny-v2.data.%s.hist.cont' % port_name + lat_count = trex_res.get_last_value(path) + if lat_count == 0: + self.fail('LatencyError: Number of latency packets received on %s is 0' % port_name) + if not self.is_loopback: # check router number of drops --> deliberately masked- need to be figured out!!!!! pkt_drop_stats = self.router.get_drop_stats() @@ -359,7 +368,7 @@ class CTRexGeneral_Test(unittest.TestCase): print("Can't get TRex log:", e) if len(self.fail_reasons): sys.stdout.flush() - raise Exception('The test is failed, reasons:\n%s' % '\n'.join(self.fail_reasons)) + raise Exception('Test failed. Reasons:\n%s' % '\n'.join(self.fail_reasons)) sys.stdout.flush() def check_for_trex_crash(self): diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 6421b5c2..0086106a 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -6845,8 +6845,8 @@ void CTRexExtendedDriverBaseVIC::update_configuration(port_cfg_t * cfg){ cfg->m_tx_conf.tx_thresh.hthresh = TX_HTHRESH; cfg->m_tx_conf.tx_thresh.wthresh = TX_WTHRESH; cfg->m_port_conf.rxmode.max_rx_pkt_len =9*1000-10; - cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos = 0x0f; - cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc = 0x0f; + cfg->m_port_conf.fdir_conf.mask.ipv4_mask.tos = 0x01; + cfg->m_port_conf.fdir_conf.mask.ipv6_mask.tc = 0x01; } void CTRexExtendedDriverBaseVIC::add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type -- cgit 1.2.3-korg From 523b9dc5e4b2b8ee9abbe60175416b8a3c41f5e8 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 13 Dec 2016 15:56:23 +0200 Subject: Fix trex-257 - Could not count p:... printed to screen with IPv6 streams Signed-off-by: Ido Barnea --- src/main_dpdk.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 0086106a..68c2d34e 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -6455,11 +6455,11 @@ int CTRexExtendedDriverBase40G::configure_rx_filter_rules(CPhyEthIF * _if) { add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, 0 , FLOW_STAT_PAYLOAD_IP_ID, IPPROTO_ICMP, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID); add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, 0 - , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, 0); + , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID); add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_TCP, 0 - , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, 0); + , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID); add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, 0 - , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, 0); + , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID); rte_eth_fdir_stats_reset(_if->get_port_id(), NULL, FDIR_TEMP_HW_ID, 1); return 0; // Other rules are configured dynamically in stateless -- cgit 1.2.3-korg From dc546861c7e74b830a17e1bfe83252c67b70444f Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 13 Dec 2016 16:29:47 +0200 Subject: In stateful, print latency stats only if given -l != 0 Signed-off-by: Ido Barnea --- src/main_dpdk.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src/main_dpdk.cpp') diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 68c2d34e..3466572c 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4507,18 +4507,20 @@ CGlobalTRex::handle_slow_path() { m_mg.update(); if ( m_io_modes.m_g_mode == CTrexGlobalIoMode::gNORMAL ) { - switch (m_io_modes.m_l_mode) { - case CTrexGlobalIoMode::lDISABLE: - fprintf(stdout,"\n+Latency stats disabled \n"); - break; - case CTrexGlobalIoMode::lENABLE: - fprintf(stdout,"\n-Latency stats enabled \n"); - m_mg.DumpShort(stdout); - break; - case CTrexGlobalIoMode::lENABLE_Extended: - fprintf(stdout,"\n-Latency stats extended \n"); - m_mg.Dump(stdout); - break; + if (CGlobalInfo::m_options.m_latency_rate != 0) { + switch (m_io_modes.m_l_mode) { + case CTrexGlobalIoMode::lDISABLE: + fprintf(stdout, "\n+Latency stats disabled \n"); + break; + case CTrexGlobalIoMode::lENABLE: + fprintf(stdout, "\n-Latency stats enabled \n"); + m_mg.DumpShort(stdout); + break; + case CTrexGlobalIoMode::lENABLE_Extended: + fprintf(stdout, "\n-Latency stats extended \n"); + m_mg.Dump(stdout); + break; + } } if ( get_is_rx_check_mode() ) { -- cgit 1.2.3-korg