From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id C4AB31288 for ; Tue, 9 Jun 2015 06:07:14 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 08 Jun 2015 21:07:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,577,1427785200"; d="scan'208";a="743390352" Received: from kmsmsx151.gar.corp.intel.com ([172.21.73.86]) by orsmga002.jf.intel.com with ESMTP; 08 Jun 2015 21:07:12 -0700 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by KMSMSX151.gar.corp.intel.com (172.21.73.86) with Microsoft SMTP Server (TLS) id 14.3.224.2; Tue, 9 Jun 2015 12:06:59 +0800 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.94]) by SHSMSX101.ccr.corp.intel.com ([10.239.4.153]) with mapi id 14.03.0224.002; Tue, 9 Jun 2015 12:06:58 +0800 From: "Wu, Jingjing" To: "Wodkowski, PawelX" , "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH v4 4/7] move rte_eth_dev_check_mq_mode() logic to driver Thread-Index: AQHQTF9IQijE+U5+VEKJvPTNPYCGSp2kMyvA Date: Tue, 9 Jun 2015 04:06:57 +0000 Message-ID: <9BB6961774997848B5B42BEC655768F8C3E96B@SHSMSX104.ccr.corp.intel.com> References: <1421672551-11652-1-git-send-email-pawelx.wodkowski@intel.com> <1424361289-30718-1-git-send-email-pawelx.wodkowski@intel.com> <1424361289-30718-5-git-send-email-pawelx.wodkowski@intel.com> In-Reply-To: <1424361289-30718-5-git-send-email-pawelx.wodkowski@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v4 4/7] move rte_eth_dev_check_mq_mode() logic to driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Jun 2015 04:07:15 -0000 > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Pawel Wodkowski > Sent: Thursday, February 19, 2015 11:55 PM > To: dev@dpdk.org > Subject: [dpdk-dev] [PATCH v4 4/7] move rte_eth_dev_check_mq_mode() > logic to driver >=20 > Function rte_eth_dev_check_mq_mode() is driver specific. It should be > done in PF configuration phase. This patch move igb/ixgbe driver specific= mq > check and SRIOV configuration code to driver part. Also rewriting log > messages to be shorter and more descriptive. >=20 > Signed-off-by: Pawel Wodkowski > --- > lib/librte_ether/rte_ethdev.c | 197 ------------------------------= ----- > lib/librte_pmd_e1000/igb_ethdev.c | 43 ++++++++ > lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 105 ++++++++++++++++++- > lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 5 +- > lib/librte_pmd_ixgbe/ixgbe_pf.c | 202 > +++++++++++++++++++++++++++++++----- > 5 files changed, 327 insertions(+), 225 deletions(-) >=20 > diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c > b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c > index 02b9cda..8e9da3b 100644 > --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c > +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c > @@ -863,7 +863,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct > eth_driver *eth_drv, > "Failed to allocate %u bytes needed to store " > "MAC addresses", > ETHER_ADDR_LEN * hw->mac.num_rar_entries); > - return -ENOMEM; > + diag =3D -ENOMEM; > + goto error; > } > /* Copy the permanent MAC address */ > ether_addr_copy((struct ether_addr *) hw->mac.perm_addr, @@ - > 876,7 +877,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct > eth_driver *eth_drv, > PMD_INIT_LOG(ERR, > "Failed to allocate %d bytes needed to store MAC > addresses", > ETHER_ADDR_LEN * IXGBE_VMDQ_NUM_UC_MAC); > - return -ENOMEM; > + diag =3D -ENOMEM; > + goto error; > } >=20 > /* initialize the vfta */ > @@ -886,7 +888,13 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct > eth_driver *eth_drv, > memset(hwstrip, 0, sizeof(*hwstrip)); >=20 > /* initialize PF if max_vfs not zero */ > - ixgbe_pf_host_init(eth_dev); > + diag =3D ixgbe_pf_host_init(eth_dev); > + if (diag < 0) { > + PMD_INIT_LOG(ERR, > + "Failed to allocate %d bytes needed to store MAC > addresses", > + ETHER_ADDR_LEN * IXGBE_VMDQ_NUM_UC_MAC); > + goto error; > + } >=20 > ctrl_ext =3D IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); > /* let hardware know driver is loaded */ @@ -918,6 +926,11 @@ > eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, > ixgbe_enable_intr(eth_dev); >=20 > return 0; > + > +error: > + rte_free(eth_dev->data->hash_mac_addrs); > + rte_free(eth_dev->data->mac_addrs); > + return diag; > } >=20 >=20 > @@ -1434,7 +1447,93 @@ ixgbe_dev_configure(struct rte_eth_dev *dev) > struct ixgbe_interrupt *intr =3D > IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private); >=20 > + struct rte_eth_conf *dev_conf =3D &dev->data->dev_conf; > + struct rte_eth_dev_info dev_info; > + int retval; > + > PMD_INIT_FUNC_TRACE(); > + retval =3D ixgbe_pf_configure_mq_sriov(dev); > + if (retval <=3D 0) > + return retval; > + > + uint16_t nb_rx_q =3D dev->data->nb_rx_queues; > + uint16_t nb_tx_q =3D dev->data->nb_rx_queues; > + > + /* For DCB we need to obtain maximum number of queues > dinamically, > + * as this depends on max VF exported in PF. */ > + if ((dev_conf->rxmode.mq_mode =3D=3D ETH_MQ_RX_DCB) || > + (dev_conf->txmode.mq_mode =3D=3D ETH_MQ_TX_DCB)) { > + /* Use dev_infos_get field as this might be pointer to PF or > VF. */ > + (*dev->dev_ops->dev_infos_get)(dev, &dev_info); Why not call ixgbe_dev_info_get directly? And it looks only max_rx_queues a= nd max_tx_queues are used below, maybe hw->mac.max_rx_queues and hw->mac.max_tx_queues can b= e used below instead of calling a function. > + } > + > + /* For vmdq+dcb mode check our configuration before we go further > */ > + if (dev_conf->rxmode.mq_mode =3D=3D ETH_MQ_RX_VMDQ_DCB) { > + const struct rte_eth_vmdq_dcb_conf *conf; > + > + if (nb_rx_q !=3D ETH_VMDQ_DCB_NUM_QUEUES) { > + PMD_INIT_LOG(ERR, " VMDQ+DCB, > nb_rx_q !=3D %d\n", > + ETH_VMDQ_DCB_NUM_QUEUES); > + return (-EINVAL); > + } > + conf =3D &(dev_conf->rx_adv_conf.vmdq_dcb_conf); > + if (conf->nb_queue_pools !=3D ETH_16_POOLS && > + conf->nb_queue_pools !=3D ETH_32_POOLS) { > + PMD_INIT_LOG(ERR, " VMDQ+DCB selected, " > + "number of RX queue pools must > be %d or %d\n", > + ETH_16_POOLS, ETH_32_POOLS); > + return (-EINVAL); > + } > + } else if (dev_conf->rxmode.mq_mode =3D=3D ETH_MQ_RX_DCB) { > + /* For DCB mode check out configuration before we go > further */ > + const struct rte_eth_dcb_rx_conf *conf; > + > + if (nb_rx_q !=3D dev_info.max_rx_queues) { > + PMD_INIT_LOG(ERR, " DCB, number of RX > queues !=3D %d\n", > + ETH_DCB_NUM_QUEUES); The check is using dev_info.max_rx_queues, while ETH_DCB_NUM_QUEUES in log. > + return (-EINVAL); > + } > + conf =3D &(dev_conf->rx_adv_conf.dcb_rx_conf); > + if (conf->nb_tcs !=3D ETH_4_TCS && > + conf->nb_tcs !=3D ETH_8_TCS) { > + PMD_INIT_LOG(ERR, " DCB, number of RX TC must > be %d or %d\n", > + ETH_4_TCS, ETH_8_TCS); > + return (-EINVAL); > + } > + } > + > + if (dev_conf->txmode.mq_mode =3D=3D ETH_MQ_TX_VMDQ_DCB) { > + const struct rte_eth_vmdq_dcb_tx_conf *conf; > + > + if (nb_tx_q !=3D ETH_VMDQ_DCB_NUM_QUEUES) { > + PMD_INIT_LOG(ERR, " VMDQ+DCB, number of TX > queues !=3D %d\n", > + ETH_VMDQ_DCB_NUM_QUEUES); > + return (-EINVAL); > + } > + conf =3D &(dev_conf->tx_adv_conf.vmdq_dcb_tx_conf); > + if (conf->nb_queue_pools !=3D ETH_16_POOLS && > + conf->nb_queue_pools !=3D ETH_32_POOLS) { > + PMD_INIT_LOG(ERR, " VMDQ+DCB selected, " > + "number of TX qqueue pools must Typo: qqueue->queue > be %d or %d\n", > + ETH_16_POOLS, ETH_32_POOLS); > + return (-EINVAL); > + } > + } else if (dev_conf->txmode.mq_mode =3D=3D ETH_MQ_TX_DCB) { > + const struct rte_eth_dcb_tx_conf *conf; > + > + if (nb_tx_q !=3D dev_info.max_tx_queues) { > + PMD_INIT_LOG(ERR, " DCB, number of queues must > be %d\n", > + ETH_DCB_NUM_QUEUES); The check is using dev_info.max_rx_queues, while ETH_DCB_NUM_QUEUES in log. > + return (-EINVAL); > + } > + conf =3D &(dev_conf->tx_adv_conf.dcb_tx_conf); > + if (conf->nb_tcs !=3D ETH_4_TCS && > + conf->nb_tcs !=3D ETH_8_TCS) { > + PMD_INIT_LOG(ERR, " DCB, number of TX TC must > be %d or %d\n", > + ETH_4_TCS, ETH_8_TCS); > + return (-EINVAL); > + } > + } >=20 > /* set flag to update link status after init */ > intr->flags |=3D IXGBE_FLAG_NEED_LINK_UPDATE; diff --git > a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h > b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h > index 1383194..e70a6e8 100644 > --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h > +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h > @@ -348,11 +348,14 @@ void ixgbe_vlan_hw_strip_enable_all(struct > rte_eth_dev *dev); >=20 > void ixgbe_vlan_hw_strip_disable_all(struct rte_eth_dev *dev); >=20 > -void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev); > +int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev); >=20 > void ixgbe_pf_mbx_process(struct rte_eth_dev *eth_dev); >=20 > +int ixgbe_pf_configure_mq_sriov(struct rte_eth_dev *dev); > + > int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev); >=20 > uint32_t ixgbe_convert_vm_rx_mask_to_val(uint16_t rx_mask, uint32_t > orig_val); > + > #endif /* _IXGBE_ETHDEV_H_ */ > diff --git a/lib/librte_pmd_ixgbe/ixgbe_pf.c > b/lib/librte_pmd_ixgbe/ixgbe_pf.c index 4103e97..a7b9333 100644 > --- a/lib/librte_pmd_ixgbe/ixgbe_pf.c > +++ b/lib/librte_pmd_ixgbe/ixgbe_pf.c > @@ -91,7 +91,7 @@ ixgbe_mb_intr_setup(struct rte_eth_dev *dev) > return 0; > } >=20 > -void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev) > +int ixgbe_pf_host_init(struct rte_eth_dev *eth_dev) > { > struct ixgbe_vf_info **vfinfo =3D > IXGBE_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data- > >dev_private); > @@ -101,39 +101,31 @@ void ixgbe_pf_host_init(struct rte_eth_dev > *eth_dev) > IXGBE_DEV_PRIVATE_TO_UTA(eth_dev->data->dev_private); > struct ixgbe_hw *hw =3D > IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); > + int retval; > uint16_t vf_num; > - uint8_t nb_queue; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > - RTE_ETH_DEV_SRIOV(eth_dev).active =3D 0; > - if (0 =3D=3D (vf_num =3D dev_num_vf(eth_dev))) > - return; > + /* Fill sriov structure using default configuration. */ > + retval =3D ixgbe_pf_configure_mq_sriov(eth_dev); > + if (retval !=3D 0) { > + if (retval < 0) > + PMD_INIT_LOG(ERR, " Setting up SRIOV with default > device " > + "configuration should not fail. This is a > BUG."); > + return 0; > + } >=20 > + vf_num =3D dev_num_vf(eth_dev); > *vfinfo =3D rte_zmalloc("vf_info", sizeof(struct ixgbe_vf_info) * > vf_num, 0); > - if (*vfinfo =3D=3D NULL) > - rte_panic("Cannot allocate memory for private VF data\n"); > + if (*vfinfo =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Cannot allocate memory for private VF > data."); > + return (-ENOMEM); > + } >=20 > memset(mirror_info,0,sizeof(struct ixgbe_mirror_info)); > memset(uta_info,0,sizeof(struct ixgbe_uta_info)); > hw->mac.mc_filter_type =3D 0; >=20 > - if (vf_num >=3D ETH_32_POOLS) { > - nb_queue =3D 2; > - RTE_ETH_DEV_SRIOV(eth_dev).active =3D ETH_64_POOLS; > - } else if (vf_num >=3D ETH_16_POOLS) { > - nb_queue =3D 4; > - RTE_ETH_DEV_SRIOV(eth_dev).active =3D ETH_32_POOLS; > - } else { > - nb_queue =3D 8; > - RTE_ETH_DEV_SRIOV(eth_dev).active =3D ETH_16_POOLS; > - } > - > - RTE_ETH_DEV_SRIOV(eth_dev).nb_rx_q_per_pool =3D nb_queue; > - RTE_ETH_DEV_SRIOV(eth_dev).nb_tx_q_per_pool =3D nb_queue; > - RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx =3D vf_num; > - RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx =3D > (uint16_t)(vf_num * nb_queue); > - > ixgbe_vf_perm_addr_gen(eth_dev, vf_num); >=20 > /* init_mailbox_params */ > @@ -142,7 +134,169 @@ void ixgbe_pf_host_init(struct rte_eth_dev > *eth_dev) > /* set mb interrupt mask */ > ixgbe_mb_intr_setup(eth_dev); >=20 > - return; > + return 0; > +} > + > + > +/* > + * Function that make SRIOV configuration, based on device > +configuration, > + * number of requested queues and number of VF created. > + * Function returns: > + * 1 - SRIOV is not enabled (no VF created) > + * 0 - proper SRIOV configuration found. > + * -EINVAL - no suitable SRIOV configuration found. > + */ > +int > +ixgbe_pf_configure_mq_sriov(struct rte_eth_dev *dev) { If this function is called by ixgbe_pf_host_init. It is in the initializati= on process, the dev_conf in data is meaningless. The following check is still necessary? Ma= ybe it's better to use different functions in configure and init phase. > + struct rte_eth_conf *dev_conf =3D &dev->data->dev_conf; > + struct rte_eth_dev_sriov *sriov =3D &RTE_ETH_DEV_SRIOV(dev); > + uint16_t vf_num; > + > + vf_num =3D dev_num_vf(dev); > + if (vf_num =3D=3D 0) { > + memset(sriov, 0, sizeof(*sriov)); > + return 1; > + } > + > + /* Check multi-queue mode. */ > + if ((dev_conf->rxmode.mq_mode =3D=3D ETH_MQ_RX_DCB) || > + (dev_conf->rxmode.mq_mode =3D=3D ETH_MQ_RX_DCB_RSS) > || > + (dev_conf->txmode.mq_mode =3D=3D ETH_MQ_TX_DCB)) { > + /* SRIOV only works in VMDq enable mode */ > + PMD_INIT_LOG(ERR, " SRIOV active, " > + "invlaid VMDQ rx mode (%u) or tx (%u) > mode.", > + dev_conf->rxmode.mq_mode, dev_conf- > >txmode.mq_mode); > + return (-EINVAL); > + } > + > + switch (dev_conf->rxmode.mq_mode) { > + case ETH_MQ_RX_VMDQ_DCB: > + if (vf_num <=3D ETH_16_POOLS) > + sriov->nb_rx_q_per_pool =3D 8; > + else if (vf_num <=3D ETH_32_POOLS) > + sriov->nb_rx_q_per_pool =3D 4; > + else { > + PMD_INIT_LOG(ERR, > + "DCB (SRIOV active) - VF count (%d) must be > less or equal 32.", > + vf_num); > + return (-EINVAL); > + } > + > + if (dev->data->nb_rx_queues < sriov->nb_rx_q_per_pool) { > + PMD_INIT_LOG(WARNING, > + "DCB (SRIOV active) rx queues (%d) count is > not equal %d.", > + dev->data->nb_rx_queues, > + sriov->nb_rx_q_per_pool); > + } > + break; > + case ETH_MQ_RX_RSS: > + PMD_INIT_LOG(INFO, "RSS (SRIOV active), " > + "rx mq mode is changed from: mq_mode %u > into VMDQ mq_mode %u.", > + dev_conf->rxmode.mq_mode, dev->data- > >dev_conf.rxmode.mq_mode); > + dev->data->dev_conf.rxmode.mq_mode =3D > ETH_MQ_RX_VMDQ_RSS; > + /* falltrought */ > + case ETH_MQ_RX_VMDQ_RSS: > + if (vf_num >=3D ETH_64_POOLS) { > + /* FIXME: Is vf_num > 64 realy supported by > hardware? */ > + PMD_INIT_LOG(ERR, "RSS (SRIOV active), " > + "VFs num must be less or equal 64."); > + return (-EINVAL); > + } else if (vf_num >=3D ETH_32_POOLS) { > + if (dev->data->nb_rx_queues !=3D 1 && dev->data- > >nb_rx_queues !=3D 2) { > + PMD_INIT_LOG(ERR, "RSS (SRIOV active, VF > count >=3D 32)," > + "invalid rx queues count %d. > It must be 1 or 2.", > + dev->data->nb_rx_queues); > + return (-EINVAL); > + } > + > + sriov->nb_rx_q_per_pool =3D dev->data- > >nb_rx_queues; > + } else { > + /* FIXME: is VT(16) + RSS realy supported? */ > + if (dev->data->nb_rx_queues !=3D 4) { > + PMD_INIT_LOG(ERR, "RSS (SRIOV active, VFs > count < 32), " > + "invalid rx queues count %d. > It must be 4.", > + dev->data->nb_rx_queues); > + return (-EINVAL); > + } > + > + sriov->nb_rx_q_per_pool =3D 4; > + } > + break; > + default: /* ETH_MQ_RX_VMDQ_ONLY or ETH_MQ_RX_NONE */ > + /* if nothing mq mode configure, use default scheme */ > + if (dev->data->dev_conf.rxmode.mq_mode !=3D > ETH_MQ_RX_VMDQ_ONLY) { > + PMD_INIT_LOG(INFO, "Rx mq mode changed > from %u into VMDQ %u.", > + dev->data- > >dev_conf.rxmode.mq_mode, ETH_MQ_RX_VMDQ_ONLY); > + > + dev->data->dev_conf.rxmode.mq_mode =3D > ETH_MQ_RX_VMDQ_ONLY; > + } > + > + /* queue 0 of each pool is used. */ > + sriov->nb_rx_q_per_pool =3D 1; > + break; > + } > + > + switch (dev_conf->txmode.mq_mode) { > + case ETH_MQ_TX_VMDQ_DCB: /* DCB VMDQ in SRIOV mode*/ > + if (vf_num <=3D ETH_16_POOLS) > + sriov->nb_tx_q_per_pool =3D 8; > + else if (vf_num <=3D ETH_32_POOLS) > + sriov->nb_tx_q_per_pool =3D 4; > + else if (vf_num <=3D ETH_64_POOLS) > + sriov->nb_tx_q_per_pool =3D 1; > + else { > + PMD_INIT_LOG(ERR, "DCB (SRIOV active), " > + "VF count (%d) must be less or equal > 64.", > + vf_num); > + return (-EINVAL); > + } > + break; > + default: /* ETH_MQ_TX_VMDQ_ONLY or ETH_MQ_TX_NONE */ > + /* if nothing mq mode configure, use default scheme */ > + if (dev->data->dev_conf.txmode.mq_mode !=3D > ETH_MQ_TX_VMDQ_ONLY) { > + PMD_INIT_LOG(INFO, "Tx mq mode is changed > from %u into VMDQ %u.", > + dev->data- > >dev_conf.txmode.mq_mode, ETH_MQ_TX_VMDQ_ONLY); > + > + dev->data->dev_conf.txmode.mq_mode =3D > ETH_MQ_TX_VMDQ_ONLY; > + } > + > + /* queue 0 of each pool is used. */ > + sriov->nb_tx_q_per_pool =3D 1; > + break; > + } > + > + sriov->def_vmdq_idx =3D vf_num; > + > + /* > + * Pools starts at 2xN, 4xN or 8xN > + */ > + if (vf_num >=3D ETH_32_POOLS) { > + /* This must be vf_num <=3D ETH_64_POOLS */ > + sriov->active =3D ETH_64_POOLS; > + sriov->def_pool_q_idx =3D vf_num * 2; > + } else if (vf_num >=3D ETH_16_POOLS) { > + sriov->active =3D ETH_32_POOLS; > + sriov->def_pool_q_idx =3D vf_num * 4; > + } else { > + sriov->active =3D ETH_16_POOLS; > + sriov->def_pool_q_idx =3D vf_num * 8; > + } > + > + /* Check if available queus count is not less than allocated.*/ > + if (dev->data->nb_rx_queues > sriov->nb_rx_q_per_pool) { > + PMD_INIT_LOG(ERR, "SRIOV active, rx queue count must > less or equal %d.", > + sriov->nb_rx_q_per_pool); > + return (-EINVAL); > + } > + > + if (dev->data->nb_rx_queues > sriov->nb_tx_q_per_pool) { > + PMD_INIT_LOG(ERR, "SRIOV active, tx queue count must > less or equal %d.", > + sriov->nb_tx_q_per_pool); > + return (-EINVAL); > + } > + > + return 0; > } >=20 > int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev) > -- > 1.9.1