From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Dai, Wei" Subject: Re: [PATCH v3 1/2] net/e1000: move RSS to flow API Date: Thu, 7 Dec 2017 09:19:02 +0000 Message-ID: <49759EB36A64CF4892C1AFEC9231E8D651568910@PGSMSX112.gar.corp.intel.com> References: <20171124031032.47199-1-wei.zhao1@intel.com> <20171124080527.56495-1-wei.zhao1@intel.com> <20171124080527.56495-2-wei.zhao1@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Cc: "Zhao1, Wei" To: "Zhao1, Wei" , "dev@dpdk.org" Return-path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 4E9C61C00 for ; Thu, 7 Dec 2017 10:19:06 +0100 (CET) In-Reply-To: <20171124080527.56495-2-wei.zhao1@intel.com> Content-Language: en-US List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi, Zhao Wei Please correct build error show in http://dpdk.org/ml/archives/test-report/= 2017-November/035129.html > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wei Zhao > Sent: Friday, November 24, 2017 4:05 PM > To: dev@dpdk.org > Cc: Zhao1, Wei > Subject: [dpdk-dev] [PATCH v3 1/2] net/e1000: move RSS to flow API >=20 > Rte_flow actually defined to include RSS, but till now, RSS is out of rte= _flow. > This patch is to move igb existing RSS to rte_flow. >=20 > Signed-off-by: Wei Zhao > --- > drivers/net/e1000/e1000_ethdev.h | 20 +++++ > drivers/net/e1000/igb_ethdev.c | 17 +++++ > drivers/net/e1000/igb_flow.c | 160 > +++++++++++++++++++++++++++++++++++++++ > drivers/net/e1000/igb_rxtx.c | 61 +++++++++++++++ > 4 files changed, 258 insertions(+) >=20 > diff --git a/drivers/net/e1000/e1000_ethdev.h > b/drivers/net/e1000/e1000_ethdev.h > index 5668910..0731766 100644 > --- a/drivers/net/e1000/e1000_ethdev.h > +++ b/drivers/net/e1000/e1000_ethdev.h > @@ -257,6 +257,12 @@ struct igb_ethertype_filter { > uint32_t etqf; > }; >=20 > +struct igb_rte_flow_rss_conf { > + struct rte_eth_rss_conf rss_conf; /**< RSS parameters. */ > + uint16_t num; /**< Number of entries in queue[]. */ > + uint16_t queue[IGB_MAX_RX_QUEUE_NUM]; /**< Queues indices to > use. */ > +}; > + > /* > * Structure to store filters'info. > */ > @@ -274,6 +280,8 @@ struct e1000_filter_info { > struct e1000_2tuple_filter_list twotuple_list; > /* store the SYN filter info */ > uint32_t syn_info; > + /* store the rss filter info */ > + struct igb_rte_flow_rss_conf rss_info; > }; >=20 > /* > @@ -342,6 +350,12 @@ struct igb_flex_filter_ele { > struct rte_eth_flex_filter filter_info; }; >=20 > +/* rss filter list structure */ > +struct igb_rss_conf_ele { > + TAILQ_ENTRY(igb_rss_conf_ele) entries; > + struct igb_rte_flow_rss_conf filter_info; }; > + > /* igb_flow memory list structure */ > struct igb_flow_mem { > TAILQ_ENTRY(igb_flow_mem) entries; > @@ -357,6 +371,8 @@ TAILQ_HEAD(igb_syn_filter_list, > igb_eth_syn_filter_ele); struct igb_syn_filter_list igb_filter_syn_list; > TAILQ_HEAD(igb_flex_filter_list, igb_flex_filter_ele); struct > igb_flex_filter_list igb_filter_flex_list; > +TAILQ_HEAD(igb_rss_filter_list, igb_rss_conf_ele); struct > +igb_rss_filter_list igb_filter_rss_list; > TAILQ_HEAD(igb_flow_mem_list, igb_flow_mem); struct > igb_flow_mem_list igb_flow_list; >=20 > @@ -500,4 +516,8 @@ int eth_igb_syn_filter_set(struct rte_eth_dev *dev, > int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev, > struct rte_eth_flex_filter *filter, > bool add); > +int igb_config_rss_filter(struct rte_eth_dev *dev, > + struct igb_rte_flow_rss_conf *conf, > + bool add); > + > #endif /* _E1000_ETHDEV_H_ */ > diff --git a/drivers/net/e1000/igb_ethdev.c > b/drivers/net/e1000/igb_ethdev.c index fdc139f..275fa02 100644 > --- a/drivers/net/e1000/igb_ethdev.c > +++ b/drivers/net/e1000/igb_ethdev.c > @@ -948,6 +948,7 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev) > TAILQ_INIT(&igb_filter_ethertype_list); > TAILQ_INIT(&igb_filter_syn_list); > TAILQ_INIT(&igb_filter_flex_list); > + TAILQ_INIT(&igb_filter_rss_list); > TAILQ_INIT(&igb_flow_list); >=20 > return 0; > @@ -1007,6 +1008,10 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev) > memset(filter_info->ethertype_filters, 0, > E1000_MAX_ETQF_FILTERS * sizeof(struct igb_ethertype_filter)); >=20 > + /* clear the rss filter info */ > + memset(&filter_info->rss_info, 0, > + sizeof(struct igb_rte_flow_rss_conf)); > + > /* remove all ntuple filters of the device */ > igb_ntuple_filter_uninit(eth_dev); >=20 > @@ -5628,6 +5633,17 @@ igb_flex_filter_restore(struct rte_eth_dev *dev) > } > } >=20 > +/* restore rss filter */ > +static inline void > +igb_rss_filter_restore(struct rte_eth_dev *dev) { > + struct e1000_filter_info *filter_info =3D > + E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); > + > + if (filter_info->rss_info.num) > + igb_config_rss_filter(dev, &filter_info->rss_info, TRUE); } > + > /* restore all types filter */ > static int > igb_filter_restore(struct rte_eth_dev *dev) @@ -5636,6 +5652,7 @@ > igb_filter_restore(struct rte_eth_dev *dev) > igb_ethertype_filter_restore(dev); > igb_syn_filter_restore(dev); > igb_flex_filter_restore(dev); > + igb_rss_filter_restore(dev); >=20 > return 0; > } > diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c > index 22bad26..bf5cfac 100644 > --- a/drivers/net/e1000/igb_flow.c > +++ b/drivers/net/e1000/igb_flow.c > @@ -1295,6 +1295,101 @@ igb_parse_flex_filter(struct rte_eth_dev *dev, > return 0; > } >=20 > +static int > +igb_parse_rss_filter(struct rte_eth_dev *dev, > + const struct rte_flow_attr *attr, > + const struct rte_flow_action actions[], > + struct igb_rte_flow_rss_conf *rss_conf, > + struct rte_flow_error *error) > +{ > + const struct rte_flow_action *act; > + const struct rte_flow_action_rss *rss; > + uint16_t n, index; > + > + /** > + * rss only supports forwarding, > + * check if the first not void action is RSS. > + */ > + index =3D 0; > + NEXT_ITEM_OF_ACTION(act, actions, index); > + if (act->type !=3D RTE_FLOW_ACTION_TYPE_RSS) { > + memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf)); > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + act, "Not supported action."); > + return -rte_errno; > + } > + > + rss =3D (const struct rte_flow_action_rss *)act->conf; > + > + if (!rss || !rss->num) { > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + act, > + "no valid queues"); > + return -rte_errno; > + } > + > + for (n =3D 0; n < rss->num; n++) { > + if (rss->queue[n] >=3D dev->data->nb_rx_queues) { > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + act, > + "queue id > max number of queues"); > + return -rte_errno; > + } > + } > + > + if (rss->rss_conf) > + rss_conf->rss_conf =3D *rss->rss_conf; > + else > + rss_conf->rss_conf.rss_hf =3D IXGBE_RSS_OFFLOAD_ALL; > + > + for (n =3D 0; n < rss->num; ++n) > + rss_conf->queue[n] =3D rss->queue[n]; > + rss_conf->num =3D rss->num; > + > + /* check if the next not void item is END */ > + index++; > + NEXT_ITEM_OF_ACTION(act, actions, index); > + if (act->type !=3D RTE_FLOW_ACTION_TYPE_END) { > + memset(rss_conf, 0, sizeof(struct rte_eth_rss_conf)); > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ACTION, > + act, "Not supported action."); > + return -rte_errno; > + } > + > + /* parse attr */ > + /* must be input direction */ > + if (!attr->ingress) { > + memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf)); > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, > + attr, "Only support ingress."); > + return -rte_errno; > + } > + > + /* not supported */ > + if (attr->egress) { > + memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf)); > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, > + attr, "Not support egress."); > + return -rte_errno; > + } > + > + if (attr->priority > 0xFFFF) { > + memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf)); > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, > + attr, "Error priority."); > + return -rte_errno; > + } > + > + return 0; > +} > + > /** > * Create a flow rule. > * Theorically one rule can match more than one filters. > @@ -1313,11 +1408,13 @@ igb_flow_create(struct rte_eth_dev *dev, > struct rte_eth_ethertype_filter ethertype_filter; > struct rte_eth_syn_filter syn_filter; > struct rte_eth_flex_filter flex_filter; > + struct igb_rte_flow_rss_conf rss_conf; > struct rte_flow *flow =3D NULL; > struct igb_ntuple_filter_ele *ntuple_filter_ptr; > struct igb_ethertype_filter_ele *ethertype_filter_ptr; > struct igb_eth_syn_filter_ele *syn_filter_ptr; > struct igb_flex_filter_ele *flex_filter_ptr; > + struct igb_rss_conf_ele *rss_filter_ptr; > struct igb_flow_mem *igb_flow_mem_ptr; >=20 > flow =3D rte_zmalloc("igb_rte_flow", sizeof(struct rte_flow), 0); @@ > -1419,6 +1516,29 @@ igb_flow_create(struct rte_eth_dev *dev, > } > } >=20 > + memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf)); > + ret =3D igb_parse_rss_filter(dev, attr, > + actions, &rss_conf, error); > + if (!ret) { > + ret =3D igb_config_rss_filter(dev, &rss_conf, TRUE); > + if (!ret) { > + rss_filter_ptr =3D rte_zmalloc("igb_rss_filter", > + sizeof(struct igb_rss_conf_ele), 0); > + if (!rss_filter_ptr) { > + PMD_DRV_LOG(ERR, "failed to allocate memory"); > + goto out; > + } > + rte_memcpy(&rss_filter_ptr->filter_info, > + &rss_conf, > + sizeof(struct igb_rte_flow_rss_conf)); > + TAILQ_INSERT_TAIL(&igb_filter_rss_list, > + rss_filter_ptr, entries); > + flow->rule =3D rss_filter_ptr; > + flow->filter_type =3D RTE_ETH_FILTER_HASH; > + return flow; > + } > + } > + > out: > TAILQ_REMOVE(&igb_flow_list, > igb_flow_mem_ptr, entries); > @@ -1446,6 +1566,7 @@ igb_flow_validate(__rte_unused struct > rte_eth_dev *dev, > struct rte_eth_ethertype_filter ethertype_filter; > struct rte_eth_syn_filter syn_filter; > struct rte_eth_flex_filter flex_filter; > + struct igb_rte_flow_rss_conf rss_conf; > int ret; >=20 > memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter)); @@ > -1469,6 +1590,12 @@ igb_flow_validate(__rte_unused struct rte_eth_dev > *dev, > memset(&flex_filter, 0, sizeof(struct rte_eth_flex_filter)); > ret =3D igb_parse_flex_filter(dev, attr, pattern, > actions, &flex_filter, error); > + if (!ret) > + return 0; > + > + memset(&rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf)); > + ret =3D igb_parse_rss_filter(dev, attr, > + actions, &rss_conf, error); >=20 > return ret; > } > @@ -1487,6 +1614,7 @@ igb_flow_destroy(struct rte_eth_dev *dev, > struct igb_eth_syn_filter_ele *syn_filter_ptr; > struct igb_flex_filter_ele *flex_filter_ptr; > struct igb_flow_mem *igb_flow_mem_ptr; > + struct igb_rss_conf_ele *rss_filter_ptr; >=20 > switch (filter_type) { > case RTE_ETH_FILTER_NTUPLE: > @@ -1533,6 +1661,17 @@ igb_flow_destroy(struct rte_eth_dev *dev, > rte_free(flex_filter_ptr); > } > break; > + case RTE_ETH_FILTER_HASH: > + rss_filter_ptr =3D (struct igb_rss_conf_ele *) > + pmd_flow->rule; > + ret =3D igb_config_rss_filter(dev, > + &rss_filter_ptr->filter_info, FALSE); > + if (!ret) { > + TAILQ_REMOVE(&igb_filter_rss_list, > + rss_filter_ptr, entries); > + rte_free(rss_filter_ptr); > + } > + break; > default: > PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", > filter_type); > @@ -1621,6 +1760,17 @@ igb_clear_all_flex_filter(struct rte_eth_dev *dev) > igb_remove_flex_filter(dev, flex_filter); } >=20 > +/* remove the rss filter */ > +static void > +igb_clear_rss_filter(struct rte_eth_dev *dev) { > + struct e1000_filter_info *filter =3D > + E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); > + > + if (filter->rss_info.num) > + igb_config_rss_filter(dev, &filter->rss_info, FALSE); } > + > void > igb_filterlist_flush(struct rte_eth_dev *dev) { @@ -1628,6 +1778,7 @@ > igb_filterlist_flush(struct rte_eth_dev *dev) > struct igb_ethertype_filter_ele *ethertype_filter_ptr; > struct igb_eth_syn_filter_ele *syn_filter_ptr; > struct igb_flex_filter_ele *flex_filter_ptr; > + struct igb_rss_conf_ele *rss_filter_ptr; > struct igb_flow_mem *igb_flow_mem_ptr; > enum rte_filter_type filter_type; > struct rte_flow *pmd_flow; > @@ -1670,6 +1821,14 @@ igb_filterlist_flush(struct rte_eth_dev *dev) > flex_filter_ptr, entries); > rte_free(flex_filter_ptr); > break; > + case RTE_ETH_FILTER_HASH: > + rss_filter_ptr =3D > + (struct igb_rss_conf_ele *) > + pmd_flow->rule; > + TAILQ_REMOVE(&igb_filter_rss_list, > + rss_filter_ptr, entries); > + rte_free(rss_filter_ptr); > + break; > default: > PMD_DRV_LOG(WARNING, "Filter type" > "(%d) not supported", filter_type); @@ -1693,6 > +1852,7 @@ igb_flow_flush(struct rte_eth_dev *dev, > igb_clear_all_ethertype_filter(dev); > igb_clear_syn_filter(dev); > igb_clear_all_flex_filter(dev); > + igb_clear_rss_filter(dev); > igb_filterlist_flush(dev); >=20 > return 0; > diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c > index 4ee12e9..af86726 100644 > --- a/drivers/net/e1000/igb_rxtx.c > +++ b/drivers/net/e1000/igb_rxtx.c > @@ -2786,3 +2786,64 @@ igb_txq_info_get(struct rte_eth_dev *dev, > uint16_t queue_id, > qinfo->conf.tx_thresh.hthresh =3D txq->hthresh; > qinfo->conf.tx_thresh.wthresh =3D txq->wthresh; } > + > +int > +igb_config_rss_filter(struct rte_eth_dev *dev, > + struct igb_rte_flow_rss_conf *conf, bool add) { > + uint32_t shift; > + uint16_t i, j; > + struct rte_eth_rss_conf rss_conf =3D conf->rss_conf; > + struct e1000_filter_info *filter_info =3D > + E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); > + struct e1000_hw *hw =3D > E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); > + > + hw =3D E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); > + > + if (!add) { > + if (memcmp(conf, &filter_info->rss_info, > + sizeof(struct igb_rte_flow_rss_conf)) =3D=3D 0) { > + igb_rss_disable(dev); > + memset(&filter_info->rss_info, 0, > + sizeof(struct igb_rte_flow_rss_conf)); > + return 0; > + } > + return -EINVAL; > + } > + > + if (filter_info->rss_info.num) > + return -EINVAL; > + > + /* Fill in redirection table. */ > + shift =3D (hw->mac.type =3D=3D e1000_82575) ? 6 : 0; > + for (i =3D 0, j =3D 0; i < 128; i++, j++) { > + union e1000_reta { > + uint32_t dword; > + uint8_t bytes[4]; > + } reta; > + uint8_t q_idx; > + > + q_idx =3D conf->queue[j]; > + if (j =3D=3D conf->num) > + j =3D 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. > + */ > + if ((rss_conf.rss_hf & IGB_RSS_OFFLOAD_ALL) =3D=3D 0) { > + igb_rss_disable(dev); > + return 0; > + } > + if (rss_conf.rss_key =3D=3D NULL) > + rss_conf.rss_key =3D rss_intel_key; /* Default hash key */ > + igb_hw_rss_hash_set(hw, &rss_conf); > + > + rte_memcpy(&filter_info->rss_info, > + conf, sizeof(struct igb_rte_flow_rss_conf)); > + > + return 0; > +} > -- > 2.9.3