All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Guo, Jia" <jia.guo@intel.com>
To: "Di, ChenxuX" <chenxux.di@intel.com>, "dev@dpdk.org" <dev@dpdk.org>
Cc: "Xing, Beilei" <beilei.xing@intel.com>,
	"Wang, Haiyue" <haiyue.wang@intel.com>,
	"Di, ChenxuX" <chenxux.di@intel.com>,
	"stable@dpdk.org" <stable@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH 2/2] net/i40e: fix incorrect FDIR flex pit
Date: Wed, 4 Nov 2020 09:18:49 +0000	[thread overview]
Message-ID: <36fa7db4c27244ddb043fb7fd3e0f11a@intel.com> (raw)
In-Reply-To: <20201104082959.63800-3-chenxux.di@intel.com>

Hi, chenxu

> -----Original Message-----
> From: Chenxu Di <chenxux.di@intel.com>
> Sent: Wednesday, November 4, 2020 4:30 PM
> To: dev@dpdk.org
> Cc: Xing, Beilei <beilei.xing@intel.com>; Guo, Jia <jia.guo@intel.com>; Wang,
> Haiyue <haiyue.wang@intel.com>; Di, ChenxuX <chenxux.di@intel.com>;
> stable@dpdk.org
> Subject: [PATCH 2/2] net/i40e: fix incorrect FDIR flex pit
> 
> The register of FDIR flex pit should not be set during flow validate.
> It should be set when flow create.
> 
> Fixes: 6ced3dd72f5f ("net/i40e: support flexible payload parsing for FDIR")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Chenxu Di <chenxux.di@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.h |  21 ++++---
>  drivers/net/i40e/i40e_fdir.c   | 100
> +++++++++++++++++++++++++++++++++
>  drivers/net/i40e/i40e_flow.c   |  98 +++-----------------------------
>  3 files changed, 119 insertions(+), 100 deletions(-)
> 
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index 6be929f65..e00133c88 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -599,12 +599,22 @@ enum i40e_fdir_ip_type {
>  	I40E_FDIR_IPTYPE_IPV6,
>  };
> 
> +/*
> + * Structure to store flex pit for flow diretor.
> + */
> +struct i40e_fdir_flex_pit {
> +	uint8_t src_offset; /* offset in words from the beginning of payload
> */
> +	uint8_t size;       /* size in words */
> +	uint8_t dst_offset; /* offset in words of flexible payload */ };
> +
>  /* A structure used to contain extend input of flow */  struct
> i40e_fdir_flow_ext {
>  	uint16_t vlan_tci;
>  	uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
>  	/* It is filled by the flexible payload to match. */
>  	uint8_t flex_mask[I40E_FDIR_MAX_FLEX_LEN];
> +	uint8_t raw_id;
>  	uint8_t is_vf;   /* 1 for VF, 0 for port dev */
>  	uint16_t dst_id; /* VF ID, available when is_vf is 1*/
>  	bool inner_ip;   /* If there is inner ip */
> @@ -613,6 +623,8 @@ struct i40e_fdir_flow_ext {
>  	bool customized_pctype; /* If customized pctype is used */
>  	bool pkt_template; /* If raw packet template is used */
>  	bool is_udp; /* ipv4|ipv6 udp flow */
> +	enum i40e_flxpld_layer_idx layer_idx;
> +	struct i40e_fdir_flex_pit flex_pit[I40E_MAX_FLXPLD_LAYER *
> +I40E_MAX_FLXPLD_FIED];
>  };
> 
>  /* A structure used to define the input for a flow director filter entry */ @@
> -664,15 +676,6 @@ struct i40e_fdir_filter_conf {
>  	struct i40e_fdir_action action;  /* Action taken when match */  };
> 
> -/*
> - * Structure to store flex pit for flow diretor.
> - */
> -struct i40e_fdir_flex_pit {
> -	uint8_t src_offset;    /* offset in words from the beginning of payload
> */
> -	uint8_t size;          /* size in words */
> -	uint8_t dst_offset;    /* offset in words of flexible payload */
> -};
> -
>  struct i40e_fdir_flex_mask {
>  	uint8_t word_mask;  /**< Bit i enables word i of flexible payload */
>  	uint8_t nb_bitmask;
> diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index
> e31464eb7..e64cb2fd0 100644
> --- a/drivers/net/i40e/i40e_fdir.c
> +++ b/drivers/net/i40e/i40e_fdir.c
> @@ -1765,6 +1765,81 @@ i40e_add_del_fdir_filter(struct rte_eth_dev *dev,
>  	return ret;
>  }
> 
> +static int
> +i40e_flow_store_flex_pit(struct i40e_pf *pf,
> +			 struct i40e_fdir_flex_pit *flex_pit,
> +			 enum i40e_flxpld_layer_idx layer_idx,
> +			 uint8_t raw_id)
> +{
> +	uint8_t field_idx;
> +
> +	field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
> +	/* Check if the configuration is conflicted */
> +	if (pf->fdir.flex_pit_flag[layer_idx] &&
> +	    (pf->fdir.flex_set[field_idx].src_offset != flex_pit->src_offset ||
> +	     pf->fdir.flex_set[field_idx].size != flex_pit->size ||
> +	     pf->fdir.flex_set[field_idx].dst_offset != flex_pit->dst_offset))
> +		return -1;
> +
> +	/* Check if the configuration exists. */
> +	if (pf->fdir.flex_pit_flag[layer_idx] &&
> +	    (pf->fdir.flex_set[field_idx].src_offset == flex_pit->src_offset &&
> +	     pf->fdir.flex_set[field_idx].size == flex_pit->size &&
> +	     pf->fdir.flex_set[field_idx].dst_offset == flex_pit->dst_offset))
> +		return 1;
> +
> +	pf->fdir.flex_set[field_idx].src_offset =
> +		flex_pit->src_offset;
> +	pf->fdir.flex_set[field_idx].size =
> +		flex_pit->size;
> +	pf->fdir.flex_set[field_idx].dst_offset =
> +		flex_pit->dst_offset;
> +
> +	return 0;
> +}
> +
> +static void
> +i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf,
> +			    enum i40e_flxpld_layer_idx layer_idx,
> +			    uint8_t raw_id)
> +{
> +	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> +	uint32_t flx_pit, flx_ort;
> +	uint8_t field_idx;
> +	uint16_t min_next_off = 0;  /* in words */
> +	uint8_t i;
> +
> +	if (raw_id) {
> +		flx_ort = (1 << I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT) |
> +			  (raw_id << I40E_GLQF_ORT_FIELD_CNT_SHIFT) |
> +			  (layer_idx * I40E_MAX_FLXPLD_FIED);
> +		I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33 + layer_idx),
> flx_ort);
> +	}
> +
> +	/* Set flex pit */
> +	for (i = 0; i < raw_id; i++) {
> +		field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> +		flx_pit = MK_FLX_PIT(pf->fdir.flex_set[field_idx].src_offset,
> +				     pf->fdir.flex_set[field_idx].size,
> +				     pf->fdir.flex_set[field_idx].dst_offset);
> +
> +		I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> +		min_next_off = pf->fdir.flex_set[field_idx].src_offset +
> +			pf->fdir.flex_set[field_idx].size;
> +	}
> +
> +	for (; i < I40E_MAX_FLXPLD_FIED; i++) {
> +		/* set the non-used register obeying register's constrain */
> +		field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> +		flx_pit = MK_FLX_PIT(min_next_off,
> NONUSE_FLX_PIT_FSIZE,
> +				     NONUSE_FLX_PIT_DEST_OFF);
> +		I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> +		min_next_off++;
> +	}
> +
> +	pf->fdir.flex_pit_flag[layer_idx] = 1; }
> +
>  static int
>  i40e_flow_store_flex_mask(struct i40e_pf *pf,
>  			  enum i40e_filter_pctype pctype,
> @@ -1889,13 +1964,17 @@ i40e_flow_add_del_fdir_filter(struct
> rte_eth_dev *dev,  {
>  	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data-
> >dev_private);
>  	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data-
> >dev_private);
> +	enum i40e_flxpld_layer_idx layer_idx = I40E_FLXPLD_L2_IDX;
>  	unsigned char *pkt = NULL;
>  	enum i40e_filter_pctype pctype;
>  	struct i40e_fdir_info *fdir_info = &pf->fdir;
>  	uint8_t flex_mask[I40E_FDIR_MAX_FLEX_LEN];
>  	struct i40e_fdir_filter *node;
>  	struct i40e_fdir_filter check_filter; /* Check if the filter exists */
> +	struct i40e_fdir_flex_pit flex_pit;
> +	bool cfg_flex_pit = true;
>  	bool wait_status = true;
> +	uint8_t field_idx;
>  	int ret = 0;
>  	int i;
> 
> @@ -1931,6 +2010,27 @@ i40e_flow_add_del_fdir_filter(struct rte_eth_dev
> *dev,
> 
>  	if (add) {
>  		if (!filter->input.flow_ext.customized_pctype) {
> +			for (i = 0; i < filter->input.flow_ext.raw_id; i++) {
> +				layer_idx = filter->input.flow_ext.layer_idx;
> +				field_idx = layer_idx *
> I40E_MAX_FLXPLD_FIED + i;
> +				flex_pit = filter-
> >input.flow_ext.flex_pit[field_idx];
> +
> +				/* Store flex pit to SW */
> +				ret = i40e_flow_store_flex_pit(pf, &flex_pit,
> +							       layer_idx, i);
> +				if (ret < 0) {
> +					PMD_DRV_LOG(ERR, "Conflict with
> the"
> +						    " first flexible rule.");
> +					return -EINVAL;
> +				} else if (ret > 0) {
> +					cfg_flex_pit = false;
> +				}
> +			}
> +
> +			if (cfg_flex_pit)
> +				i40e_flow_set_fdir_flex_pit(pf, layer_idx,
> +						filter-
> >input.flow_ext.raw_id);
> +
>  			/* Store flex mask to SW */
>  			for (i = 0; i < I40E_FDIR_MAX_FLEX_LEN; i++)
>  				flex_mask[i] =
> diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
> index 4f916494e..098ae13ab 100644
> --- a/drivers/net/i40e/i40e_flow.c
> +++ b/drivers/net/i40e/i40e_flow.c
> @@ -2240,81 +2240,6 @@ i40e_flow_check_raw_item(const struct
> rte_flow_item *item,
>  	return 0;
>  }
> 
> -static int
> -i40e_flow_store_flex_pit(struct i40e_pf *pf,
> -			 struct i40e_fdir_flex_pit *flex_pit,
> -			 enum i40e_flxpld_layer_idx layer_idx,
> -			 uint8_t raw_id)
> -{
> -	uint8_t field_idx;
> -
> -	field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + raw_id;
> -	/* Check if the configuration is conflicted */
> -	if (pf->fdir.flex_pit_flag[layer_idx] &&
> -	    (pf->fdir.flex_set[field_idx].src_offset != flex_pit->src_offset ||
> -	     pf->fdir.flex_set[field_idx].size != flex_pit->size ||
> -	     pf->fdir.flex_set[field_idx].dst_offset != flex_pit->dst_offset))
> -		return -1;
> -
> -	/* Check if the configuration exists. */
> -	if (pf->fdir.flex_pit_flag[layer_idx] &&
> -	    (pf->fdir.flex_set[field_idx].src_offset == flex_pit->src_offset &&
> -	     pf->fdir.flex_set[field_idx].size == flex_pit->size &&
> -	     pf->fdir.flex_set[field_idx].dst_offset == flex_pit->dst_offset))
> -		return 1;
> -
> -	pf->fdir.flex_set[field_idx].src_offset =
> -		flex_pit->src_offset;
> -	pf->fdir.flex_set[field_idx].size =
> -		flex_pit->size;
> -	pf->fdir.flex_set[field_idx].dst_offset =
> -		flex_pit->dst_offset;
> -
> -	return 0;
> -}
> -
> -static void
> -i40e_flow_set_fdir_flex_pit(struct i40e_pf *pf,
> -			    enum i40e_flxpld_layer_idx layer_idx,
> -			    uint8_t raw_id)
> -{
> -	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> -	uint32_t flx_pit, flx_ort;
> -	uint8_t field_idx;
> -	uint16_t min_next_off = 0;  /* in words */
> -	uint8_t i;
> -
> -	if (raw_id) {
> -		flx_ort = (1 << I40E_GLQF_ORT_FLX_PAYLOAD_SHIFT) |
> -			  (raw_id << I40E_GLQF_ORT_FIELD_CNT_SHIFT) |
> -			  (layer_idx * I40E_MAX_FLXPLD_FIED);
> -		I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33 + layer_idx),
> flx_ort);
> -	}
> -
> -	/* Set flex pit */
> -	for (i = 0; i < raw_id; i++) {
> -		field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> -		flx_pit = MK_FLX_PIT(pf->fdir.flex_set[field_idx].src_offset,
> -				     pf->fdir.flex_set[field_idx].size,
> -				     pf->fdir.flex_set[field_idx].dst_offset);
> -
> -		I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> -		min_next_off = pf->fdir.flex_set[field_idx].src_offset +
> -			pf->fdir.flex_set[field_idx].size;
> -	}
> -
> -	for (; i < I40E_MAX_FLXPLD_FIED; i++) {
> -		/* set the non-used register obeying register's constrain */
> -		field_idx = layer_idx * I40E_MAX_FLXPLD_FIED + i;
> -		flx_pit = MK_FLX_PIT(min_next_off,
> NONUSE_FLX_PIT_FSIZE,
> -				     NONUSE_FLX_PIT_DEST_OFF);
> -		I40E_WRITE_REG(hw, I40E_PRTQF_FLX_PIT(field_idx),
> flx_pit);
> -		min_next_off++;
> -	}
> -
> -	pf->fdir.flex_pit_flag[layer_idx] = 1;
> -}
> -
>  static int
>  i40e_flow_set_fdir_inset(struct i40e_pf *pf,
>  			 enum i40e_filter_pctype pctype,
> @@ -2534,10 +2459,10 @@ i40e_flow_parse_fdir_pattern(struct
> rte_eth_dev *dev,
>  	struct i40e_fdir_flex_pit flex_pit;
>  	uint8_t next_dst_off = 0;
>  	uint16_t flex_size;
> -	bool cfg_flex_pit = true;
>  	uint16_t ether_type;
>  	uint32_t vtc_flow_cpu;
>  	bool outer_ip = true;
> +	uint8_t field_idx;
>  	int ret;
> 
>  	memset(off_arr, 0, sizeof(off_arr));
> @@ -3089,6 +3014,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev
> *dev,
> 
>  			flex_size = 0;
>  			memset(&flex_pit, 0, sizeof(struct
> i40e_fdir_flex_pit));
> +			field_idx = layer_idx * I40E_MAX_FLXPLD_FIED +
> raw_id;
>  			flex_pit.size =
>  				raw_spec->length / sizeof(uint16_t);
>  			flex_pit.dst_offset =
> @@ -3115,18 +3041,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev
> *dev,
>  				return -rte_errno;
>  			}
> 
> -			/* Store flex pit to SW */
> -			ret = i40e_flow_store_flex_pit(pf, &flex_pit,
> -						       layer_idx, raw_id);
> -			if (ret < 0) {
> -				rte_flow_error_set(error, EINVAL,
> -				   RTE_FLOW_ERROR_TYPE_ITEM,
> -				   item,
> -				   "Conflict with the first flexible rule.");
> -				return -rte_errno;
> -			} else if (ret > 0)
> -				cfg_flex_pit = false;
> -
>  			for (i = 0; i < raw_spec->length; i++) {
>  				j = i + next_dst_off;
>  				filter->input.flow_ext.flexbytes[j] = @@ -
> 3137,6 +3051,11 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
> 
>  			next_dst_off += raw_spec->length;
>  			raw_id++;
> +
> +			memcpy(&filter->input.flow_ext.flex_pit[field_idx],
> +			       &flex_pit, sizeof(struct i40e_fdir_flex_pit));
> +			filter->input.flow_ext.layer_idx = layer_idx;
> +			filter->input.flow_ext.raw_id = raw_id;
>  			break;
>  		case RTE_FLOW_ITEM_TYPE_VF:
>  			vf_spec = item->spec;
> @@ -3222,9 +3141,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev
> *dev,
>  					   "Invalid pattern mask.");
>  			return -rte_errno;
>  		}
> -
> -		if (cfg_flex_pit)
> -			i40e_flow_set_fdir_flex_pit(pf, layer_idx, raw_id);

Seems that multiple switch case set the layer_idx not only the place you delete, please double check if these case all need to handle.

>  	}
> 
>  	filter->input.pctype = pctype;
> --
> 2.17.1


  reply	other threads:[~2020-11-04  9:19 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-04  8:29 [dpdk-dev] [PATCH 0/2] net/i40e: fix incorrect FDIR flex configuration Chenxu Di
2020-11-04  8:29 ` [dpdk-dev] [PATCH 1/2] net/i40e: fix incorrect FDIR flex mask Chenxu Di
2020-11-04  9:40   ` Guo, Jia
2020-11-04  9:49     ` Di, ChenxuX
2020-11-05  8:40       ` Di, ChenxuX
2020-11-04  8:29 ` [dpdk-dev] [PATCH 2/2] net/i40e: fix incorrect FDIR flex pit Chenxu Di
2020-11-04  9:18   ` Guo, Jia [this message]
2020-11-06  6:47 ` [dpdk-dev] [PATCH v2] net/i40e: fix incorrect FDIR flex configuration Chenxu Di
2020-11-09  3:23   ` Zhou, JunX W
2020-11-10  5:42 ` [dpdk-dev] [PATCH v3] " Chenxu Di
2020-11-10  6:54   ` Guo, Jia
2020-11-10  7:08 ` [dpdk-dev] [PATCH v4] " Chenxu Di
2020-11-10  8:27   ` Zhang, Qi Z

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=36fa7db4c27244ddb043fb7fd3e0f11a@intel.com \
    --to=jia.guo@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=chenxux.di@intel.com \
    --cc=dev@dpdk.org \
    --cc=haiyue.wang@intel.com \
    --cc=stable@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.