From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [143.182.124.21]) by dpdk.org (Postfix) with ESMTP id 70E60AFD7 for ; Fri, 2 May 2014 01:21:41 +0200 (CEST) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 01 May 2014 16:21:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,968,1389772800"; d="scan'208";a="426575170" Received: from irsmsx104.ger.corp.intel.com ([163.33.3.159]) by azsmga001.ch.intel.com with ESMTP; 01 May 2014 16:21:42 -0700 Received: from irsmsx152.ger.corp.intel.com (163.33.192.66) by IRSMSX104.ger.corp.intel.com (163.33.3.159) with Microsoft SMTP Server (TLS) id 14.3.123.3; Fri, 2 May 2014 00:21:42 +0100 Received: from irsmsx105.ger.corp.intel.com ([169.254.7.70]) by IRSMSX152.ger.corp.intel.com ([169.254.6.128]) with mapi id 14.03.0123.003; Fri, 2 May 2014 00:21:41 +0100 From: "Ananyev, Konstantin" To: Ivan Boule , "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH 2/5] ethdev: allow to set RSS hash computation flags and/or key Thread-Index: AQHPZHv0IkB70FE00UWqg4TVUsHVGZssXXQg Date: Thu, 1 May 2014 23:21:41 +0000 Message-ID: <2601191342CEEE43887BDE71AB9772580EFA2293@IRSMSX105.ger.corp.intel.com> References: <1398866126-16931-1-git-send-email-ivan.boule@6wind.com> <1398866126-16931-3-git-send-email-ivan.boule@6wind.com> In-Reply-To: <1398866126-16931-3-git-send-email-ivan.boule@6wind.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [163.33.239.182] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH 2/5] ethdev: allow to set RSS hash computation flags and/or key 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: Thu, 01 May 2014 23:21:42 -0000 Hi Ivan, About enabling/disabling RSS dynamically (without dev_stop/dev_start): As I know 82599 spec explicitly states that RSS shouldn't be enabled/disabl= ed dynamically. >>From section 7.1.2.8 Receive-Side Scaling (RSS): "... Enabling rules: * RSS is enabled in the MRQC register. * RSS enabling cannot be done dynamically while it must be preceded by a so= ftware reset. ... Disabling rules: * Disabling RSS on the fly is not allowed, and the 82599 must be reset afte= r RSS is disabled. ..." RETA table from other side can be updated on the fly. As I remember that was the reason why we allow only dev_rss_reta_update() t= o be used dynamically (without dev_start/dev_stop). Konstantin -----Original Message----- From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Ivan Boule Sent: Wednesday, April 30, 2014 2:55 PM To: dev@dpdk.org Subject: [dpdk-dev] [PATCH 2/5] ethdev: allow to set RSS hash computation f= lags and/or key 1) Add a new function "rss_hash_conf_update" in the PMD API to dynamically update the RSS flags and/or the RSS key used by a NIC to compute the RSS hash of input packets. The new function uses the existing data structure "rte_eth_rss_conf" for the argument that contains the new hash flags and/or the new hash key to use. 2) Add the ixgbe-specific function "ixgbe_dev_rss_hash_conf_update" and the igb-specific function "eth_igb_rss_hash_conf_update" to update the RSS hash configuration of ixgbe and igb controllers respectively. Note: Configuring the RSS hash flags and the RSS key used by a NIC consists in updating appropriate PCI registers of the NIC. These operations have been manually tested with the interactive commands "write reg" and "write regbit" of the testpmd application. Signed-off-by: Ivan Boule --- lib/librte_ether/rte_ethdev.c | 23 +++++++++ lib/librte_ether/rte_ethdev.h | 25 ++++++++++ lib/librte_pmd_e1000/e1000_ethdev.h | 3 ++ lib/librte_pmd_e1000/igb_ethdev.c | 1 + lib/librte_pmd_e1000/igb_rxtx.c | 93 +++++++++++++++++++++----------= ---- lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 1 + lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 3 ++ lib/librte_pmd_ixgbe/ixgbe_rxtx.c | 90 ++++++++++++++++++++-----------= -- 8 files changed, 169 insertions(+), 70 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 473c98b..c00dff0 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1572,6 +1572,29 @@ rte_eth_dev_rss_reta_query(uint8_t port_id, struct r= te_eth_rss_reta *reta_conf) } =20 int +rte_eth_dev_rss_hash_conf_update(uint8_t port_id, + struct rte_eth_rss_conf *rss_conf) +{ + struct rte_eth_dev *dev; + uint16_t rss_hash_protos; + + if (port_id >=3D nb_ports) { + PMD_DEBUG_TRACE("Invalid port_id=3D%d\n", port_id); + return (-ENODEV); + } + rss_hash_protos =3D rss_conf->rss_hf; + if ((rss_hash_protos !=3D 0) && + ((rss_hash_protos & ETH_RSS_PROTO_MASK) =3D=3D 0)) { + PMD_DEBUG_TRACE("Invalid rss_hash_protos=3D0x%x\n", + rss_hash_protos); + return (-EINVAL); + } + dev =3D &rte_eth_devices[port_id]; + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_update, -ENOTSUP); + return (*dev->dev_ops->rss_hash_conf_update)(dev, rss_conf); +} + +int rte_eth_led_on(uint8_t port_id) { struct rte_eth_dev *dev; diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index dea7471..a970761 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -331,6 +331,8 @@ struct rte_eth_rss_conf { #define ETH_RSS_IPV4_UDP 0x0040 /**< IPv4/UDP packet. */ #define ETH_RSS_IPV6_UDP 0x0080 /**< IPv6/UDP packet. */ #define ETH_RSS_IPV6_UDP_EX 0x0100 /**< IPv6/UDP with extension headers. *= / + +#define ETH_RSS_PROTO_MASK 0x01FF /**< Mask of valid RSS hash protocols *= / /* Definitions used for redirection table entry size */ #define ETH_RSS_RETA_NUM_ENTRIES 128 #define ETH_RSS_RETA_MAX_QUEUE 16 =20 @@ -966,6 +968,10 @@ typedef int (*reta_query_t)(struct rte_eth_dev *dev, struct rte_eth_rss_reta *reta_conf); /**< @internal Query RSS redirection table on an Ethernet device */ =20 +typedef int (*rss_hash_conf_update_t)(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); +/**< @internal Update RSS hash configuration of an Ethernet device */ + typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev); /**< @internal Turn on SW controllable LED on an Ethernet device */ =20 @@ -1153,6 +1159,8 @@ struct eth_dev_ops { bypass_wd_reset_t bypass_wd_reset; #endif =20 + /** Configure RSS hash protocols. */ + rss_hash_conf_update_t rss_hash_conf_update; }; =20 /** @@ -2859,6 +2867,23 @@ int rte_eth_dev_bypass_wd_timeout_show(uint8_t port,= uint32_t *wd_timeout); */ int rte_eth_dev_bypass_wd_reset(uint8_t port); =20 + /** + * Configuration of Receive Side Scaling hash computation of Ethernet devi= ce. + * + * @param port + * The port identifier of the Ethernet device. + * @param rss_conf + * The new configuration to use for RSS hash computation on the port. + * @return + * - (0) if successful. + * - (-ENODEV) if port identifier is invalid. + * - (-ENOTSUP) if hardware doesn't support. + * - (-EINVAL) if bad parameter. + */ +int +rte_eth_dev_rss_hash_conf_update(uint8_t port_id, + struct rte_eth_rss_conf *rss_conf); + #ifdef __cplusplus } #endif diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e10= 00_ethdev.h index d09064e..e228c53 100644 --- a/lib/librte_pmd_e1000/e1000_ethdev.h +++ b/lib/librte_pmd_e1000/e1000_ethdev.h @@ -138,6 +138,9 @@ uint16_t eth_igb_recv_pkts(void *rxq, struct rte_mbuf *= *rx_pkts, uint16_t eth_igb_recv_scattered_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); =20 +int eth_igb_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); + int eth_igbvf_rx_init(struct rte_eth_dev *dev); =20 void eth_igbvf_tx_init(struct rte_eth_dev *dev); diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_e= thdev.c index 673b4de..07ae149 100644 --- a/lib/librte_pmd_e1000/igb_ethdev.c +++ b/lib/librte_pmd_e1000/igb_ethdev.c @@ -193,6 +193,7 @@ static struct eth_dev_ops eth_igb_ops =3D { .mac_addr_remove =3D eth_igb_rar_clear, .reta_update =3D eth_igb_rss_reta_update, .reta_query =3D eth_igb_rss_reta_query, + .rss_hash_conf_update =3D eth_igb_rss_hash_conf_update, }; =20 /* diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxt= x.c index 1ebe2f5..5499fd8 100644 --- a/lib/librte_pmd_e1000/igb_rxtx.c +++ b/lib/librte_pmd_e1000/igb_rxtx.c @@ -1518,54 +1518,36 @@ igb_rss_disable(struct rte_eth_dev *dev) E1000_WRITE_REG(hw, E1000_MRQC, mrqc); } =20 -static void -igb_rss_configure(struct rte_eth_dev *dev) +int +eth_igb_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) { struct e1000_hw *hw; - uint8_t *hash_key; + uint8_t *hash_key; uint32_t rss_key; uint32_t mrqc; - uint32_t shift; uint16_t rss_hf; uint16_t i; =20 hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - rss_hf =3D dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; - if (rss_hf =3D=3D 0) /* Disable RSS. */ { - igb_rss_disable(dev); - return; - } - hash_key =3D dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; - if (hash_key =3D=3D NULL) - hash_key =3D rss_intel_key; /* Default hash key. */ - - /* Fill in RSS hash key. */ - for (i =3D 0; i < 10; i++) { - rss_key =3D hash_key[(i * 4)]; - rss_key |=3D hash_key[(i * 4) + 1] << 8; - rss_key |=3D hash_key[(i * 4) + 2] << 16; - rss_key |=3D hash_key[(i * 4) + 3] << 24; - E1000_WRITE_REG_ARRAY(hw, E1000_RSSRK(0), i, rss_key); + hash_key =3D rss_conf->rss_key; + if (hash_key !=3D NULL) { + /* Fill in RSS hash key */ + for (i =3D 0; i < 10; i++) { + rss_key =3D hash_key[(i * 4)]; + rss_key |=3D hash_key[(i * 4) + 1] << 8; + rss_key |=3D hash_key[(i * 4) + 2] << 16; + rss_key |=3D hash_key[(i * 4) + 3] << 24; + E1000_WRITE_REG_ARRAY(hw, E1000_RSSRK(0), i, rss_key); + } } - - /* Fill in redirection table. */ - shift =3D (hw->mac.type =3D=3D e1000_82575) ? 6 : 0; - for (i =3D 0; i < 128; i++) { - union e1000_reta { - uint32_t dword; - uint8_t bytes[4]; - } reta; - uint8_t q_idx; - - q_idx =3D (uint8_t) ((dev->data->nb_rx_queues > 1) ? - i % dev->data->nb_rx_queues : 0); - reta.bytes[i & 3] =3D (uint8_t) (q_idx << shift); - if ((i & 3) =3D=3D 3) - E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword); + rss_hf =3D rss_conf->rss_hf; + if (rss_hf =3D=3D 0) { /* Disable RSS */ + igb_rss_disable(dev); + return 0; } =20 - /* Set configured hashing functions in MRQC register. */ + /* Set configured hashing protocols in MRQC register */ mrqc =3D E1000_MRQC_ENABLE_RSS_4Q; /* RSS enabled. */ if (rss_hf & ETH_RSS_IPV4) mrqc |=3D E1000_MRQC_RSS_FIELD_IPV4; @@ -1586,6 +1568,43 @@ igb_rss_configure(struct rte_eth_dev *dev) if (rss_hf & ETH_RSS_IPV6_UDP_EX) mrqc |=3D E1000_MRQC_RSS_FIELD_IPV6_UDP_EX; E1000_WRITE_REG(hw, E1000_MRQC, mrqc); + return 0; +} + +static void +igb_rss_configure(struct rte_eth_dev *dev) +{ + struct rte_eth_rss_conf rss_conf; + struct e1000_hw *hw; + uint32_t shift; + uint16_t i; + + hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* Fill in redirection table. */ + shift =3D (hw->mac.type =3D=3D e1000_82575) ? 6 : 0; + for (i =3D 0; i < 128; i++) { + union e1000_reta { + uint32_t dword; + uint8_t bytes[4]; + } reta; + uint8_t q_idx; + + q_idx =3D (uint8_t) ((dev->data->nb_rx_queues > 1) ? + i % dev->data->nb_rx_queues : 0); + reta.bytes[i & 3] =3D (uint8_t) (q_idx << shift); + if ((i & 3) =3D=3D 3) + E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword); + } + + /* + * Configure the RSS key and the RSS protocols used to compute + * the RSS hash of input packets. + */ + rss_conf =3D dev->data->dev_conf.rx_adv_conf.rss_conf; + if (rss_conf.rss_key =3D=3D NULL) + rss_conf.rss_key =3D rss_intel_key; /* Default hash key */ + (void) eth_igb_rss_hash_conf_update(dev, &rss_conf); } =20 /* diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixg= be_ethdev.c index 6dd52d7..5910501 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -300,6 +300,7 @@ static struct eth_dev_ops ixgbe_eth_dev_ops =3D { .bypass_ver_show =3D ixgbe_bypass_ver_show, .bypass_wd_reset =3D ixgbe_bypass_wd_reset, #endif /* RTE_NIC_BYPASS */ + .rss_hash_conf_update =3D ixgbe_dev_rss_hash_conf_update, }; =20 /* diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixg= be_ethdev.h index 9d7e93f..3d33ad2 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h @@ -235,6 +235,9 @@ uint16_t ixgbe_xmit_pkts(void *tx_queue, struct rte_mbu= f **tx_pkts, uint16_t ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); =20 +int ixgbe_dev_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); + /* * Flow director function prototypes */ diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe= _rxtx.c index 7930dbd..877ecfd 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c +++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c @@ -2291,50 +2291,37 @@ ixgbe_rss_disable(struct rte_eth_dev *dev) IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } =20 -static void -ixgbe_rss_configure(struct rte_eth_dev *dev) +int +ixgbe_dev_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) { struct ixgbe_hw *hw; - uint8_t *hash_key; - uint32_t rss_key; + uint8_t *hash_key; uint32_t mrqc; - uint32_t reta; + uint32_t rss_key; uint16_t rss_hf; uint16_t i; - uint16_t j; =20 - PMD_INIT_FUNC_TRACE(); hw =3D IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - rss_hf =3D dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; + hash_key =3D rss_conf->rss_key; + if (hash_key !=3D NULL) { + /* Fill in RSS hash key */ + for (i =3D 0; i < 10; i++) { + rss_key =3D hash_key[(i * 4)]; + rss_key |=3D hash_key[(i * 4) + 1] << 8; + rss_key |=3D hash_key[(i * 4) + 2] << 16; + rss_key |=3D hash_key[(i * 4) + 3] << 24; + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RSSRK(0), i, rss_key); + } + } + rss_hf =3D rss_conf->rss_hf; if (rss_hf =3D=3D 0) { /* Disable RSS */ ixgbe_rss_disable(dev); - return; - } - hash_key =3D dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; - if (hash_key =3D=3D NULL) - hash_key =3D rss_intel_key; /* Default hash key */ - - /* Fill in RSS hash key */ - for (i =3D 0; i < 10; i++) { - rss_key =3D hash_key[(i * 4)]; - rss_key |=3D hash_key[(i * 4) + 1] << 8; - rss_key |=3D hash_key[(i * 4) + 2] << 16; - rss_key |=3D hash_key[(i * 4) + 3] << 24; - IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RSSRK(0), i, rss_key); - } - - /* Fill in redirection table */ - reta =3D 0; - for (i =3D 0, j =3D 0; i < 128; i++, j++) { - if (j =3D=3D dev->data->nb_rx_queues) j =3D 0; - reta =3D (reta << 8) | j; - if ((i & 3) =3D=3D 3) - IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), rte_bswap32(reta)); + return 0; } =20 - /* Set configured hashing functions in MRQC register */ - mrqc =3D IXGBE_MRQC_RSSEN; /* RSS enable */ + /* Set configured hashing protocols in MRQC register */ + mrqc =3D IXGBE_MRQC_RSSEN; /* Enable RSS */ if (rss_hf & ETH_RSS_IPV4) mrqc |=3D IXGBE_MRQC_RSS_FIELD_IPV4; if (rss_hf & ETH_RSS_IPV4_TCP) @@ -2354,6 +2341,43 @@ ixgbe_rss_configure(struct rte_eth_dev *dev) if (rss_hf & ETH_RSS_IPV6_UDP_EX) mrqc |=3D IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP; IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + return 0; +} + +static void +ixgbe_rss_configure(struct rte_eth_dev *dev) +{ + struct rte_eth_rss_conf rss_conf; + struct ixgbe_hw *hw; + uint32_t reta; + uint16_t i; + uint16_t j; + + PMD_INIT_FUNC_TRACE(); + hw =3D IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* + * Fill in redirection table + * The byte-swap is needed because NIC registers are in + * little-endian order. + */ + reta =3D 0; + for (i =3D 0, j =3D 0; i < 128; i++, j++) { + if (j =3D=3D dev->data->nb_rx_queues) j =3D 0; + reta =3D (reta << 8) | j; + if ((i & 3) =3D=3D 3) + IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), + rte_bswap32(reta)); + } + + /* + * Configure the RSS key and the RSS protocols used to compute + * the RSS hash of input packets. + */ + rss_conf =3D dev->data->dev_conf.rx_adv_conf.rss_conf; + if (rss_conf.rss_key =3D=3D NULL) + rss_conf.rss_key =3D rss_intel_key; /* Default hash key */ + (void) ixgbe_dev_rss_hash_conf_update(dev, &rss_conf); } =20 #define NUM_VFTA_REGISTERS 128 --=20 1.7.10.4