summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2017-01-08 17:14:32 +0200
committerIdo Barnea <ibarnea@cisco.com>2017-01-09 15:19:00 +0200
commite532c2a19bd6afeaccb0b3eafebed3c5e758b339 (patch)
tree277f5347c9870f72e881e807744b3813a5968d4e
parent335131c1d13f80caf1dd326758e154317283c780 (diff)
Support for ixgbevf and i40evf
Signed-off-by: Ido Barnea <ibarnea@cisco.com>
-rwxr-xr-xlinux_dpdk/ws_main.py2
-rw-r--r--src/debug.cpp8
-rw-r--r--src/dpdk/drivers/net/i40e/i40e_rxtx.c49
-rw-r--r--src/main_dpdk.cpp126
-rw-r--r--src/stateless/rx/trex_stateless_rx_port_mngr.cpp3
5 files changed, 94 insertions, 94 deletions
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index f3e25605..29588622 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -432,7 +432,7 @@ dpdk_src = SrcGroup(dir='src/dpdk/',
'drivers/net/i40e/base/i40e_hmc.c',
'drivers/net/i40e/base/i40e_lan_hmc.c',
'drivers/net/i40e/base/i40e_nvm.c',
-# 'drivers/net/i40e/i40e_ethdev_vf.c',
+ 'drivers/net/i40e/i40e_ethdev_vf.c',
'drivers/net/i40e/i40e_pf.c',
'drivers/net/i40e/i40e_rxtx.c',
'drivers/net/i40e/i40e_rxtx_vec.c',
diff --git a/src/debug.cpp b/src/debug.cpp
index 3e35a862..4abd05a0 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -398,7 +398,13 @@ int CTrexDebug::verify_hw_rules(bool recv_all) {
memset(pkt_per_q, 0, sizeof(pkt_per_q));
// We don't know which interfaces connected where, so sum all queue 1 and all queue 0
for (int port = 0; port < m_max_ports; port++) {
- for(int queue_id = 0; queue_id <= 1; queue_id++) {
+ int max_q;
+ if (CGlobalInfo::m_options.preview.get_vm_one_queue_enable()) {
+ max_q = 0;
+ } else {
+ max_q = 1;
+ }
+ for(int queue_id = 0; queue_id <= max_q; queue_id++) {
lp = &m_ports[port];
uint16_t cnt = lp->rx_burst(queue_id, rx_pkts, 32);
pkt_per_q[queue_id] += cnt;
diff --git a/src/dpdk/drivers/net/i40e/i40e_rxtx.c b/src/dpdk/drivers/net/i40e/i40e_rxtx.c
index 8fdf30c6..19b431c3 100644
--- a/src/dpdk/drivers/net/i40e/i40e_rxtx.c
+++ b/src/dpdk/drivers/net/i40e/i40e_rxtx.c
@@ -2161,10 +2161,18 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
uint16_t base, bsf, tc_mapping;
int use_def_burst_func = 1;
+#define TREX_PATCH_LOW_LATENCY
+#ifdef TREX_PATCH_LOW_LATENCY
+ int is_vf = 0;
+#endif
+
if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
struct i40e_vf *vf =
I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
vsi = &vf->vsi;
+#ifdef TREX_PATCH_LOW_LATENCY
+ is_vf = 1;
+#endif
} else {
vsi = i40e_pf_get_vsi_by_qindex(pf, queue_idx);
}
@@ -2272,10 +2280,11 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
ad->rx_bulk_alloc_allowed = false;
}
-#define TREX_PATCH_LOW_LATENCY
#ifdef TREX_PATCH_LOW_LATENCY
- rxq->dcb_tc =0;
-#else
+ if (! is_vf)
+ rxq->dcb_tc =0;
+ else // The entire for below is in the else
+#endif
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (!(vsi->enabled_tc & (1 << i)))
@@ -2289,7 +2298,6 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
if (queue_idx >= base && queue_idx < (base + BIT(bsf)))
rxq->dcb_tc = i;
}
-#endif
return 0;
}
@@ -2385,20 +2393,25 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
uint16_t tx_rs_thresh, tx_free_thresh;
uint16_t i, base, bsf, tc_mapping;
+#ifdef TREX_PATCH_LOW_LATENCY
+ u8 low_latency = 0;
+ int is_vf = 1;
+#endif
+
if (hw->mac.type == I40E_MAC_VF || hw->mac.type == I40E_MAC_X722_VF) {
struct i40e_vf *vf =
I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
vsi = &vf->vsi;
} else {
vsi = i40e_pf_get_vsi_by_qindex(pf, queue_idx);
- }
-
#ifdef TREX_PATCH_LOW_LATENCY
- u8 low_latency = 0;
- if (queue_idx == pf->dev_data->nb_tx_queues-1) {
- low_latency = 1;
- }
+ if (queue_idx == pf->dev_data->nb_tx_queues-1) {
+ low_latency = 1;
+ }
+ is_vf = 0;
#endif
+ }
+
if (vsi == NULL) {
PMD_DRV_LOG(ERR, "VSI is NULL, or queue index (%u) "
@@ -2555,12 +2568,14 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
i40e_set_tx_function_flag(dev, txq);
#ifdef TREX_PATCH_LOW_LATENCY
- if (low_latency) {
- txq->dcb_tc=1;
- }else{
- txq->dcb_tc=0;
- }
-#else
+ if (! is_vf) {
+ if (low_latency) {
+ txq->dcb_tc=1;
+ }else{
+ txq->dcb_tc=0;
+ }
+ } else // The entire for below is in the else
+#endif
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (!(vsi->enabled_tc & (1 << i)))
continue;
@@ -2573,7 +2588,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
if (queue_idx >= base && queue_idx < (base + BIT(bsf)))
txq->dcb_tc = i;
}
-#endif
+
return 0;
}
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 5c78013b..3149bdb3 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -288,6 +288,27 @@ public:
virtual int set_rcv_all(CPhyEthIF * _if, bool set_on) {return 0;}
};
+class CTRexExtendedDriverVf : public CTRexExtendedDriverBase1GVm {
+
+public:
+ CTRexExtendedDriverVf(){
+ /* we are working in mode in which we have we have 1 queue for rx and one queue for tx*/
+ CGlobalInfo::m_options.preview.set_vm_one_queue_enable(true);
+ }
+ virtual void get_extended_stats(CPhyEthIF * _if, CPhyEthIFStats *stats) {
+ uint64_t prev_ipackets = stats->ipackets;
+ uint64_t prev_opackets = stats->opackets;
+
+ CTRexExtendedDriverBase1GVm::get_extended_stats(_if, stats);
+ // Since this driver report byte counts without Ethernet FCS (4 bytes), we need to fix the reported numbers
+ stats->ibytes += (stats->ipackets - prev_ipackets) * 4;
+ stats->obytes += (stats->opackets - prev_opackets) * 4;
+ }
+ static CTRexExtendedDriverBase * create(){
+ return ( new CTRexExtendedDriverVf() );
+ }
+};
+
class CTRexExtendedDriverBaseE1000 : public CTRexExtendedDriverBase1GVm {
CTRexExtendedDriverBaseE1000() {
// E1000 driver is only relevant in VM in our case
@@ -571,14 +592,12 @@ private:
register_driver(std::string("rte_enic_pmd"),CTRexExtendedDriverBaseVIC::create);
register_driver(std::string("net_mlx5"),CTRexExtendedDriverBaseMlnx5G::create);
-
/* virtual devices */
register_driver(std::string("rte_em_pmd"),CTRexExtendedDriverBaseE1000::create);
register_driver(std::string("rte_vmxnet3_pmd"),CTRexExtendedDriverBase1GVm::create);
register_driver(std::string("rte_virtio_pmd"),CTRexExtendedDriverBase1GVm::create);
-
-
-
+ register_driver(std::string("rte_ixgbevf_pmd"),CTRexExtendedDriverVf::create);
+ register_driver(std::string("rte_i40evf_pmd"),CTRexExtendedDriverVf::create);
m_driver_was_set=false;
m_drv=0;
@@ -1801,7 +1820,15 @@ int DpdkTRexPortAttr::add_mac(char * mac){
for (int i=0; i<6;i++) {
mac_addr.addr_bytes[i] =mac[i];
}
- return rte_eth_dev_mac_addr_add(m_port_id, &mac_addr,0);
+
+ if ( ! get_vm_one_queue_enable() ) {
+ if ( rte_eth_dev_mac_addr_add(m_port_id, &mac_addr,0) != 0) {
+ printf("Failed setting MAC for port %d \n", m_port_id);
+ exit(-1);
+ }
+ }
+
+ return 0;
}
int DpdkTRexPortAttr::set_promiscuous(bool enable){
@@ -2171,6 +2198,18 @@ int CCoreEthIF::send_burst(CCorePerPort * lp_port,
uint16_t len,
CVirtualIFPerSideStats * lp_stats){
+#ifdef DEBUG_SEND_BURST
+ if (CGlobalInfo::m_options.preview.getVMode() > 10) {
+ fprintf(stdout, "send_burst port:%d queue:%d len:%d\n", lp_port->m_port->get_rte_port_id()
+ , lp_port->m_tx_queue_id, len);
+ for (int i = 0; i < lp_port->m_len; i++) {
+ fprintf(stdout, "packet %d:\n", i);
+ rte_mbuf_t *m = lp_port->m_table[i];
+ utl_DumpBuffer(stdout, rte_pktmbuf_mtod(m, uint8_t*), rte_pktmbuf_pkt_len(m), 0);
+ }
+ }
+#endif
+
uint16_t ret = lp_port->m_port->tx_burst(lp_port->m_tx_queue_id,lp_port->m_table,len);
#ifdef DELAY_IF_NEEDED
while ( unlikely( ret<len ) ){
@@ -3928,21 +3967,22 @@ int CGlobalTRex::ixgbe_prob_init(void){
m_max_ports = rte_eth_dev_count();
if (m_max_ports == 0)
- rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
+ rte_exit(EXIT_FAILURE, "Error: Could not find supported ethernet ports. You are probably trying to use unsupported NIC \n");
printf(" Number of ports found: %d \n",m_max_ports);
if ( m_max_ports %2 !=0 ) {
- rte_exit(EXIT_FAILURE, " Number of ports %d should be even, mask the one port in the configuration file \n, ",
+ rte_exit(EXIT_FAILURE, " Number of ports in config file is %d. It should be even. Please use --limit-ports, or change 'port_limit:' in the config file\n",
m_max_ports);
}
if ( CGlobalInfo::m_options.get_expected_ports() > TREX_MAX_PORTS ) {
- rte_exit(EXIT_FAILURE, " Maximum ports supported are %d, use the configuration file to set the expected number of ports \n",TREX_MAX_PORTS);
+ rte_exit(EXIT_FAILURE, " Maximum number of ports supported is %d. You are trying to use %d. Please use --limit-ports, or change 'port_limit:' in the config file\n"
+ ,TREX_MAX_PORTS, CGlobalInfo::m_options.get_expected_ports());
}
if ( CGlobalInfo::m_options.get_expected_ports() > m_max_ports ){
- rte_exit(EXIT_FAILURE, " There are %d ports you expected more %d,use the configuration file to set the expected number of ports \n",
+ rte_exit(EXIT_FAILURE, " There are %d ports available. You are trying to use %d. Please use --limit-ports, or change 'port_limit:' in the config file\n",
m_max_ports,
CGlobalInfo::m_options.get_expected_ports());
}
@@ -5218,70 +5258,6 @@ int CPhyEthIF::get_flow_stats_payload(rx_per_flow_t *rx_stats, tx_per_flow_t *tx
return 0;
}
-// If needed, send packets to rx core for processing.
-// This is relevant only in VM case, where we receive packets to the working DP core (only 1 DP core in this case)
-bool CCoreEthIF::process_rx_pkt(pkt_dir_t dir, rte_mbuf_t * m) {
- CFlowStatParser parser;
- uint32_t ip_id;
-
- if (parser.parse(rte_pktmbuf_mtod(m, uint8_t*), rte_pktmbuf_pkt_len(m)) != 0) {
- return false;
- }
- bool send=false;
-
- // e1000 on ESXI hands us the packet with the ethernet FCS
- if (parser.get_pkt_size() < rte_pktmbuf_pkt_len(m)) {
- rte_pktmbuf_trim(m, rte_pktmbuf_pkt_len(m) - parser.get_pkt_size());
- }
-
- if ( get_is_stateless() ) {
- // In stateless RX, we only care about flow stat packets
- if ((parser.get_ip_id(ip_id) == 0) && ((ip_id & 0xff00) == IP_ID_RESERVE_BASE)) {
- send = true;
- }
- } else {
- CLatencyPktMode *c_l_pkt_mode = g_trex.m_mg.c_l_pkt_mode;
- bool is_lateancy_pkt = c_l_pkt_mode->IsLatencyPkt((IPHeader *)parser.get_l4()) &
- CCPortLatency::IsLatencyPkt(parser.get_l4() + c_l_pkt_mode->l4_header_len());
-
- if (is_lateancy_pkt) {
- send = true;
- } else {
- if ( get_is_rx_filter_enable() ) {
- uint8_t max_ttl = 0xff - get_rx_check_hops();
- uint8_t pkt_ttl = parser.get_ttl();
- if ( (pkt_ttl==max_ttl) || (pkt_ttl==(max_ttl-1) ) ) {
- send=true;
- }
- }
- }
- }
-
-
- if (send) {
- CGenNodeLatencyPktInfo * node=(CGenNodeLatencyPktInfo * )CGlobalInfo::create_node();
- if ( node ) {
- node->m_msg_type = CGenNodeMsgBase::LATENCY_PKT;
- node->m_dir = dir;
- node->m_latency_offset = 0xdead;
- node->m_pkt = m;
- if ( m_ring_to_rx->Enqueue((CGenNode*)node)==0 ){
- }else{
- CGlobalInfo::free_node((CGenNode *)node);
- send=false;
- }
-
-#ifdef LATENCY_QUEUE_TRACE_
- printf("rx to cp --\n");
- rte_pktmbuf_dump(stdout,m, rte_pktmbuf_pkt_len(m));
-#endif
- }else{
- send=false;
- }
- }
- return (send);
-}
-
TrexStateless * get_stateless_obj() {
return g_trex.m_trex_stateless;
}
@@ -6677,8 +6653,8 @@ void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFSta
stats->ipackets += stats1.ipackets - prev_stats->ipackets;
stats->ibytes += stats1.ibytes - prev_stats->ibytes;
stats->opackets += stats1.opackets - prev_stats->opackets;
- stats->obytes += stats1.obytes - prev_stats->obytes
- + (stats1.opackets << 2) - (prev_stats->opackets << 2);
+ // Since this driver report obytes count without Ethernet FCS (4 bytes), we need to fix the reported numbers
+ stats->obytes += stats1.obytes - prev_stats->obytes + (stats1.opackets - prev_stats->opackets) * 4;
stats->f_ipackets += 0;
stats->f_ibytes += 0;
stats->ierrors += stats1.imissed + stats1.ierrors + stats1.rx_nombuf
diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
index e16b3d0c..caed2bee 100644
--- a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
+++ b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp
@@ -461,6 +461,9 @@ public:
m_icmp = NULL;
m_vlan_tag = 0;
+ if (m_size_left < 14)
+ return;
+
/* ethernet */
m_ether = (EthernetHeader *)parse_bytes(14);