From: Raslan Darawsheh <rasland@mellanox.com>
To: Suanming Mou <suanmingm@mellanox.com>,
Slava Ovsiienko <viacheslavo@mellanox.com>,
Matan Azrad <matan@mellanox.com>
Cc: "dev@dpdk.org" <dev@dpdk.org>, "stable@dpdk.org" <stable@dpdk.org>
Subject: Re: [dpdk-dev] [PATCH] net/mlx5: fix VLAN actions in meter
Date: Thu, 20 Feb 2020 12:43:54 +0000 [thread overview]
Message-ID: <AM0PR05MB6707CC023913959F550A1A37C2130@AM0PR05MB6707.eurprd05.prod.outlook.com> (raw)
In-Reply-To: <1582184744-91629-1-git-send-email-suanmingm@mellanox.com>
Hi,
> -----Original Message-----
> From: Suanming Mou <suanmingm@mellanox.com>
> Sent: Thursday, February 20, 2020 9:46 AM
> To: Slava Ovsiienko <viacheslavo@mellanox.com>; Matan Azrad
> <matan@mellanox.com>
> Cc: dev@dpdk.org; Raslan Darawsheh <rasland@mellanox.com>;
> stable@dpdk.org
> Subject: [PATCH] net/mlx5: fix VLAN actions in meter
>
> Meter suffix subflow only has the port id and tag match item, if VLAN
> push and set VLAN id actions exist in the suffix subflow, the user
> defined VLAN items is required for the actions to set a correct VLAN
> id.
>
> Currently, the VLAN item stays in the meter prefix subflow. Without
> the VLAN item, VLAN id or pcp will not be inherited.
>
> Actions require the VLAN item as below:
> RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN
> RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID
>
> Add a private VLAN item to copy the user defined VLAN item to the meter
> suffix subflow, so the suffix subflow will have the chance to get the
> correct original VLAN id and pcp value from the VLAN item.
>
> Fixes: 9ea9b049a960 ("net/mlx5: split meter flow")
> Cc: stable@dpdk.org
>
> Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
> ---
> drivers/net/mlx5/mlx5_flow.c | 153 ++++++++++++++++++------------------
> ----
> drivers/net/mlx5/mlx5_flow.h | 4 ++
> drivers/net/mlx5/mlx5_flow_dv.c | 14 ++--
> 3 files changed, 82 insertions(+), 89 deletions(-)
>
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index e5d2e64..2a78c43 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -2664,26 +2664,6 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> }
>
> /**
> - * Get port id item from the item list.
> - *
> - * @param[in] item
> - * Pointer to the list of items.
> - *
> - * @return
> - * Pointer to the port id item if exist, else return NULL.
> - */
> -static const struct rte_flow_item *
> -find_port_id_item(const struct rte_flow_item *item)
> -{
> - MLX5_ASSERT(item);
> - for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
> - if (item->type == RTE_FLOW_ITEM_TYPE_PORT_ID)
> - return item;
> - }
> - return NULL;
> -}
> -
> -/**
> * Get RSS action from the action list.
> *
> * @param[in] actions
> @@ -3502,6 +3482,10 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> *
> * @param dev
> * Pointer to Ethernet device.
> + * @param[in] items
> + * Pattern specification (list terminated by the END pattern item).
> + * @param[out] sfx_items
> + * Suffix flow match items (list terminated by the END pattern item).
> * @param[in] actions
> * Associated actions (list terminated by the END action).
> * @param[out] actions_sfx
> @@ -3518,70 +3502,60 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> */
> static int
> flow_meter_split_prep(struct rte_eth_dev *dev,
> + const struct rte_flow_item items[],
> + struct rte_flow_item sfx_items[],
> const struct rte_flow_action actions[],
> struct rte_flow_action actions_sfx[],
> struct rte_flow_action actions_pre[])
> {
> struct rte_flow_action *tag_action = NULL;
> + struct rte_flow_item *tag_item;
> struct mlx5_rte_flow_action_set_tag *set_tag;
> struct rte_flow_error error;
> const struct rte_flow_action_raw_encap *raw_encap;
> const struct rte_flow_action_raw_decap *raw_decap;
> + struct mlx5_rte_flow_item_tag *tag_spec;
> + struct mlx5_rte_flow_item_tag *tag_mask;
> uint32_t tag_id;
> + bool copy_vlan = false;
>
> /* Prepare the actions for prefix and suffix flow. */
> for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
> + struct rte_flow_action **action_cur = NULL;
> +
> switch (actions->type) {
> case RTE_FLOW_ACTION_TYPE_METER:
> /* Add the extra tag action first. */
> tag_action = actions_pre;
> tag_action->type =
> MLX5_RTE_FLOW_ACTION_TYPE_TAG;
> actions_pre++;
> - memcpy(actions_pre, actions,
> - sizeof(struct rte_flow_action));
> - actions_pre++;
> + action_cur = &actions_pre;
> break;
> case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP:
> case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP:
> - memcpy(actions_pre, actions,
> - sizeof(struct rte_flow_action));
> - actions_pre++;
> + action_cur = &actions_pre;
> break;
> case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
> raw_encap = actions->conf;
> - if (raw_encap->size >
> - (sizeof(struct rte_flow_item_eth) +
> - sizeof(struct rte_flow_item_ipv4))) {
> - memcpy(actions_sfx, actions,
> - sizeof(struct rte_flow_action));
> - actions_sfx++;
> - } else {
> - rte_memcpy(actions_pre, actions,
> - sizeof(struct rte_flow_action));
> - actions_pre++;
> - }
> + if (raw_encap->size <
> MLX5_ENCAPSULATION_DECISION_SIZE)
> + action_cur = &actions_pre;
> break;
> case RTE_FLOW_ACTION_TYPE_RAW_DECAP:
> raw_decap = actions->conf;
> - /* Size 0 decap means 50 bytes as vxlan decap. */
> - if (raw_decap->size && (raw_decap->size <
> - (sizeof(struct rte_flow_item_eth) +
> - sizeof(struct rte_flow_item_ipv4)))) {
> - memcpy(actions_sfx, actions,
> - sizeof(struct rte_flow_action));
> - actions_sfx++;
> - } else {
> - rte_memcpy(actions_pre, actions,
> - sizeof(struct rte_flow_action));
> - actions_pre++;
> - }
> + if (raw_decap->size >
> MLX5_ENCAPSULATION_DECISION_SIZE)
> + action_cur = &actions_pre;
> + break;
> + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
> + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
> + copy_vlan = true;
> break;
> default:
> - memcpy(actions_sfx, actions,
> - sizeof(struct rte_flow_action));
> - actions_sfx++;
> break;
> }
> + if (!action_cur)
> + action_cur = &actions_sfx;
> + memcpy(*action_cur, actions, sizeof(struct
> rte_flow_action));
> + (*action_cur)++;
> }
> /* Add end action to the actions. */
> actions_sfx->type = RTE_FLOW_ACTION_TYPE_END;
> @@ -3597,6 +3571,42 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> set_tag->data = tag_id << MLX5_MTR_COLOR_BITS;
> assert(tag_action);
> tag_action->conf = set_tag;
> + /* Prepare the suffix subflow items. */
> + tag_item = sfx_items++;
> + for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
> + int item_type = items->type;
> +
> + switch (item_type) {
> + case RTE_FLOW_ITEM_TYPE_PORT_ID:
> + memcpy(sfx_items, items, sizeof(*sfx_items));
> + sfx_items++;
> + break;
> + case RTE_FLOW_ITEM_TYPE_VLAN:
> + if (copy_vlan) {
> + memcpy(sfx_items, items,
> sizeof(*sfx_items));
> + /*
> + * Convert to internal match item, it is used
> + * for vlan push and set vid.
> + */
> + sfx_items->type =
> MLX5_RTE_FLOW_ITEM_TYPE_VLAN;
> + sfx_items++;
> + }
> + break;
> + default:
> + break;
> + }
> + }
> + sfx_items->type = RTE_FLOW_ITEM_TYPE_END;
> + sfx_items++;
> + tag_spec = (struct mlx5_rte_flow_item_tag *)sfx_items;
> + tag_spec->data = tag_id << MLX5_MTR_COLOR_BITS;
> + tag_spec->id = mlx5_flow_get_reg_id(dev, MLX5_MTR_SFX, 0,
> &error);
> + tag_mask = tag_spec + 1;
> + tag_mask->data = 0xffffff00;
> + tag_item->type = MLX5_RTE_FLOW_ITEM_TYPE_TAG;
> + tag_item->spec = tag_spec;
> + tag_item->last = NULL;
> + tag_item->mask = tag_mask;
> return tag_id;
> }
>
> @@ -4023,7 +4033,6 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> struct rte_flow_action *sfx_actions = NULL;
> struct rte_flow_action *pre_actions = NULL;
> struct rte_flow_item *sfx_items = NULL;
> - const struct rte_flow_item *sfx_port_id_item;
> struct mlx5_flow *dev_flow = NULL;
> struct rte_flow_attr sfx_attr = *attr;
> uint32_t mtr = 0;
> @@ -4036,13 +4045,11 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> if (priv->mtr_en)
> actions_n = flow_check_meter_action(actions, &mtr);
> if (mtr) {
> - struct mlx5_rte_flow_item_tag *tag_spec;
> - struct mlx5_rte_flow_item_tag *tag_mask;
> /* The five prefix actions: meter, decap, encap, tag, end. */
> act_size = sizeof(struct rte_flow_action) * (actions_n + 5) +
> - sizeof(struct rte_flow_action_set_tag);
> - /* tag, end. */
> -#define METER_SUFFIX_ITEM 3
> + sizeof(struct mlx5_rte_flow_action_set_tag);
> + /* tag, vlan, port id, end. */
> +#define METER_SUFFIX_ITEM 4
> item_size = sizeof(struct rte_flow_item) *
> METER_SUFFIX_ITEM +
> sizeof(struct mlx5_rte_flow_item_tag) * 2;
> sfx_actions = rte_zmalloc(__func__, (act_size + item_size),
> 0);
> @@ -4051,9 +4058,12 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
>
> RTE_FLOW_ERROR_TYPE_ACTION,
> NULL, "no memory to split "
> "meter flow");
> + sfx_items = (struct rte_flow_item *)((char *)sfx_actions +
> + act_size);
> pre_actions = sfx_actions + actions_n;
> - mtr_tag_id = flow_meter_split_prep(dev, actions,
> sfx_actions,
> - pre_actions);
> + mtr_tag_id = flow_meter_split_prep(dev, items, sfx_items,
> + actions, sfx_actions,
> + pre_actions);
> if (!mtr_tag_id) {
> ret = -rte_errno;
> goto exit;
> @@ -4067,29 +4077,6 @@ uint32_t mlx5_flow_adjust_priority(struct
> rte_eth_dev *dev, int32_t priority,
> goto exit;
> }
> dev_flow->mtr_flow_id = mtr_tag_id;
> - /* Prepare the suffix flow match pattern. */
> - sfx_items = (struct rte_flow_item *)((char *)sfx_actions +
> - act_size);
> - tag_spec = (struct mlx5_rte_flow_item_tag *)(sfx_items +
> - METER_SUFFIX_ITEM);
> - tag_spec->data = dev_flow->mtr_flow_id <<
> MLX5_MTR_COLOR_BITS;
> - tag_spec->id = mlx5_flow_get_reg_id(dev, MLX5_MTR_SFX,
> 0,
> - error);
> - tag_mask = tag_spec + 1;
> - tag_mask->data = 0xffffff00;
> - sfx_items->type = MLX5_RTE_FLOW_ITEM_TYPE_TAG;
> - sfx_items->spec = tag_spec;
> - sfx_items->last = NULL;
> - sfx_items->mask = tag_mask;
> - sfx_items++;
> - sfx_port_id_item = find_port_id_item(items);
> - if (sfx_port_id_item) {
> - memcpy(sfx_items, sfx_port_id_item,
> - sizeof(*sfx_items));
> - sfx_items++;
> - }
> - sfx_items->type = RTE_FLOW_ITEM_TYPE_END;
> - sfx_items -= sfx_port_id_item ? 2 : 1;
> /* Setting the sfx group atrr. */
> sfx_attr.group = sfx_attr.transfer ?
> (MLX5_FLOW_TABLE_LEVEL_SUFFIX - 1) :
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 791f3bd..13c8589 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -34,6 +34,7 @@ enum mlx5_rte_flow_item_type {
> MLX5_RTE_FLOW_ITEM_TYPE_END = INT_MIN,
> MLX5_RTE_FLOW_ITEM_TYPE_TAG,
> MLX5_RTE_FLOW_ITEM_TYPE_TX_QUEUE,
> + MLX5_RTE_FLOW_ITEM_TYPE_VLAN,
> };
>
> /* Private (internal) rte flow actions. */
> @@ -328,6 +329,9 @@ enum mlx5_feature_name {
> #define MLX5_GENEVE_OPT_LEN_0 14
> #define MLX5_GENEVE_OPT_LEN_1 63
>
> +#define MLX5_ENCAPSULATION_DECISION_SIZE (sizeof(struct
> rte_flow_item_eth) + \
> + sizeof(struct rte_flow_item_ipv4))
> +
> enum mlx5_flow_drv_type {
> MLX5_FLOW_TYPE_MIN,
> MLX5_FLOW_TYPE_DV,
> diff --git a/drivers/net/mlx5/mlx5_flow_dv.c
> b/drivers/net/mlx5/mlx5_flow_dv.c
> index 3fac288..2437e55 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -54,8 +54,6 @@
> #define MLX5DV_DR_ACTION_FLAGS_ROOT_LEVEL 1
> #endif
>
> -#define MLX5_ENCAPSULATION_DECISION_SIZE (sizeof(struct
> rte_flow_item_eth) + \
> - sizeof(struct rte_flow_item_ipv4))
> /* VLAN header definitions */
> #define MLX5DV_FLOW_VLAN_PCP_SHIFT 13
> #define MLX5DV_FLOW_VLAN_PCP_MASK (0x7 <<
> MLX5DV_FLOW_VLAN_PCP_SHIFT)
> @@ -1757,10 +1755,14 @@ struct field_modify_info modify_tcp[] = {
>
> if (items == NULL)
> return;
> - for (; items->type != RTE_FLOW_ITEM_TYPE_END &&
> - items->type != RTE_FLOW_ITEM_TYPE_VLAN; items++)
> - ;
> - if (items->type == RTE_FLOW_ITEM_TYPE_VLAN) {
> + for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
> + int type = items->type;
> +
> + if (type == RTE_FLOW_ITEM_TYPE_VLAN ||
> + type == MLX5_RTE_FLOW_ITEM_TYPE_VLAN)
> + break;
> + }
> + if (items->type != RTE_FLOW_ITEM_TYPE_END) {
> const struct rte_flow_item_vlan *vlan_m = items->mask;
> const struct rte_flow_item_vlan *vlan_v = items->spec;
>
> --
> 1.8.3.1
Patch applied to next-net-mlx,
Kindest regards,
Raslan Darawsheh
prev parent reply other threads:[~2020-02-20 12:43 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-20 7:45 Suanming Mou
2020-02-20 7:52 ` Matan Azrad
2020-02-20 12:43 ` Raslan Darawsheh [this message]
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=AM0PR05MB6707CC023913959F550A1A37C2130@AM0PR05MB6707.eurprd05.prod.outlook.com \
--to=rasland@mellanox.com \
--cc=dev@dpdk.org \
--cc=matan@mellanox.com \
--cc=stable@dpdk.org \
--cc=suanmingm@mellanox.com \
--cc=viacheslavo@mellanox.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).