* [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling
@ 2026-10-13 14:00 Zhang Tengfei
2026-10-13 14:00 ` [PATCH 1/3] net/txgbe: fix Rx packet buffer size with flow director Zhang Tengfei
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Zhang Tengfei @ 2026-10-13 14:00 UTC (permalink / raw)
To: dev; +Cc: stephen, Zhang Tengfei, jiawenwu, zaiyuwang
Enabling Flow Director reduces the Rx packet buffer 0 to reserve memory
for the filter table, but the size was computed from the current
register value and never restored when FDIR was no longer used. Since
the FDIR mode is reset when the last rule is removed, on flush, or when
enabling FDIR fails, the next rule enabled FDIR again and shrank the
buffer once more, until it underflowed. Validating a rule also enabled
FDIR.
Patch 1 computes the buffer size from the default packet buffer size,
which alone stops the repeated reduction.
Patch 2 stops enabling FDIR from flow validate and rolls back the mode
when the first rule fails.
Patch 3 disables FDIR and restores the buffer when no rule is left.
The same issue was fixed in ixgbe:
<https://patches.dpdk.org/project/dpdk/patch/20260927042545.45152-1-zhtfdev@gmail.com>
Compile tested only.
Zhang Tengfei (3):
net/txgbe: fix Rx packet buffer size with flow director
net/txgbe: do not enable flow director on flow validate
net/txgbe: disable flow director when no rule is left
drivers/net/txgbe/txgbe_ethdev.h | 1 +
drivers/net/txgbe/txgbe_fdir.c | 36 +++++++++++++++----
drivers/net/txgbe/txgbe_flow.c | 60 +++++++++++++++++---------------
3 files changed, 62 insertions(+), 35 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] net/txgbe: fix Rx packet buffer size with flow director
2026-10-13 14:00 [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Zhang Tengfei
@ 2026-10-13 14:00 ` Zhang Tengfei
2026-10-13 14:00 ` [PATCH 2/3] net/txgbe: do not enable flow director on flow validate Zhang Tengfei
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Zhang Tengfei @ 2026-10-13 14:00 UTC (permalink / raw)
To: dev; +Cc: stephen, Zhang Tengfei, jiawenwu, zaiyuwang, stable
Enabling Flow Director reduces PBRXSIZE(0) to reserve packet buffer
memory for the filter table. The new size was computed from the
current register value, but the FDIR mode is reset to none when the
last rule is destroyed, on flush, or when enabling FDIR fails, without
restoring the buffer. The next FDIR rule created or validated then
enabled FDIR again and reduced the buffer a second time, until the
size underflowed.
Compute PBRXSIZE(0) from the default packet buffer size instead.
Fixes: ea230dda16ad ("net/txgbe: configure flow director filter")
Cc: stable@dpdk.org
Signed-off-by: Zhang Tengfei <zhtfdev@gmail.com>
---
drivers/net/txgbe/txgbe_fdir.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_fdir.c b/drivers/net/txgbe/txgbe_fdir.c
index 67f586ffc7..cee38a42b8 100644
--- a/drivers/net/txgbe/txgbe_fdir.c
+++ b/drivers/net/txgbe/txgbe_fdir.c
@@ -390,11 +390,10 @@ txgbe_fdir_configure(struct rte_eth_dev *dev)
/*
* Before enabling Flow Director, the Rx Packet Buffer size
- * must be reduced. The new value is the current size minus
+ * must be reduced. The new value is the default size minus
* flow director memory usage size.
*/
- pbsize = rd32(hw, TXGBE_PBRXSIZE(0));
- pbsize -= TXGBD_FDIRCTL_BUF_BYTE(fdirctrl);
+ pbsize = (hw->mac.rx_pb_size << 10) - TXGBD_FDIRCTL_BUF_BYTE(fdirctrl);
wr32(hw, TXGBE_PBRXSIZE(0), pbsize);
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] net/txgbe: do not enable flow director on flow validate
2026-10-13 14:00 [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Zhang Tengfei
2026-10-13 14:00 ` [PATCH 1/3] net/txgbe: fix Rx packet buffer size with flow director Zhang Tengfei
@ 2026-10-13 14:00 ` Zhang Tengfei
2026-10-13 14:00 ` [PATCH 3/3] net/txgbe: disable flow director when no rule is left Zhang Tengfei
2026-10-13 14:45 ` [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Zhang Tengfei @ 2026-10-13 14:00 UTC (permalink / raw)
To: dev; +Cc: stephen, Zhang Tengfei, jiawenwu, zaiyuwang, stable
Flow Director was enabled and its mode recorded while parsing a rule,
so validating a rule configured the hardware, and the mode stayed
locked when the rule was rejected afterwards, e.g. for an invalid
queue or when the rule could not be programmed.
Enable Flow Director only when creating the rule, and reset the mode
if the first rule fails.
Fixes: 5007ac13189d ("ethdev: remove deprecated Flow Director configuration")
Cc: stable@dpdk.org
Signed-off-by: Zhang Tengfei <zhtfdev@gmail.com>
---
drivers/net/txgbe/txgbe_flow.c | 55 +++++++++++++++++-----------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_flow.c b/drivers/net/txgbe/txgbe_flow.c
index f8d8c6850d..f2fc589a10 100644
--- a/drivers/net/txgbe/txgbe_flow.c
+++ b/drivers/net/txgbe/txgbe_flow.c
@@ -2966,16 +2966,9 @@ txgbe_parse_fdir_filter(struct rte_eth_dev *dev,
if (!txgbe_is_pf(TXGBE_DEV_HW(dev)))
return ret;
- if (fdir_conf->mode == RTE_FDIR_MODE_NONE) {
- fdir_conf->mode = rule->mode;
- ret = txgbe_fdir_configure(dev);
- if (ret) {
- fdir_conf->mode = RTE_FDIR_MODE_NONE;
- return ret;
- }
- } else if (fdir_conf->mode != rule->mode) {
+ if (fdir_conf->mode != RTE_FDIR_MODE_NONE &&
+ fdir_conf->mode != rule->mode)
return -ENOTSUP;
- }
if (rule->queue >= dev->data->nb_rx_queues)
return -ENOTSUP;
@@ -3208,17 +3201,19 @@ txgbe_flow_create(struct rte_eth_dev *dev,
struct txgbe_fdir_rule fdir_rule;
struct txgbe_l2_tunnel_conf l2_tn_filter;
struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(dev);
+ struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
struct txgbe_rte_flow_rss_conf rss_conf;
struct rte_flow *flow = NULL;
struct txgbe_ntuple_filter_ele *ntuple_filter_ptr;
struct txgbe_ethertype_filter_ele *ethertype_filter_ptr;
struct txgbe_eth_syn_filter_ele *syn_filter_ptr;
struct txgbe_eth_l2_tunnel_conf_ele *l2_tn_filter_ptr;
- struct txgbe_fdir_rule_ele *fdir_rule_ptr;
+ struct txgbe_fdir_rule_ele *fdir_rule_ptr = NULL;
struct txgbe_rss_conf_ele *rss_filter_ptr;
struct txgbe_flow_mem *txgbe_flow_mem_ptr;
struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
uint8_t first_mask = FALSE;
+ bool fdir_configured = false;
flow = rte_zmalloc("txgbe_rte_flow", sizeof(struct rte_flow), 0);
if (!flow) {
@@ -3360,6 +3355,16 @@ txgbe_flow_create(struct rte_eth_dev *dev,
goto out;
}
+ if (fdir_conf->mode == RTE_FDIR_MODE_NONE) {
+ fdir_conf->mode = fdir_rule.mode;
+ ret = txgbe_fdir_configure(dev);
+ if (ret) {
+ fdir_conf->mode = RTE_FDIR_MODE_NONE;
+ goto fdir_out;
+ }
+ fdir_configured = true;
+ }
+
/* A mask cannot be deleted. */
if (fdir_rule.b_mask) {
if (!fdir_info->mask_added) {
@@ -3381,10 +3386,8 @@ txgbe_flow_create(struct rte_eth_dev *dev,
fdir_info->mask.pkt_type_mask =
fdir_rule.mask.pkt_type_mask;
ret = txgbe_fdir_set_input_mask(dev);
- if (ret) {
- rte_free(fdir_rule_ptr);
- goto out;
- }
+ if (ret)
+ goto fdir_out;
fdir_info->mask_added = TRUE;
first_mask = TRUE;
@@ -3397,9 +3400,8 @@ txgbe_flow_create(struct rte_eth_dev *dev,
&fdir_rule.mask,
sizeof(struct txgbe_hw_fdir_mask)) != 0) {
PMD_DRV_LOG(ERR, "only support one global mask");
- rte_free(fdir_rule_ptr);
ret = -EINVAL;
- goto out;
+ goto fdir_out;
}
if (fdir_info->flex_bytes_offset !=
@@ -3408,25 +3410,16 @@ txgbe_flow_create(struct rte_eth_dev *dev,
fdir_rule.flex_relative) {
PMD_DRV_LOG(ERR,
"flex bytes offset mismatch");
- rte_free(fdir_rule_ptr);
ret = -EINVAL;
- goto out;
+ goto fdir_out;
}
}
}
ret = txgbe_fdir_filter_program(dev, &fdir_rule,
FALSE, FALSE);
- if (ret) {
- rte_free(fdir_rule_ptr);
- /**
- * clean the mask_added flag if fail to
- * program
- **/
- if (first_mask)
- fdir_info->mask_added = FALSE;
- goto out;
- }
+ if (ret)
+ goto fdir_out;
fdir_rule_ptr->filter_info = fdir_rule;
TAILQ_INSERT_TAIL(&filter_fdir_list,
@@ -3486,6 +3479,12 @@ txgbe_flow_create(struct rte_eth_dev *dev,
return flow;
}
+fdir_out:
+ rte_free(fdir_rule_ptr);
+ if (first_mask)
+ fdir_info->mask_added = FALSE;
+ if (fdir_configured)
+ fdir_conf->mode = RTE_FDIR_MODE_NONE;
out:
TAILQ_REMOVE(&txgbe_flow_list,
txgbe_flow_mem_ptr, entries);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] net/txgbe: disable flow director when no rule is left
2026-10-13 14:00 [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Zhang Tengfei
2026-10-13 14:00 ` [PATCH 1/3] net/txgbe: fix Rx packet buffer size with flow director Zhang Tengfei
2026-10-13 14:00 ` [PATCH 2/3] net/txgbe: do not enable flow director on flow validate Zhang Tengfei
@ 2026-10-13 14:00 ` Zhang Tengfei
2026-10-13 14:45 ` [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Zhang Tengfei @ 2026-10-13 14:00 UTC (permalink / raw)
To: dev; +Cc: stephen, Zhang Tengfei, jiawenwu, zaiyuwang, stable
When the last FDIR rule is destroyed, on flush, or when enabling
FDIR fails, the FDIR mode is reset to none, but Flow Director is
left enabled and the Rx packet buffer stays reduced.
Disable Flow Director and restore the Rx packet buffer size in
these cases, and when the first rule fails after FDIR was enabled.
Fixes: ea230dda16ad ("net/txgbe: configure flow director filter")
Fixes: 26048c25942f ("net/txgbe: fix FDIR mode clearing")
Cc: stable@dpdk.org
Signed-off-by: Zhang Tengfei <zhtfdev@gmail.com>
---
drivers/net/txgbe/txgbe_ethdev.h | 1 +
drivers/net/txgbe/txgbe_fdir.c | 31 +++++++++++++++++++++++++++----
drivers/net/txgbe/txgbe_flow.c | 7 ++++++-
3 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index a617b70e3c..05c20fd58c 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -552,6 +552,7 @@ void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,
* Flow director function prototypes
*/
int txgbe_fdir_configure(struct rte_eth_dev *dev);
+void txgbe_fdir_disable(struct txgbe_hw *hw);
int txgbe_fdir_set_input_mask(struct rte_eth_dev *dev);
uint16_t txgbe_fdir_get_flex_base(struct txgbe_fdir_rule *rule);
int txgbe_fdir_set_flexbytes_offset(struct rte_eth_dev *dev,
diff --git a/drivers/net/txgbe/txgbe_fdir.c b/drivers/net/txgbe/txgbe_fdir.c
index cee38a42b8..8e397c995c 100644
--- a/drivers/net/txgbe/txgbe_fdir.c
+++ b/drivers/net/txgbe/txgbe_fdir.c
@@ -368,6 +368,18 @@ txgbe_set_fdir_flex_conf(struct rte_eth_dev *dev, uint32_t flex)
return 0;
}
+void
+txgbe_fdir_disable(struct txgbe_hw *hw)
+{
+ int i;
+
+ wr32(hw, TXGBE_FDIRCTL, 0);
+ wr32(hw, TXGBE_PBRXSIZE(0), hw->mac.rx_pb_size << 10);
+ for (i = 1; i < 8; i++)
+ wr32(hw, TXGBE_PBRXSIZE(i), 0);
+ txgbe_flush(hw);
+}
+
int
txgbe_fdir_configure(struct rte_eth_dev *dev)
{
@@ -408,27 +420,31 @@ txgbe_fdir_configure(struct rte_eth_dev *dev)
err = txgbe_fdir_store_input_mask(dev);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on setting FD mask");
- return err;
+ goto error;
}
err = txgbe_fdir_set_input_mask(dev);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on setting FD mask");
- return err;
+ goto error;
}
err = txgbe_set_fdir_flex_conf(dev, flex);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on setting FD flexible arguments.");
- return err;
+ goto error;
}
err = txgbe_fdir_enable(hw, fdirctrl);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on enabling FD.");
- return err;
+ goto error;
}
return 0;
+
+error:
+ txgbe_fdir_disable(hw);
+ return err;
}
/*
@@ -1138,12 +1154,16 @@ txgbe_fdir_filter_restore(struct rte_eth_dev *dev)
int
txgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
{
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(dev);
struct txgbe_fdir_filter *fdir_filter;
struct txgbe_fdir_filter *filter_flag;
+ bool fdir_enabled;
int ret = 0;
+ fdir_enabled = fdir_conf->mode != RTE_FDIR_MODE_NONE;
+
/* flush flow director */
rte_hash_reset(fdir_info->hash_handle);
memset(fdir_info->hash_map, 0,
@@ -1161,5 +1181,8 @@ txgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
if (filter_flag != NULL)
ret = txgbe_fdir_flush(dev);
+ if (fdir_enabled && txgbe_is_pf(hw))
+ txgbe_fdir_disable(hw);
+
return ret;
}
diff --git a/drivers/net/txgbe/txgbe_flow.c b/drivers/net/txgbe/txgbe_flow.c
index f2fc589a10..9fa79fc064 100644
--- a/drivers/net/txgbe/txgbe_flow.c
+++ b/drivers/net/txgbe/txgbe_flow.c
@@ -3483,8 +3483,10 @@ txgbe_flow_create(struct rte_eth_dev *dev,
rte_free(fdir_rule_ptr);
if (first_mask)
fdir_info->mask_added = FALSE;
- if (fdir_configured)
+ if (fdir_configured) {
+ txgbe_fdir_disable(TXGBE_DEV_HW(dev));
fdir_conf->mode = RTE_FDIR_MODE_NONE;
+ }
out:
TAILQ_REMOVE(&txgbe_flow_list,
txgbe_flow_mem_ptr, entries);
@@ -3637,6 +3639,9 @@ txgbe_flow_destroy(struct rte_eth_dev *dev,
fdir_info->mask_added = false;
fdir_info->flex_relative = false;
fdir_info->flex_bytes_offset = 0;
+ if (fdir_conf->mode != RTE_FDIR_MODE_NONE &&
+ txgbe_is_pf(TXGBE_DEV_HW(dev)))
+ txgbe_fdir_disable(TXGBE_DEV_HW(dev));
fdir_conf->mode = RTE_FDIR_MODE_NONE;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling
2026-10-13 14:00 [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Zhang Tengfei
` (2 preceding siblings ...)
2026-10-13 14:00 ` [PATCH 3/3] net/txgbe: disable flow director when no rule is left Zhang Tengfei
@ 2026-10-13 14:45 ` Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2026-10-13 14:45 UTC (permalink / raw)
To: Zhang Tengfei; +Cc: dev, jiawenwu, zaiyuwang
On Tue, 13 Oct 2026 22:00:16 +0800
Zhang Tengfei <zhtfdev@gmail.com> wrote:
> Enabling Flow Director reduces the Rx packet buffer 0 to reserve memory
> for the filter table, but the size was computed from the current
> register value and never restored when FDIR was no longer used. Since
> the FDIR mode is reset when the last rule is removed, on flush, or when
> enabling FDIR fails, the next rule enabled FDIR again and shrank the
> buffer once more, until it underflowed. Validating a rule also enabled
> FDIR.
>
> Patch 1 computes the buffer size from the default packet buffer size,
> which alone stops the repeated reduction.
> Patch 2 stops enabling FDIR from flow validate and rolls back the mode
> when the first rule fails.
> Patch 3 disables FDIR and restores the buffer when no rule is left.
>
> The same issue was fixed in ixgbe:
> <https://patches.dpdk.org/project/dpdk/patch/20260927042545.45152-1-zhtfdev@gmail.com>
>
> Compile tested only.
>
> Zhang Tengfei (3):
> net/txgbe: fix Rx packet buffer size with flow director
> net/txgbe: do not enable flow director on flow validate
> net/txgbe: disable flow director when no rule is left
>
> drivers/net/txgbe/txgbe_ethdev.h | 1 +
> drivers/net/txgbe/txgbe_fdir.c | 36 +++++++++++++++----
> drivers/net/txgbe/txgbe_flow.c | 60 +++++++++++++++++---------------
> 3 files changed, 62 insertions(+), 35 deletions(-)
>
AI review saw a warning that would be easy to fix.
Subject: Re: [PATCH 0/3] net/txgbe: flow director state fixes
Applied to main, each commit builds with -Dwerror=true. Fixes: tags
check out.
Series looks right overall; one validate regression in 2/3.
[PATCH 2/3] net/txgbe: do not enable flow director on flow validate
Warning: validate now accepts rules that create will always reject.
txgbe_parse_fdir_filter_normal() can set
rule->mode = RTE_FDIR_MODE_PERFECT_MAC_VLAN. Before this patch, with
mode NONE, parse called txgbe_fdir_configure() which returns -ENOSYS
for anything other than SIGNATURE or PERFECT, so validate failed.
Now parse only checks for a mode mismatch, validate succeeds, and
create fails later in txgbe_fdir_configure().
Keep the cheap mode check in parse so validate and create agree:
if (rule->mode != RTE_FDIR_MODE_SIGNATURE &&
rule->mode != RTE_FDIR_MODE_PERFECT)
return -ENOTSUP;
if (fdir_conf->mode != RTE_FDIR_MODE_NONE &&
fdir_conf->mode != rule->mode)
return -ENOTSUP;
[PATCH 3/3] net/txgbe: disable flow director when no rule is left
Info: txgbe_fdir_disable() restores a single packet buffer layout
(PB0 = rx_pb_size, PB1-7 = 0), not what txgbe_configure_dcb() set at
dev_start. That matches what txgbe_fdir_configure() already does, so
FDIR with DCB is already broken and this is not a new problem. If
you respin, consider saving the PBRXSIZE values before enabling FDIR
and restoring them on disable, or reject FDIR when DCB Rx is
configured.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-13 14:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 14:00 [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Zhang Tengfei
2026-10-13 14:00 ` [PATCH 1/3] net/txgbe: fix Rx packet buffer size with flow director Zhang Tengfei
2026-10-13 14:00 ` [PATCH 2/3] net/txgbe: do not enable flow director on flow validate Zhang Tengfei
2026-10-13 14:00 ` [PATCH 3/3] net/txgbe: disable flow director when no rule is left Zhang Tengfei
2026-10-13 14:45 ` [PATCH 0/3] net/txgbe: fix FDIR Rx packet buffer handling Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox