From: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
To: dev@dpdk.org
Cc: matan@mellanox.com, rasland@mellanox.com, thomas@monjalon.net,
orika@mellanox.com, Yongseok Koh <yskoh@mellanox.com>
Subject: [dpdk-dev] [PATCH 02/20] net/mlx5: update modify header action translator
Date: Tue, 5 Nov 2019 08:01:37 +0000 [thread overview]
Message-ID: <1572940915-29416-3-git-send-email-viacheslavo@mellanox.com> (raw)
In-Reply-To: <1572940915-29416-1-git-send-email-viacheslavo@mellanox.com>
When composing device command for modify header action, provided mask
should be taken more accurate into account thus length and offset
in action should be set accordingly at precise bit-wise boundaries.
For the future use, metadata register copy action is also added.
Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
---
drivers/net/mlx5/mlx5_flow_dv.c | 148 ++++++++++++++++++++++++++++++----------
drivers/net/mlx5/mlx5_prm.h | 18 +++--
2 files changed, 126 insertions(+), 40 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 42c265f..3df2609 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -240,12 +240,62 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Fetch 1, 2, 3 or 4 byte field from the byte array
+ * and return as unsigned integer in host-endian format.
+ *
+ * @param[in] data
+ * Pointer to data array.
+ * @param[in] size
+ * Size of field to extract.
+ *
+ * @return
+ * converted field in host endian format.
+ */
+static inline uint32_t
+flow_dv_fetch_field(const uint8_t *data, uint32_t size)
+{
+ uint32_t ret;
+
+ switch (size) {
+ case 1:
+ ret = *data;
+ break;
+ case 2:
+ ret = rte_be_to_cpu_16(*(const unaligned_uint16_t *)data);
+ break;
+ case 3:
+ ret = rte_be_to_cpu_16(*(const unaligned_uint16_t *)data);
+ ret = (ret << 8) | *(data + sizeof(uint16_t));
+ break;
+ case 4:
+ ret = rte_be_to_cpu_32(*(const unaligned_uint32_t *)data);
+ break;
+ default:
+ assert(false);
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+/**
* Convert modify-header action to DV specification.
*
+ * Data length of each action is determined by provided field description
+ * and the item mask. Data bit offset and width of each action is determined
+ * by provided item mask.
+ *
* @param[in] item
* Pointer to item specification.
* @param[in] field
* Pointer to field modification information.
+ * For MLX5_MODIFICATION_TYPE_SET specifies destination field.
+ * For MLX5_MODIFICATION_TYPE_ADD specifies destination field.
+ * For MLX5_MODIFICATION_TYPE_COPY specifies source field.
+ * @param[in] dcopy
+ * Destination field info for MLX5_MODIFICATION_TYPE_COPY in @type.
+ * Negative offset value sets the same offset as source offset.
+ * size field is ignored, value is taken from source field.
* @param[in,out] resource
* Pointer to the modify-header resource.
* @param[in] type
@@ -259,38 +309,66 @@ struct field_modify_info modify_tcp[] = {
static int
flow_dv_convert_modify_action(struct rte_flow_item *item,
struct field_modify_info *field,
+ struct field_modify_info *dcopy,
struct mlx5_flow_dv_modify_hdr_resource *resource,
- uint32_t type,
- struct rte_flow_error *error)
+ uint32_t type, struct rte_flow_error *error)
{
uint32_t i = resource->actions_num;
struct mlx5_modification_cmd *actions = resource->actions;
- const uint8_t *spec = item->spec;
- const uint8_t *mask = item->mask;
- uint32_t set;
-
- while (field->size) {
- set = 0;
- /* Generate modify command for each mask segment. */
- memcpy(&set, &mask[field->offset], field->size);
- if (set) {
- if (i >= MLX5_MODIFY_NUM)
- return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, NULL,
- "too many items to modify");
- actions[i].action_type = type;
- actions[i].field = field->id;
- actions[i].length = field->size ==
- 4 ? 0 : field->size * 8;
- rte_memcpy(&actions[i].data[4 - field->size],
- &spec[field->offset], field->size);
- actions[i].data0 = rte_cpu_to_be_32(actions[i].data0);
- ++i;
+
+ /*
+ * The item and mask are provided in big-endian format.
+ * The fields should be presented as in big-endian format either.
+ * Mask must be always present, it defines the actual field width.
+ */
+ assert(item->mask);
+ assert(field->size);
+ do {
+ unsigned int size_b;
+ unsigned int off_b;
+ uint32_t mask;
+ uint32_t data;
+
+ if (i >= MLX5_MODIFY_NUM)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "too many items to modify");
+ /* Fetch variable byte size mask from the array. */
+ mask = flow_dv_fetch_field((const uint8_t *)item->mask +
+ field->offset, field->size);
+ if (!mask)
+ continue;
+ /* Deduce actual data width in bits from mask value. */
+ off_b = rte_bsf32(mask);
+ size_b = sizeof(uint32_t) * CHAR_BIT -
+ off_b - __builtin_clz(mask);
+ assert(size_b);
+ size_b = size_b == sizeof(uint32_t) * CHAR_BIT ? 0 : size_b;
+ actions[i].action_type = type;
+ actions[i].field = field->id;
+ actions[i].offset = off_b;
+ actions[i].length = size_b;
+ /* Convert entire record to expected big-endian format. */
+ actions[i].data0 = rte_cpu_to_be_32(actions[i].data0);
+ if (type == MLX5_MODIFICATION_TYPE_COPY) {
+ assert(dcopy);
+ actions[i].dst_field = dcopy->id;
+ actions[i].dst_offset =
+ (int)dcopy->offset < 0 ? off_b : dcopy->offset;
+ /* Convert entire record to big-endian format. */
+ actions[i].data1 = rte_cpu_to_be_32(actions[i].data1);
+ } else {
+ assert(item->spec);
+ data = flow_dv_fetch_field((const uint8_t *)item->spec +
+ field->offset, field->size);
+ /* Shift out the trailing masked bits from data. */
+ data = (data & mask) >> off_b;
+ actions[i].data1 = rte_cpu_to_be_32(data);
}
- if (resource->actions_num != i)
- resource->actions_num = i;
- field++;
- }
+ ++i;
+ ++field;
+ } while (field->size);
+ resource->actions_num = i;
if (!resource->actions_num)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -334,7 +412,7 @@ struct field_modify_info modify_tcp[] = {
}
item.spec = &ipv4;
item.mask = &ipv4_mask;
- return flow_dv_convert_modify_action(&item, modify_ipv4, resource,
+ return flow_dv_convert_modify_action(&item, modify_ipv4, NULL, resource,
MLX5_MODIFICATION_TYPE_SET, error);
}
@@ -380,7 +458,7 @@ struct field_modify_info modify_tcp[] = {
}
item.spec = &ipv6;
item.mask = &ipv6_mask;
- return flow_dv_convert_modify_action(&item, modify_ipv6, resource,
+ return flow_dv_convert_modify_action(&item, modify_ipv6, NULL, resource,
MLX5_MODIFICATION_TYPE_SET, error);
}
@@ -426,7 +504,7 @@ struct field_modify_info modify_tcp[] = {
}
item.spec = ð
item.mask = ð_mask;
- return flow_dv_convert_modify_action(&item, modify_eth, resource,
+ return flow_dv_convert_modify_action(&item, modify_eth, NULL, resource,
MLX5_MODIFICATION_TYPE_SET, error);
}
@@ -540,7 +618,7 @@ struct field_modify_info modify_tcp[] = {
item.mask = &tcp_mask;
field = modify_tcp;
}
- return flow_dv_convert_modify_action(&item, field, resource,
+ return flow_dv_convert_modify_action(&item, field, NULL, resource,
MLX5_MODIFICATION_TYPE_SET, error);
}
@@ -600,7 +678,7 @@ struct field_modify_info modify_tcp[] = {
item.mask = &ipv6_mask;
field = modify_ipv6;
}
- return flow_dv_convert_modify_action(&item, field, resource,
+ return flow_dv_convert_modify_action(&item, field, NULL, resource,
MLX5_MODIFICATION_TYPE_SET, error);
}
@@ -657,7 +735,7 @@ struct field_modify_info modify_tcp[] = {
item.mask = &ipv6_mask;
field = modify_ipv6;
}
- return flow_dv_convert_modify_action(&item, field, resource,
+ return flow_dv_convert_modify_action(&item, field, NULL, resource,
MLX5_MODIFICATION_TYPE_ADD, error);
}
@@ -702,7 +780,7 @@ struct field_modify_info modify_tcp[] = {
item.type = RTE_FLOW_ITEM_TYPE_TCP;
item.spec = &tcp;
item.mask = &tcp_mask;
- return flow_dv_convert_modify_action(&item, modify_tcp, resource,
+ return flow_dv_convert_modify_action(&item, modify_tcp, NULL, resource,
MLX5_MODIFICATION_TYPE_ADD, error);
}
@@ -747,7 +825,7 @@ struct field_modify_info modify_tcp[] = {
item.type = RTE_FLOW_ITEM_TYPE_TCP;
item.spec = &tcp;
item.mask = &tcp_mask;
- return flow_dv_convert_modify_action(&item, modify_tcp, resource,
+ return flow_dv_convert_modify_action(&item, modify_tcp, NULL, resource,
MLX5_MODIFICATION_TYPE_ADD, error);
}
diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
index 96b9166..b9e53f5 100644
--- a/drivers/net/mlx5/mlx5_prm.h
+++ b/drivers/net/mlx5/mlx5_prm.h
@@ -383,11 +383,12 @@ struct mlx5_cqe {
/* CQE format value. */
#define MLX5_COMPRESSED 0x3
-/* Write a specific data value to a field. */
-#define MLX5_MODIFICATION_TYPE_SET 1
-
-/* Add a specific data value to a field. */
-#define MLX5_MODIFICATION_TYPE_ADD 2
+/* Action type of header modification. */
+enum {
+ MLX5_MODIFICATION_TYPE_SET = 0x1,
+ MLX5_MODIFICATION_TYPE_ADD = 0x2,
+ MLX5_MODIFICATION_TYPE_COPY = 0x3,
+};
/* The field of packet to be modified. */
enum mlx5_modification_field {
@@ -470,6 +471,13 @@ struct mlx5_modification_cmd {
union {
uint32_t data1;
uint8_t data[4];
+ struct {
+ unsigned int rsvd2:8;
+ unsigned int dst_offset:5;
+ unsigned int rsvd3:3;
+ unsigned int dst_field:12;
+ unsigned int rsvd4:4;
+ };
};
};
--
1.8.3.1
next prev parent reply other threads:[~2019-11-05 8:02 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-05 8:01 [dpdk-dev] [PATCH 00/20] net/mlx5: implement extensive metadata feature Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 01/20] net/mlx5: convert internal tag endianness Viacheslav Ovsiienko
2019-11-05 8:01 ` Viacheslav Ovsiienko [this message]
2019-11-05 8:01 ` [dpdk-dev] [PATCH 03/20] net/mlx5: add metadata register copy Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 04/20] net/mlx5: refactor flow structure Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 05/20] net/mlx5: update flow functions Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 06/20] net/mlx5: update meta register matcher set Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 07/20] net/mlx5: rename structure and function Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 08/20] net/mlx5: check metadata registers availability Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 09/20] net/mlx5: add devarg for extensive metadata support Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 10/20] net/mlx5: adjust shared register according to mask Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 11/20] net/mlx5: check the maximal modify actions number Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 12/20] net/mlx5: update metadata register id query Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 13/20] net/mlx5: add flow tag support Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 14/20] net/mlx5: extend flow mark support Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 15/20] net/mlx5: extend flow meta data support Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 16/20] net/mlx5: add meta data support to Rx datapath Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 17/20] net/mlx5: add simple hash table Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 18/20] net/mlx5: introduce flow splitters chain Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 19/20] net/mlx5: split Rx flows to provide metadata copy Viacheslav Ovsiienko
2019-11-05 8:01 ` [dpdk-dev] [PATCH 20/20] net/mlx5: add metadata register copy table Viacheslav Ovsiienko
2019-11-05 9:35 ` [dpdk-dev] [PATCH 00/20] net/mlx5: implement extensive metadata feature Matan Azrad
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 00/19] " Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 01/19] net/mlx5: convert internal tag endianness Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 02/19] net/mlx5: update modify header action translator Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 03/19] net/mlx5: add metadata register copy Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 04/19] net/mlx5: refactor flow structure Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 05/19] net/mlx5: update flow functions Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 06/19] net/mlx5: update meta register matcher set Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 07/19] net/mlx5: rename structure and function Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 08/19] net/mlx5: check metadata registers availability Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 09/19] net/mlx5: add devarg for extensive metadata support Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 10/19] net/mlx5: adjust shared register according to mask Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 11/19] net/mlx5: check the maximal modify actions number Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 12/19] net/mlx5: update metadata register id query Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 13/19] net/mlx5: add flow tag support Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 14/19] net/mlx5: extend flow mark support Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 15/19] net/mlx5: extend flow meta data support Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 16/19] net/mlx5: add meta data support to Rx datapath Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 17/19] net/mlx5: introduce flow splitters chain Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 18/19] net/mlx5: split Rx flows to provide metadata copy Viacheslav Ovsiienko
2019-11-06 17:37 ` [dpdk-dev] [PATCH v2 19/19] net/mlx5: add metadata register copy table Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 00/19] net/mlx5: implement extensive metadata feature Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 01/19] net/mlx5: convert internal tag endianness Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 02/19] net/mlx5: update modify header action translator Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 03/19] net/mlx5: add metadata register copy Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 04/19] net/mlx5: refactor flow structure Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 05/19] net/mlx5: update flow functions Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 06/19] net/mlx5: update meta register matcher set Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 07/19] net/mlx5: rename structure and function Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 08/19] net/mlx5: check metadata registers availability Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 09/19] net/mlx5: add devarg for extensive metadata support Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 10/19] net/mlx5: adjust shared register according to mask Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 11/19] net/mlx5: check the maximal modify actions number Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 12/19] net/mlx5: update metadata register id query Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 13/19] net/mlx5: add flow tag support Viacheslav Ovsiienko
2019-11-07 17:09 ` [dpdk-dev] [PATCH v3 14/19] net/mlx5: extend flow mark support Viacheslav Ovsiienko
2019-11-07 17:10 ` [dpdk-dev] [PATCH v3 15/19] net/mlx5: extend flow meta data support Viacheslav Ovsiienko
2019-11-07 17:10 ` [dpdk-dev] [PATCH v3 16/19] net/mlx5: add meta data support to Rx datapath Viacheslav Ovsiienko
2019-11-25 14:24 ` David Marchand
2019-11-07 17:10 ` [dpdk-dev] [PATCH v3 17/19] net/mlx5: introduce flow splitters chain Viacheslav Ovsiienko
2019-11-07 17:10 ` [dpdk-dev] [PATCH v3 18/19] net/mlx5: split Rx flows to provide metadata copy Viacheslav Ovsiienko
2019-11-07 17:10 ` [dpdk-dev] [PATCH v3 19/19] net/mlx5: add metadata register copy table Viacheslav Ovsiienko
2019-11-07 22:46 ` [dpdk-dev] [PATCH v3 00/19] net/mlx5: implement extensive metadata feature Raslan Darawsheh
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=1572940915-29416-3-git-send-email-viacheslavo@mellanox.com \
--to=viacheslavo@mellanox.com \
--cc=dev@dpdk.org \
--cc=matan@mellanox.com \
--cc=orika@mellanox.com \
--cc=rasland@mellanox.com \
--cc=thomas@monjalon.net \
--cc=yskoh@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).