[PATCH v6 08/27] net/i40e: remove global pattern variable

Anatoly Burakov
2026-02-19T16:24:20Z

When parsing flow patterns, current code cleans up the pattern list by
removing void flow items, and copies the patterns into an array. That
array, when dealing with under 32 flow items, is allocated on the stack,
but when the pattern is big enough, a new list is dynamically allocated.
This allocated list is a global variable, and is allocated using
rte_zmalloc call which seems like overkill for this use case.

Remove the global variable, and replace the split behavior with
unconditional allocation.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
---
drivers/net/intel/i40e/i40e_flow.c | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/net/intel/i40e/i40e_flow.c b/drivers/net/intel/i40e/i40e_flow.c
index e611de0c06..2791139e59 100644
--- a/drivers/net/intel/i40e/i40e_flow.c
+++ b/drivers/net/intel/i40e/i40e_flow.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
+#include <stdlib.h>

#include <rte_debug.h>
#include <rte_ether.h>
@@ -145,9 +146,6 @@ const struct rte_flow_ops i40e_flow_ops = {
.query = i40e_flow_query,
};

-/* internal pattern w/o VOID items */
-struct rte_flow_item g_items[32];
-
/* Pattern matched ethertype filter */
static enum rte_flow_item_type pattern_ethertype[] = {
RTE_FLOW_ITEM_TYPE_ETH,
@@ -3837,19 +3835,13 @@ i40e_flow_check(struct rte_eth_dev *dev,
i++;
}
item_num++;
-
- if (item_num <= ARRAY_SIZE(g_items)) {
- items = g_items;
- } else {
- items = rte_zmalloc("i40e_pattern",
- item_num * sizeof(struct rte_flow_item), 0);
- if (!items) {
- rte_flow_error_set(error, ENOMEM,
- RTE_FLOW_ERROR_TYPE_ITEM_NUM,
- NULL,
- "No memory for PMD internal items.");
- return -ENOMEM;
- }
+ items = calloc(item_num, sizeof(struct rte_flow_item));
+ if (items == NULL) {
+ rte_flow_error_set(error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_ITEM_NUM,
+ NULL,
+ "No memory for PMD internal items.");
+ return -ENOMEM;
}

i40e_pattern_skip_void_item(items, pattern);
@@ -3862,8 +3854,7 @@ i40e_flow_check(struct rte_eth_dev *dev,
RTE_FLOW_ERROR_TYPE_ITEM,
pattern, "Unsupported pattern");

- if (items != g_items)
- rte_free(items);
+ free(items);
return -rte_errno;
}

@@ -3873,8 +3864,7 @@ i40e_flow_check(struct rte_eth_dev *dev,
flag = true;
} while ((ret < 0) && (i < RTE_DIM(i40e_supported_patterns)));

- if (items != g_items)
- rte_free(items);
+ free(items);

return ret;
}
--
2.47.3