* [PATCH v1 00/13] net/sxe2: fix bugs
@ 2026-08-14 12:21 liujie5
2026-08-14 12:21 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Jie Liu (13):
net/sxe2: add Rx queue buffer split fill support
net/sxe2: update switchdev repr VSI ID display format
net/sxe2: add ACL engine event statistics support
net/sxe2: enhance device cap and res management
net/sxe2: improve representor device initialization
net/sxe2: refactor flow tunnel port handling
net/sxe2: validate IPsec key length against maximum limit
net/sxe2: enhance repre event handling and MP code
net/sxe2: optimize vectorized Tx/Rx path
common/sxe2: allow munmap during kernel reset
net/sxe2: clean up duplicate function declarations
net/sxe2: clean up structure definitions
doc/sxe2: add acl-stat-type parameter documentation
doc/guides/nics/sxe2.rst | 33 +--
drivers/common/sxe2/sxe2_common.c | 5 +-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-
drivers/net/sxe2/sxe2_cmd_chnl.c | 215 +++++++++++++++--
drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 47 ++--
drivers/net/sxe2/sxe2_dump.c | 10 +-
drivers/net/sxe2/sxe2_ethdev.c | 203 +++++++++-------
drivers/net/sxe2/sxe2_ethdev.h | 38 +--
drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +-
drivers/net/sxe2/sxe2_flow.c | 259 +++++++++++++++++----
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 13 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 37 ++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 7 -
drivers/net/sxe2/sxe2_ipsec.c | 5 +
drivers/net/sxe2/sxe2_irq.c | 27 ++-
drivers/net/sxe2/sxe2_mac.c | 10 +-
drivers/net/sxe2/sxe2_mp.c | 65 +++---
drivers/net/sxe2/sxe2_mp.h | 3 +-
drivers/net/sxe2/sxe2_queue.c | 2 +
drivers/net/sxe2/sxe2_queue.h | 7 +-
drivers/net/sxe2/sxe2_rx.c | 5 +-
drivers/net/sxe2/sxe2_security.c | 1 +
drivers/net/sxe2/sxe2_stats.c | 10 +-
drivers/net/sxe2/sxe2_switchdev.c | 12 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++-
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 19 +-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 77 +++---
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 123 +---------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 215 +++++++++++------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
39 files changed, 993 insertions(+), 692 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format liujie5
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Implement sxe2_rxq_buf_split_fill function to configure Rx queue
buffer split offload. The function validates and sets split
parameters based on protocol header type.
Supports following split types:
- L2: Ether
- L3: IPv4, IPv6
- L4: TCP, UDP, SCTP
- Tunnel: GRE/NAT
- Inner L2/L3/L4 for tunneled packets
Sets split_type_mask and header_len (256 bytes) for hardware
buffer split configuration. Returns error if protocol header
is not configured or unsupported.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 142 ++++++++++++++++++++++++++++---
1 file changed, 128 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..9ed5559eff 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
}
static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
- struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+ struct sxe2_drv_cmd_params *cmd, uint32_t opc,
void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
{
- PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
cmd->opcode = opc;
cmd->vsi_id = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,7 +43,7 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
}
#define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
- __sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
+ __sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len)
int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
@@ -193,6 +192,102 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
#define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN (1 << 7)
#define SXE2_RX_HDR_SIZE 256
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+ struct sxe2_drv_rxq_ctxt *ctxt)
+{
+ int32_t ret = 0;
+ uint32_t proto_hdr;
+
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ ret = -1;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ ret = -1;
+ } else {
+ ctxt->hdr_len = 0;
+ ctxt->split_type_mask = 0;
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
{
@@ -226,7 +321,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
else
ctxt->keep_crc_en = 0;
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+ if (ret)
+ goto l_end;
+ ctxt->split_en = 1;
+ } else {
+ ctxt->split_en = 0;
+ }
+
ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
return ret;
}
@@ -391,7 +496,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
&vsi_info_get_resp, sizeof(vsi_info_get_resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
goto l_end;
}
@@ -412,6 +517,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
{
int32_t ret = 0;
struct sxe2_common_device *cdev = adapter->cdev;
+ struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
struct sxe2_drv_cmd_params param = {0};
struct sxe2_drv_link_info_resp resp = {0};
@@ -425,6 +531,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
}
adapter->link_ctxt.speed = resp.speed;
adapter->link_ctxt.link_up = resp.status;
+ (void)sxe2_link_update(dev, 0);
l_end:
return ret;
@@ -447,7 +554,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -467,7 +574,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -668,7 +775,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+ PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
return ret;
}
@@ -1532,7 +1639,7 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
[SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U] = SXE2_UDP_TUNNEL_PROTOCOL_GTP_U,
[SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE] = SXE2_UDP_TUNNEL_PROTOCOL_NVGRE,
};
- struct sxe2_udp_tunnel_cfg tunnel_config = {};
+ struct sxe2_udp_tunnel_cfg tunnel_config = {0};
tunnel_config.protocol = flow_proto_to_udp_tunnel_proto[proto];
ret = sxe2_drv_udp_tunnel_get(adapter, &tunnel_config);
@@ -1560,8 +1667,10 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
&req, sizeof(req),
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+ goto l_end;
+ }
tunnel_config->fw_port = resp.port;
tunnel_config->fw_status = resp.enable;
@@ -1569,6 +1678,7 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
tunnel_config->fw_src_en = resp.src;
tunnel_config->fw_used = resp.fw_used;
+l_end:
return ret;
}
@@ -1591,7 +1701,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
goto l_end;
}
@@ -1635,7 +1745,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1652,7 +1762,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
txq = eth_dev->data->tx_queues[queue_id];
if (txq == NULL) {
- PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+ PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
ret = -EINVAL;
goto l_end;
}
@@ -1666,7 +1776,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1726,10 +1836,14 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
sizeof(req), &resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+ flow->create_err = ret;
+ goto l_end;
+ }
flow->flow_id = resp.flow_id;
flow->create_err = ret;
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
2026-08-14 12:21 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support liujie5
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Update the output format for representor primary VSI ID and backup
VSI ID in switchdev dump function. The fields repr_vf_primary_vsi_id
and repr_vf_backup_vsi_id should be displayed correctly for better
debug visibility.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_dump.c | 8 ++++----
drivers/net/sxe2/sxe2_ethdev.h | 4 ++--
drivers/net/sxe2/sxe2_flow.c | 4 ++--
drivers/net/sxe2/sxe2_switchdev.c | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index d43473e083..590219f502 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -211,16 +211,16 @@ sxe2_dump_switchdev_info(FILE *file, struct rte_eth_dev *dev)
"\t -- repr_pf_id: %u\n"
"\t -- repr_vf_id: %u\n"
"\t -- repr_vf_vsi_id: %u\n"
- "\t -- repr_vf_k_vsi_id: %s\n"
- "\t -- repr_vf_u_vsi_id: %s\n",
+ "\t -- repr_vf_primary_vsi_id: %s\n"
+ "\t -- repr_vf_backup_vsi_id: %s\n",
adapter->repr_priv_data->repr_id,
adapter->repr_priv_data->repr_q_id,
adapter->repr_priv_data->repr_pf_id,
adapter->repr_priv_data->repr_vf_id,
adapter->repr_priv_data->repr_vf_vsi_id,
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_k_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_primary_vsi_id,
k_vsi_buf, sizeof(k_vsi_buf)),
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_u_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_backup_vsi_id,
u_vsi_buf, sizeof(u_vsi_buf)));
goto l_end;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index c54e8a435e..158198d74b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -263,8 +263,8 @@ struct sxe2_repr_private_data {
uint16_t repr_pf_id;
uint16_t repr_vf_id;
uint16_t repr_vf_vsi_id;
- uint16_t repr_vf_k_vsi_id;
- uint16_t repr_vf_u_vsi_id;
+ uint16_t repr_vf_primary_vsi_id;
+ uint16_t repr_vf_backup_vsi_id;
};
struct sxe2_sched_hw_cap {
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 63cfc36968..cf54803301 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -380,9 +380,9 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
flow_bond_num = 1;
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
- adapter->repr_priv_data->repr_vf_u_vsi_id;
+ adapter->repr_priv_data->repr_vf_backup_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
- adapter->repr_priv_data->repr_vf_k_vsi_id;
+ adapter->repr_priv_data->repr_vf_primary_vsi_id;
}
for (idx = 0; idx < flow_bond_num; idx++) {
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index 44703cfb5c..efb1468b91 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,9 +312,9 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
- repr_priv_data->repr_vf_k_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
- repr_priv_data->repr_vf_u_vsi_id =
+ repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
repr_priv_data->repr_vf_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
2026-08-14 12:21 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
2026-08-14 12:21 ` [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 04/13] net/sxe2: enhance device cap and res management liujie5
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Add statistics support for ACL flow engine to track packet hits
and bytes. This enables flow aging and traffic monitoring for
ACL rules.
Implementation includes:
- Add acl-stat-type devarg to configure statistics type
- Implement sxe2_drv_flow_acl_get_stat_id for stat allocation
- Implement sxe2_drv_flow_acl_free_stat for stat cleanup
- Implement sxe2_drv_flow_acl_query_stat for stat query
- Integrate stat operations into flow create/destroy/query paths
Statistics are accumulated in manager context and reported through
rte_flow_query() interface with COUNT action.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 73 +++++++++++++-
drivers/net/sxe2/sxe2_cmd_chnl.h | 9 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 17 ++++
drivers/net/sxe2/sxe2_dump.c | 2 +
drivers/net/sxe2/sxe2_ethdev.c | 25 +++--
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 111 ++++++++++++++++------
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 13 +--
drivers/net/sxe2/sxe2_flow_parse_action.c | 19 +++-
drivers/net/sxe2/sxe2_queue.c | 2 +
11 files changed, 225 insertions(+), 53 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 9ed5559eff..b2dbd4457d 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1914,7 +1914,7 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
}
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr)
+ struct sxe2_flow_cid_mgr *mgr)
{
struct sxe2_drv_flow_fnav_query_stat_req req = { 0 };
struct sxe2_drv_flow_fnav_query_stat_resp resp = { 0 };
@@ -1943,6 +1943,77 @@ int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
return ret;
}
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id)
+{
+ struct sxe2_drv_flow_fnav_get_stat_id_req req = { 0 };
+ struct sxe2_drv_flow_fnav_get_stat_id_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+ *stat_id = resp.stat_id;
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id)
+{
+ struct sxe2_drv_flow_fnav_free_stat_id_req req = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = stat_id;
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to free acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr)
+{
+ struct sxe2_drv_acl_query_stat_req req = { 0 };
+ struct sxe2_drv_acl_query_stat_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = mgr->stat_index;
+ req.stat_ctrl = mgr->count_type;
+ req.is_clear = 1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to query ACL stat, stat id: %u, ret: %d.",
+ req.stat_id, ret);
+ goto l_end;
+ }
+ mgr->hits += resp.stat_hits;
+ mgr->bytes += resp.stat_bytes;
+
+l_end:
+ return ret;
+}
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set)
{
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..7d75a91061 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -165,7 +165,14 @@ int32_t sxe2_drv_flow_fnav_get_stat_id(struct sxe2_adapter *adapter, uint32_t *s
int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr);
+ struct sxe2_flow_cid_mgr *mgr);
+
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id);
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr);
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 03ef3b315d..aa56d9436a 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -668,6 +668,18 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_fc_get_resp {
uint8_t rsv[3];
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_req {
+ __le32 stat_id;
+ __le32 stat_ctrl;
+ __le32 is_clear;
+} __rte_packed_end;
+
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_resp {
+ __le32 stat_index;
+ __le64 stat_hits;
+ __le64 stat_bytes;
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
@@ -824,6 +836,11 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_OPT_EEP_GET =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_OPT, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+
};
#endif /* SXE2_DRV_CMD_H */
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index 590219f502..31f7d6ba61 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -80,12 +80,14 @@ sxe2_dump_dev_args_info(FILE *file, struct rte_eth_dev *dev)
"\t -- no_sched_mode: %s\n"
"\t -- flow-duplicate-pattern: %u\n"
"\t -- fnav-stat-type: %u\n"
+ "\t -- acl-stat-type: %u\n"
"\t -- sched_layer_mode: %u\n"
"\t -- rx_low_latency: %s\n"
"\t -- function-flow-direct: %s\n",
adapter->devargs.no_sched_mode ? "On" : "Off",
adapter->devargs.flow_dup_pattern_mode,
adapter->devargs.fnav_stat_type,
+ adapter->devargs.acl_stat_type,
adapter->devargs.sched_layer_mode,
adapter->devargs.rx_low_latency ? "On" : "Off",
adapter->devargs.func_flow_direct_en ? "On" : "Off");
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..3c3e78125d 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -44,7 +44,7 @@
#define SXE2_PCI_VENDOR_ID_1 0x1ff2
#define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
#define SXE2_PCI_VENDOR_ID_2 0x1d94
#define SXE2_PCI_DEVICE_ID_PF_2 0x1260
@@ -72,6 +72,7 @@ static const struct rte_pci_id pci_id_sxe2_tbl[] = {
#define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
#define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
#define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
+#define SXE2_DEVARG_ACL_STAT_TYPE "acl-stat-type"
#define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
#define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
#define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
@@ -971,11 +972,11 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
-static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
+static int32_t sxe2_parse_stat_type(const char *key, const char *value, void *args)
{
int32_t ret = -EINVAL;
uint8_t *num = (uint8_t *)args;
- unsigned long fnav_stat_type;
+ unsigned long stat_type;
char *endptr = NULL;
if (value == NULL || args == NULL) {
@@ -983,19 +984,19 @@ static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, voi
goto l_end;
}
errno = 0;
- fnav_stat_type = strtoul(value, &endptr, 10);
+ stat_type = strtoul(value, &endptr, 10);
if (errno != 0 || endptr == value || *endptr != '\0') {
PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
key, value);
goto l_end;
}
- if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
- fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
+ if (stat_type > SXE2_FNAV_STAT_ENA_ALL ||
+ stat_type == SXE2_FNAV_STAT_ENA_NONE) {
PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
key, value);
goto l_end;
}
- *num = (uint8_t)fnav_stat_type;
+ *num = (uint8_t)stat_type;
ret = 0;
l_end:
return ret;
@@ -1177,13 +1178,20 @@ static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_i
if (kvargs == NULL)
goto l_end;
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
- &sxe2_parse_fnav_stat_type,
+ &sxe2_parse_stat_type,
&adapter->devargs.fnav_stat_type);
if (ret) {
PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
goto l_end;
}
+ ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_ACL_STAT_TYPE,
+ &sxe2_parse_stat_type, &adapter->devargs.acl_stat_type);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse acl stat type, ret:%d", ret);
+ goto l_end;
+ }
+
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
&sxe2_parse_bool,
&adapter->devargs.no_sched_mode);
@@ -2350,6 +2358,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
"flow-duplicate-pattern=<0|1|2> "
"function-flow-direct=<0|1> "
"fnav-stat-type=<1|2|3> "
+ "acl-stat-type=<1|2|3> "
"no-sched-mode=<0|1> "
"sched-layer-mode=<0-3> "
"rx-low-latency=<0|1>");
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 158198d74b..7e495e5cb9 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -138,6 +138,7 @@ struct sxe2_devargs {
uint8_t flow_dup_pattern_mode;
uint8_t func_flow_direct_en;
uint8_t fnav_stat_type;
+ uint8_t acl_stat_type;
uint8_t no_sched_mode;
uint8_t sched_layer_mode;
uint8_t rx_low_latency;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cf54803301..3cf98dd294 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -857,7 +857,7 @@ static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
struct rte_flow *flow_temp = NULL;
struct sxe2_flow *hw_flow = NULL;
struct sxe2_flow *hw_flow_temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
if (flow_temp == flow)
@@ -1028,7 +1028,7 @@ static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
goto l_free_flow;
TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
- ret = sxe2_fnav_get_filter_cid(adapter, flow);
+ ret = sxe2_flow_get_filter_cid(adapter, flow);
if (ret != 0) {
PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
rte_flow_error_set(error, EIO,
@@ -1088,16 +1088,26 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
return ret;
}
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ uint32_t count_type;
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.fnav_hw_res.count_type;
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.acl_hw_res.count_type;
+ } else {
+ goto l_end;
+ }
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1112,7 +1122,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
}
if (mgr == NULL) {
mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
- sizeof(struct sxe2_fnav_cid_mgr), 0);
+ sizeof(struct sxe2_flow_cid_mgr), 0);
if (!mgr) {
PMD_LOG_ERR(DRV,
"Failed to alloc sxe2vf_fnav_cid_mgr memory.");
@@ -1120,7 +1130,10 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
goto l_end;
}
- ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ ret = sxe2_drv_flow_acl_get_stat_id(adapter, &stat_index);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
rte_free(mgr);
@@ -1131,7 +1144,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
mgr->user_id = user_id;
mgr->driver_id = driver_id;
mgr->stat_index = stat_index;
- mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
+ mgr->count_type = count_type;
}
flow->action.count.stat_index = mgr->stat_index;
flow->action.count.stat_ctrl = mgr->count_type;
@@ -1143,17 +1156,24 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
+ struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
- if (user_id == 0) {
- TAILQ_REMOVE(cid_mgr_list, mgr, next);
- ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+
+ if (user_id == 0 && mgr) {
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ }
if (ret) {
rte_flow_error_set(error, EIO,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -1170,17 +1190,23 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ else
+ goto l_end;
+
TAILQ_FOREACH(temp, cid_mgr_list, next) {
if (temp->user_id == user_id &&
temp->driver_id == driver_id) {
@@ -1197,7 +1223,15 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
ret = -EINVAL;
goto l_end;
}
- ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ ret = sxe2_drv_flow_acl_query_stat(adapter, mgr);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+ } else {
+ PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
+ ret = -ENOTSUP;
+ }
if (ret) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
@@ -1218,7 +1252,7 @@ static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
switch (flow->action.count.stat_ctrl) {
case SXE2_FNAV_STAT_ENA_NONE:
count->hits_set = 0;
@@ -1348,12 +1382,18 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
- adapter->flow_ctxt.hw_res.count_type =
+ adapter->flow_ctxt.fnav_hw_res.count_type =
adapter->devargs.fnav_stat_type;
else
- adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+ adapter->flow_ctxt.fnav_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+
+ if (adapter->devargs.acl_stat_type)
+ adapter->flow_ctxt.acl_hw_res.count_type = adapter->devargs.acl_stat_type;
+ else
+ adapter->flow_ctxt.acl_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
adapter->flow_ctxt.fnav_inited = 1;
rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
@@ -1370,15 +1410,15 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
int32_t ret = 0;
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct rte_flow_error error;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
ret = sxe2_flow_flush(dev, &error);
if (ret)
PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
@@ -1387,5 +1427,14 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
"Failed to free fnav stat id, ret: %d.", ret);
rte_free(mgr);
}
+
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ if (ret)
+ PMD_LOG_ERR(DRV, "Failed to free acl stat id, ret: %d.", ret);
+ rte_free(mgr);
+ }
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_flow.h b/drivers/net/sxe2/sxe2_flow.h
index daaeedd4dc..8d47b11ff4 100644
--- a/drivers/net/sxe2/sxe2_flow.h
+++ b/drivers/net/sxe2/sxe2_flow.h
@@ -14,16 +14,16 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev);
int32_t sxe2_flow_uninit(struct rte_eth_dev *dev);
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 263a573f04..f56f687dc7 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -98,8 +98,8 @@ struct rte_flow {
};
TAILQ_HEAD(rte_flow_list_t, rte_flow);
-struct sxe2_fnav_cid_mgr {
- TAILQ_ENTRY(sxe2_fnav_cid_mgr) next;
+struct sxe2_flow_cid_mgr {
+ TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
uint16_t stat_index;
uint32_t user_id;
uint32_t driver_id;
@@ -107,18 +107,19 @@ struct sxe2_fnav_cid_mgr {
uint64_t hits;
uint64_t bytes;
};
-TAILQ_HEAD(sxe2_fnav_cid_mgr_list_t, sxe2_fnav_cid_mgr);
+TAILQ_HEAD(sxe2_flow_cid_mgr_list_t, sxe2_flow_cid_mgr);
-struct sxe2_fnav_count_resource {
+struct sxe2_flow_count_resource {
uint32_t count_type;
uint32_t global_index;
- struct sxe2_fnav_cid_mgr_list_t fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t flow_cid_mgr_list;
};
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_fnav_count_resource hw_res;
+ struct sxe2_flow_count_resource fnav_hw_res;
+ struct sxe2_flow_count_resource acl_hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index a9559e2d7e..cdd6fcfdcd 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -1037,11 +1037,24 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
act_count = action->conf;
- flow->action.count.user_id = act_count->id;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
flow->action.count.driver_id = 0;
- if (flow->action.count.user_id == 0)
+ if (flow->action.count.user_id == 0) {
flow->action.count.driver_id =
- ++adapter->flow_ctxt.hw_res.global_index;
+ ++adapter->flow_ctxt.fnav_hw_res.global_index;
+ }
+ action_num[SXE2_FLOW_ACTION_COUNT]++;
+ } else if (engine_type == SXE2_FLOW_ENGINE_ACL) {
+ sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
+ act_count = action->conf;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
+ flow->action.count.driver_id = 0;
+ if (flow->action.count.user_id == 0) {
+ flow->action.count.driver_id =
+ ++adapter->flow_ctxt.acl_hw_res.global_index;
+ }
action_num[SXE2_FLOW_ACTION_COUNT]++;
} else {
rte_flow_error_set(error, ENOTSUP,
diff --git a/drivers/net/sxe2/sxe2_queue.c b/drivers/net/sxe2/sxe2_queue.c
index afb2681b72..3aaa14c685 100644
--- a/drivers/net/sxe2/sxe2_queue.c
+++ b/drivers/net/sxe2/sxe2_queue.c
@@ -39,6 +39,8 @@ int32_t sxe2_queues_init(struct rte_eth_dev *dev)
rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, SXE2_RX_MAX_DATA_BUF_SIZE);
if (frame_size > rxq->rx_buf_len)
dev->data->scattered_rx = 1;
+ if (adapter->flow_ctxt.fnav_inited)
+ rxq->fnav_enable = true;
}
adapter->ptp_ctxt.mbuf_rx_ts_offset = -1;
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 04/13] net/sxe2: enhance device cap and res management
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (2 preceding siblings ...)
2026-08-14 12:21 ` [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 05/13] net/sxe2: improve representor device initialization liujie5
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch improves the SXE2 PMD with several key enhancements:
- Enhance device info reporting:
* Add NULL check for main VSI in dev_infos_get
* Add max_mac_addrs field support
* Add RSS_HASH offload capability
* Conditionally enable QINQ_STRIP/QINQ_INSERT based on port VLAN check
* Fill nb_rx_queues and nb_tx_queues fields
* Set no_of_elements in buffer_split_supported_hdr_ptypes_get
- Unify PCI register operations:
* Move SXE2_PCI_REG_WRITE and SXE2_PCI_REG_READ to common header
* Replace write-combined write with regular write in pci_map_write_reg
* Add resource type validation in dev_pci_res_seg_map
- Improve VF representor matching logic:
* Remove kernel_repr_id encoding approach
* Match PF number and VF ID directly against representor info
* Add proper error handling for mismatched representor types
- Support multi-port probing:
* Loop through nb_ports in eth_pmd_probe
* Handle probe failure with proper cleanup
- Update resource cleanup order in dev_close:
* Adjust uninit sequence to prevent use-after-free
* Add NULL check for dev_ops before calling dev_close
- Add device type checks in UDP tunnel operations:
* Restrict tunnel operations to PF only
* Reject operations on VF representors
- Store additional device capabilities:
* Save port_idx and pf_idx from device capabilities
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 178 +++++++++++++++++++--------------
drivers/net/sxe2/sxe2_ethdev.h | 6 +-
drivers/net/sxe2/sxe2_queue.h | 2 -
3 files changed, 107 insertions(+), 79 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 3c3e78125d..ccf04fe1d9 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -95,7 +95,7 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
.reg_width = 4},
[SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
.bar_idx = 4,
- .reg_width = 10},
+ .reg_width = 0x10},
};
static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
@@ -630,6 +630,10 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr) {
+ ret = -ENOTSUP;
+ goto l_end;
+ }
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -659,6 +663,7 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
l_unlock_end:
rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
+l_end:
return ret;
}
@@ -782,6 +787,10 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+ if (unlikely(vsi == NULL)) {
+ PMD_LOG_ERR(INIT, "main vsi is NULL");
+ return -EINVAL;
+ }
dev_info->max_rx_queues = vsi->rxqs.q_cnt;
dev_info->max_tx_queues = vsi->txqs.q_cnt;
dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
@@ -789,6 +798,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+ dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
@@ -800,11 +810,9 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
-#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
- RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
-#endif
RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
- RTE_ETH_RX_OFFLOAD_TCP_LRO;
+ RTE_ETH_RX_OFFLOAD_TCP_LRO |
+ RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
@@ -850,13 +858,20 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
+ if (sxe2_ipsec_supported(adapter)) {
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
+ }
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
- if (sxe2_ipsec_supported(adapter)) {
- dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
- dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
+ if (!sxe2_dev_port_vlan_check(dev)) {
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
+#endif
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
}
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
@@ -909,7 +924,8 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
-
+ dev_info->nb_rx_queues = dev->data->nb_rx_queues;
+ dev_info->nb_tx_queues = dev->data->nb_tx_queues;
dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
dev_info->default_rxportconf.nb_queues = 1;
@@ -918,11 +934,8 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->default_txportconf.ring_size = SXE2_RING_SIZE_MIN;
dev_info->rx_seg_capa.max_nseg = SXE2_RX_MAX_NSEG;
-
dev_info->rx_seg_capa.multi_pools = true;
-
dev_info->rx_seg_capa.offset_allowed = false;
-
dev_info->rx_seg_capa.offset_align_log2 = false;
return 0;
@@ -930,7 +943,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
static const uint32_t *
sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
- size_t *no_of_elements __rte_unused)
+ size_t *no_of_elements)
{
static const uint32_t ptypes[] = {
RTE_PTYPE_L2_ETHER,
@@ -968,6 +981,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
+ *no_of_elements = RTE_DIM(ptypes);
return ptypes;
}
@@ -1352,6 +1366,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
goto l_end;
adapter->dev_type = dev_caps.dev_type;
+ adapter->port_idx = dev_caps.port_idx;
+ adapter->pf_idx = dev_caps.pf_idx;
sxe2_drv_dev_caps_set(adapter, &dev_caps);
@@ -1437,7 +1453,7 @@ void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
goto l_ret;
}
- SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+ SXE2_PCI_REG_WRITE(reg_addr, value);
l_ret:
return;
}
@@ -1550,6 +1566,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
struct sxe2_pci_map_addr_info *addr_info = NULL;
int32_t ret = 0;
+ if (unlikely(res_type >= SXE2_PCI_MAP_RES_MAX_COUNT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Invalid resource type %u", res_type);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
addr_info = &adapter->map_ctxt.addr_info[res_type];
if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
@@ -1765,14 +1787,13 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
uint8_t i = 0;
PMD_INIT_FUNC_TRACE();
+ if (map_ctxt->bar_info != NULL) {
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
-
- if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
for (i = 0; i < map_ctxt->bar_cnt; i++) {
bar_info = &map_ctxt->bar_info[i];
if (bar_info != NULL && bar_info->seg_info != NULL) {
@@ -1783,7 +1804,6 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
rte_free(map_ctxt->bar_info);
map_ctxt->bar_info = NULL;
}
-
adapter->dev_info.dev_data = NULL;
}
@@ -1936,6 +1956,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_switchdev_err;
}
+ ret = sxe2_eth_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+ goto init_eth_err;
+ }
+
ret = sxe2_sw_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
@@ -1948,12 +1974,6 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_irq_err;
}
- ret = sxe2_eth_init(dev);
- if (ret) {
- PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
- goto init_eth_err;
- }
-
ret = sxe2_security_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
@@ -2005,15 +2025,15 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_fc_state_err:
(void)sxe2_flow_uninit(dev);
init_flow_err:
-init_rss_err:
sxe2_security_uinit(dev);
+init_rss_err:
init_security_err:
- sxe2_eth_uinit(dev);
-init_eth_err:
sxe2_intr_uninit(dev);
init_irq_err:
sxe2_sw_uninit(dev);
init_sw_err:
+ sxe2_eth_uinit(dev);
+init_eth_err:
(void)sxe2_switchdev_uninit(dev);
init_switchdev_err:
init_dev_info_err:
@@ -2035,17 +2055,15 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_queues_release(dev);
sxe2_mp_uninit(dev);
(void)sxe2_sched_uinit(dev);
- (void)sxe2_rss_disable(dev);
(void)sxe2_flow_uninit(dev);
+ (void)sxe2_rss_disable(dev);
(void)sxe2_udp_tunnel_port_clear(dev);
- sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
sxe2_intr_uninit(dev);
(void)sxe2_switchdev_uninit(dev);
sxe2_sw_uninit(dev);
- (void)sxe2_switchdev_uninit(dev);
- sxe2_dev_pci_map_uinit(dev);
sxe2_eth_uinit(dev);
+ sxe2_vsi_uninit(dev);
sxe2_dev_pci_map_uinit(dev);
sxe2_free_repr_info(dev);
sxe2_fc_state_uinit(dev);
@@ -2068,9 +2086,11 @@ static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
if (rep_dev) {
- ret = rep_dev->dev_ops->dev_close(rep_dev);
- if (ret)
- goto l_end;
+ if (rep_dev->dev_ops && rep_dev->dev_ops->dev_close) {
+ ret = rep_dev->dev_ops->dev_close(rep_dev);
+ if (ret)
+ goto l_end;
+ }
if (rep_dev->intr_handle)
rte_intr_instance_free(rep_dev->intr_handle);
ret = rte_eth_dev_release_port(rep_dev);
@@ -2143,42 +2163,25 @@ static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_vers
return ret;
}
-static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
-{
- enum rte_eth_representor_type type;
- uint16_t repr = switchdev_info->vf_num;
- uint32_t pf = switchdev_info->pf_num;
-
- switch (switchdev_info->port_name_type) {
- case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
- if (!switchdev_info->representor)
- return UINT16_MAX;
- type = RTE_ETH_REPRESENTOR_PF;
- pf = switchdev_info->mpesw_owner;
- break;
- case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
- default:
- type = RTE_ETH_REPRESENTOR_VF;
- break;
- }
-
- return SXE2_REPRESENTOR_ID(pf, type, repr);
-}
-
static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
struct rte_eth_devargs *req_eth_da)
{
- uint32_t port_idx = 0;
- uint32_t repr_idx;
- uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
- uint16_t repr_id;
+ uint16_t port_idx = UINT16_MAX;
+ uint16_t repr_idx;
+ uint16_t vf_id;
+ uint16_t i;
switch (req_eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
+ if (adapter->switchdev_info.port_name_type !=
+ SXE2_PHYS_PORT_NAME_TYPE_UPLINK) {
+ rte_errno = EBUSY;
+ return false;
+ }
break;
case RTE_ETH_REPRESENTOR_VF:
if (adapter->switchdev_info.port_name_type !=
- SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
+ SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
rte_errno = EBUSY;
return false;
}
@@ -2191,15 +2194,30 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
return false;
}
+ for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
+ if (adapter->switchdev_info.pf_num != req_eth_da->ports[port_idx]) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf %u",
+ adapter->switchdev_info.pf_num, req_eth_da->ports[port_idx]);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
- req_eth_da->type,
- req_eth_da->representor_ports[repr_idx]);
- if (repr_id == kernel_repr_id)
- return true;
- }
- rte_errno = EBUSY;
- return false;
+ for (i = 0; i < adapter->repr_ctxt.nb_vf; ++i) {
+ vf_id = rte_le_to_cpu_16(adapter->repr_ctxt.repr_vf_id[i].func_id);
+ if (vf_id == req_eth_da->representor_ports[repr_idx])
+ break;
+ }
+ if (i == adapter->repr_ctxt.nb_vf) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev vf %u not match req vf(cnt:%u)",
+ req_eth_da->representor_ports[repr_idx], adapter->repr_ctxt.nb_vf);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
+ return true;
}
static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
@@ -2317,6 +2335,7 @@ static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
{
struct rte_eth_devargs eth_da = { .nb_ports = 0 };
int32_t ret = 0;
+ uint16_t port;
ret = sxe2_parse_eth_devargs(cdev->dev, ð_da);
if (ret != 0) {
@@ -2324,7 +2343,18 @@ static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
goto l_end;
}
- ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
+ if (eth_da.nb_ports > 0) {
+ for (port = 0; port < eth_da.nb_ports; port++) {
+ ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, port, kvargs);
+ if (ret != 0) {
+ PMD_LOG_ERR(INIT, "sxe2 eth pmd probe failed, ret=%d", ret);
+ (void)sxe2_eth_pmd_remove(cdev);
+ goto l_end;
+ }
+ }
+ } else {
+ ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
+ }
l_end:
return ret;
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 7e495e5cb9..cfcb7fcf00 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -65,9 +65,6 @@ enum sxe2_fnav_tunnel_flag_type {
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
-#define SXE2_REPRESENTOR_ID(pf, type, repr) \
- (((pf) << 14) + ((type) << 12) + ((repr) & 0xfff))
-
#define SXE2_I2C_EEPROM_DEV_ADDR 0xA0
#define SXE2_I2C_EEPROM_DEV_ADDR2 0xA2
#define SXE2_MODULE_TYPE_SFP 0x03
@@ -356,6 +353,9 @@ struct sxe2_adapter {
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
((struct sxe2_adapter *)(dev)->data->dev_private)
+#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+#define SXE2_PCI_REG_READ(reg) rte_read32(reg)
+
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint16_t idx_in_func);
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index a300b66771..10bdaf5b8d 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -12,8 +12,6 @@
#include "sxe2_drv_cmd.h"
#include "sxe2_txrx_common.h"
-#define SXE2_PCI_REG_READ(reg) \
- rte_read32(reg)
#define SXE2_PCI_REG_WRITE_WC(reg, value) \
rte_write32_wc((rte_cpu_to_le_32(value)), reg)
#define SXE2_PCI_REG_WRITE_WC_RELAXED(reg, value) \
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 05/13] net/sxe2: improve representor device initialization
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (3 preceding siblings ...)
2026-08-14 12:21 ` [PATCH v1 04/13] net/sxe2: enhance device cap and res management liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling liujie5
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch enhances the representor device initialization with:
- Add statistics initialization in sxe2_repr_dev_init
* Call sxe2_stats_init to setup statistics infrastructure
* Add proper error handling path for stats init failure
- Add representor device naming and NUMA node assignment:
* Update device name format to use base device name prefix
* Set numa_node from parent device data for proper NUMA locality
* Ensures representor devices are allocated on the same NUMA node
- Code style improvements:
* Align struct member fields in sxe2_adapter for consistency
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 24 ++++++++++++------------
drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +++++++++++--
2 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index cfcb7fcf00..d0a0f41ceb 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -314,10 +314,10 @@ struct sxe2_fc_state_ctxt {
};
struct sxe2_adapter {
- struct sxe2_common_device *cdev;
- struct sxe2_dev_info dev_info;
- struct rte_pci_device *pci_dev;
- struct sxe2_repr_private_data *repr_priv_data;
+ struct sxe2_common_device *cdev;
+ struct sxe2_dev_info dev_info;
+ struct rte_pci_device *pci_dev;
+ struct sxe2_repr_private_data *repr_priv_data;
struct sxe2_pci_map_context map_ctxt;
struct sxe2_irq_context irq_ctxt;
struct sxe2_queue_context q_ctxt;
@@ -338,16 +338,16 @@ struct sxe2_adapter {
bool rule_started;
bool flow_isolated;
bool flow_isolate_cfg;
- uint16_t dev_port_id;
+ uint16_t dev_port_id;
bool is_dev_repr;
- uint64_t cap_flags;
+ uint64_t cap_flags;
enum sxe2_dev_type dev_type;
- struct rte_ether_addr mac_addr;
- uint8_t port_idx;
- uint8_t pf_idx;
- uint32_t tx_mode_flags;
- uint32_t rx_mode_flags;
- uint8_t started;
+ struct rte_ether_addr mac_addr;
+ uint8_t port_idx;
+ uint8_t pf_idx;
+ uint32_t tx_mode_flags;
+ uint32_t rx_mode_flags;
+ uint8_t started;
};
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index f32318b731..b7096f5927 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -483,8 +483,16 @@ int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
goto l_init_sw_err;
}
+ ret = sxe2_stats_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
+ goto l_init_irq_ctxt_err;
+ }
+
goto l_end;
+l_init_irq_ctxt_err:
+ sxe2_sw_irq_ctxt_uninit(dev);
l_init_sw_err:
sxe2_eth_uinit(dev);
l_init_eth_err:
@@ -544,8 +552,8 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- snprintf(name, sizeof(name), "sxe2_representor_c%dpf%d%s%u",
- adapter->pf_idx, adapter->pf_idx,
+ snprintf(name, sizeof(name), "%s_representor_%s%u",
+ adapter->cdev->dev->name,
"vf",
req_eth_da->representor_ports[repr_idx]);
@@ -554,6 +562,7 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
ret = -ENOMEM;
goto l_release_port;
}
+ eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
eth_dev->data->dev_private = rte_zmalloc_socket(name,
sizeof(struct sxe2_adapter),
RTE_CACHE_LINE_SIZE,
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (4 preceding siblings ...)
2026-08-14 12:21 ` [PATCH v1 05/13] net/sxe2: improve representor device initialization liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit liujie5
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch refactors flow tunnel port handling and adds support for
PF bond devices:
- Refactor tunnel port functions from pattern module to flow module:
* Move sxe2_flow_parse_pattern_ipip from sxe2_flow_parse_pattern.c
* Move sxe2_flow_add_udp_tunnel_port from sxe2_flow_parse_pattern.c
* Move sxe2_flow_add_tunnel_port from public API to static function
* Remove public function declaration from header file
* Keep functions internal to flow module for better encapsulation
- Add PF bond device support in flow source split processing:
* Add bond_member_cnt field to sxe2_adapter structure
* Handle SXE2_DEV_T_PF_BOND device type in sxe2_flow_src_split_proc
* Populate flow_src_vsi for all bond members
- Enhance ACL engine support in flow actions:
* Add ACL engine support in flow action checks
* Allow PASSTHRU action for ACL engine
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 144 ++++++++++++++++++++-
drivers/net/sxe2/sxe2_flow_parse_action.c | 18 ++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ----------------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 7 -
5 files changed, 151 insertions(+), 132 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index d0a0f41ceb..36f4cc9353 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -340,6 +340,7 @@ struct sxe2_adapter {
bool flow_isolate_cfg;
uint16_t dev_port_id;
bool is_dev_repr;
+ uint16_t bond_member_cnt;
uint64_t cap_flags;
enum sxe2_dev_type dev_type;
struct rte_ether_addr mac_addr;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 3cf98dd294..af85cb0d2b 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -285,14 +285,16 @@ static int32_t sxe2_flow_meta_proc(struct rte_eth_dev *dev,
attr, "Only support priority 0.");
ret = -rte_errno;
goto l_end;
- } else if (!adapter->switchdev_info.is_switchdev) {
- PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
- rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
- attr, "Legacy mode only priority 0.");
- ret = -rte_errno;
- goto l_end;
} else {
- flow->meta.flow_prio = attr->priority;
+ if (!adapter->switchdev_info.is_switchdev) {
+ PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr, "Legacy mode only priority 0.");
+ ret = -rte_errno;
+ goto l_end;
+ } else {
+ flow->meta.flow_prio = attr->priority;
+ }
}
}
@@ -347,6 +349,21 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] = UINT16_MAX;
}
+ if (adapter->dev_type == SXE2_DEV_T_PF_BOND) {
+ flow_bond_num = adapter->bond_member_cnt;
+ for (idx = 0; idx < flow_bond_num; idx++) {
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] =
+ adapter->vsi_ctxt.bond_member_dpdk_vsi_id[idx];
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] =
+ adapter->vsi_ctxt.bond_member_kernel_vsi_id[idx];
+ }
+ } else {
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
+ adapter->vsi_ctxt.dpdk_vsi_id;
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
+ adapter->vsi_ctxt.kernel_vsi_id;
+ }
+
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] = adapter->vsi_ctxt.dpdk_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] = adapter->vsi_ctxt.kernel_vsi_id;
if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV ||
@@ -550,6 +567,119 @@ int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
+ enum sxe2_flow_udp_tunnel_protocol proto,
+ struct sxe2_flow *flow,
+ BITMAP_TYPE *flow_type)
+{
+ int32_t ret = 0;
+ uint16_t tun_port;
+
+ tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
+ if (tun_port == 0xffff || tun_port == 0) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
+ goto l_end;
+ }
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP must be over tunnel");
+ goto l_end;
+ }
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
+ flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
+l_end:
+ return ret;
+}
+
+static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
+{
+ sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ }
+ return 0;
+}
+
+static int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
+ struct rte_flow_error *error,
+ struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
+ enum sxe2_flow_tunnel_type tunnel_type)
+{
+ int32_t ret = 0;
+ enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
+ switch (tunnel_type) {
+ case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
+ } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
+ sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GTPU:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GRE:
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
+ }
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_IPIP:
+ ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
+ break;
+ default:
+ break;
+ }
+ if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
+ ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to add udp port for tunnel.");
+ PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
+ goto l_end;
+ }
+ }
+ if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
+ sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
struct rte_flow *flow_list,
struct rte_flow_error *error)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index cdd6fcfdcd..867d90ae1d 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -25,15 +25,21 @@ static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss
goto l_end;
}
- if (rss->level > 2)
+ if (rss->level > 2) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"RSS level is could not be greater than 2");
- if (rss->key_len)
+ goto l_end;
+ }
+ if (rss->key_len) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a nonzero RSS key_len is not supported");
- if (rss->queue_num)
+ goto l_end;
+ }
+ if (rss->queue_num) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a non-NULL RSS queue is not supported");
+ goto l_end;
+ }
ret = 0;
l_end:
return ret;
@@ -953,7 +959,8 @@ static int32_t sxe2_flow_check_actions(struct rte_eth_dev *dev __rte_unused, str
}
}
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
if (vsi_num) {
flow->action.q_region.q_index = 0;
flow->action.q_region.region = 7;
@@ -988,7 +995,8 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU, flow->action.act_types);
action_num[SXE2_FLOW_ACTION_PASSTHRU]++;
} else {
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.c b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
index f5bf8922c6..189abb1a33 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
@@ -1637,119 +1637,6 @@ static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *ite
return ret;
}
-static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
-{
- sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- }
- return 0;
-}
-
-static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
- enum sxe2_flow_udp_tunnel_protocol proto,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type)
-{
- int32_t ret = 0;
- uint16_t tun_port;
-
- tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
- if (tun_port == 0xffff || tun_port == 0) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
- goto l_end;
- }
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP must be over tunnel");
- goto l_end;
- }
- sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
- flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
-l_end:
- return ret;
-}
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type)
-{
- int32_t ret = 0;
- enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
- struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
- struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
- switch (tunnel_type) {
- case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
- } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
- sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GTPU:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GRE:
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
- }
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_IPIP:
- ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
- break;
- default:
- break;
- }
- if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
- ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
- if (ret != 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL, "Failed to add udp port for tunnel.");
- PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
- goto l_end;
- }
- }
- if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
- sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
- }
-l_end:
- return ret;
-}
-
struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = {
[SXE2_EXPANSION_OUTER_ETH] = {
.is_inner = false,
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.h b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
index 8442c35cae..6872a767dd 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.h
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
@@ -36,11 +36,4 @@ int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev,
const struct rte_flow_item patterns[],
struct rte_flow_error *error,
struct sxe2_flow *flow);
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type);
-
#endif /* SXE2_FLOW_PARSE_PATTERN_H_ */
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (5 preceding siblings ...)
2026-08-14 12:21 ` [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:21 ` [PATCH v1 08/13] net/sxe2: enhance repre event handling and MP code liujie5
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Add validation check in sxe2_security_valid_key to ensure source key
length does not exceed SXE2_IPSEC_MAX_KEY_LEN. This prevents potential
buffer overflows when processing security keys that are longer than
the supported maximum length.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ipsec.c | 5 +++++
drivers/net/sxe2/sxe2_security.c | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ipsec.c b/drivers/net/sxe2/sxe2_ipsec.c
index e783a51b85..622fd1adfe 100644
--- a/drivers/net/sxe2/sxe2_ipsec.c
+++ b/drivers/net/sxe2/sxe2_ipsec.c
@@ -254,6 +254,11 @@ static bool sxe2_security_valid_key(uint16_t src_key, uint16_t max_key,
goto l_end;
}
+ if (src_key > SXE2_IPSEC_MAX_KEY_LEN) {
+ is_valid = false;
+ goto l_end;
+ }
+
is_valid = true;
l_end:
diff --git a/drivers/net/sxe2/sxe2_security.c b/drivers/net/sxe2/sxe2_security.c
index bc59d1b880..8f31067942 100644
--- a/drivers/net/sxe2/sxe2_security.c
+++ b/drivers/net/sxe2/sxe2_security.c
@@ -326,6 +326,7 @@ void sxe2_security_uinit(struct rte_eth_dev *dev)
if (sctx != NULL) {
rte_free(sctx);
sctx = NULL;
+ dev->security_ctx = NULL;
}
sxe2_ipsec_uinit(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 08/13] net/sxe2: enhance repre event handling and MP code
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (6 preceding siblings ...)
2026-08-14 12:21 ` [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit liujie5
@ 2026-08-14 12:21 ` liujie5
2026-08-14 12:22 ` [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path liujie5
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:21 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch improves representor link state event handling and refactors
multi-process message processing:
- Add representor link state event propagation:
* Propagate LSC events to all VF representors when PF link changes
* Get link status and trigger callbacks for each representor
* Only process in primary process for representor callbacks
* Change OICR log format to hexadecimal for better readability
- Refactor primary process message handling:
* Extract work logic to sxe2_mp_do_primary_work helper function
* Use parameter copy to avoid side effects on original message
* Simplify reply construction in primary handler
- Simplify statistics interface:
* Remove qstats parameter from sxe2_mp_req_get_stats
* Remove qstats copy from shared memory
* Update function signature in header and implementation
- Improve error handling and cleanup:
* Change error return from EINVAL to ENODATA when no response
* Simplify sxe2_link_update_init error path
* Remove unnecessary goto statements and cleanup labels
* Remove extra whitespace
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 27 ++++++++++++---
drivers/net/sxe2/sxe2_mac.c | 10 ++----
drivers/net/sxe2/sxe2_mp.c | 65 +++++++++++++++++++----------------
drivers/net/sxe2/sxe2_mp.h | 3 +-
drivers/net/sxe2/sxe2_stats.c | 10 +++---
5 files changed, 67 insertions(+), 48 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 3306504761..7fe500b229 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -77,14 +77,32 @@ static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
{
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+ struct rte_eth_dev *repr_eth_dev;
+ struct sxe2_adapter *repr_adapter;
+ uint8_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
- PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
NULL);
+ }
+ if (adapter->switchdev_info.is_switchdev) {
+ for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
+ repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
+ if (!repr_eth_dev)
+ continue;
+ repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
+ (void)sxe2_drv_mac_link_status_get(repr_adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ rte_eth_dev_callback_process(repr_eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+ }
+ }
}
if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
@@ -863,12 +881,11 @@ static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
(void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
}
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
}
- rte_free(irq_ctxt->rxq_event_fd);
- irq_ctxt->rxq_event_fd = NULL;
rte_intr_vec_list_free(intr_handle);
-
rte_intr_nb_efd_set(intr_handle, 0);
rte_intr_max_intr_set(intr_handle, 0);
}
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
index 729c804ac3..e65c578262 100644
--- a/drivers/net/sxe2/sxe2_mac.c
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -448,20 +448,14 @@ int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
int32_t ret;
PMD_INIT_FUNC_TRACE();
-
rte_spinlock_init(&adapter->link_ctxt.link_lock);
-
ret = sxe2_drv_mac_link_status_get(adapter);
- if (ret) {
+ if (ret)
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get link status, ret=%d", ret);
- goto l_end;
- }
-
- (void)sxe2_link_update(dev, 0);
-l_end:
return ret;
}
+
int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete)
{
struct rte_eth_link new_link;
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..78986dbf14 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -29,16 +29,11 @@ static int32_t sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg,
const void *peer);
static int32_t
-sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+sxe2_mp_do_primary_work(struct sxe2_mp_param *param)
{
- struct rte_mp_msg reply;
- const struct sxe2_mp_param *param =
- (const struct sxe2_mp_param *)mp_msg->param;
- struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
struct rte_eth_dev *dev;
- int32_t ret = 0;
struct sxe2_mp_shared_data *mz_data;
- int32_t send_reply = 0;
+ int32_t ret = 0;
int32_t cnt = 0;
if (!rte_eth_dev_is_valid_port(param->port_id)) {
@@ -49,24 +44,21 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
}
dev = &rte_eth_devices[param->port_id];
- sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+
if (sxe2_mp_mz == NULL) {
- PMD_LOG_ERR(DRV, "Failed to lookup memzone %s", SXE2_MP_MZ_NAME);
- ret = -ENOENT;
- goto out;
+ sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+ if (sxe2_mp_mz == NULL) {
+ PMD_LOG_ERR(DRV, "Failed to lookup memzone %s",
+ SXE2_MP_MZ_NAME);
+ ret = -ENOENT;
+ goto out;
+ }
}
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
- send_reply = 1;
-
- memset(&reply, 0, sizeof(reply));
- (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
- reply.len_param = sizeof(*reply_param);
-
switch (param->type) {
case SXE2_MP_REQ_GET_STATS:
- ret = sxe2_stats_info_get(dev,
- &mz_data->payload.stats_blk.stats,
+ ret = sxe2_stats_info_get(dev, &mz_data->payload.stats_blk.stats,
&mz_data->payload.stats_blk.qstats);
break;
case SXE2_MP_REQ_GET_XSTATS:
@@ -88,15 +80,32 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
default:
PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
param->type);
- send_reply = false;
ret = -EINVAL;
- goto out;
+ break;
}
+
out:
- if (!send_reply)
- return ret;
+ param->result = ret;
+ return ret;
+}
- reply_param->result = ret;
+static int32_t
+sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+{
+ struct rte_mp_msg reply;
+ struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
+ const struct sxe2_mp_param *param =
+ (const struct sxe2_mp_param *)mp_msg->param;
+ struct sxe2_mp_param param_copy;
+
+ memset(&reply, 0, sizeof(reply));
+ (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
+ reply.len_param = sizeof(*reply_param);
+
+ param_copy = *param;
+ (void)sxe2_mp_do_primary_work(¶m_copy);
+
+ reply_param->result = param_copy.result;
reply_param->type = param->type;
reply_param->port_id = param->port_id;
@@ -275,7 +284,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
if (reply.nb_received == 0) {
PMD_LOG_ERR(DRV, "No response received from primary for type=%d, port %u",
type, dev->data->port_id);
- ret = -EINVAL;
+ ret = -ENODATA;
goto out;
}
@@ -289,8 +298,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
}
int32_t sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
- struct rte_eth_stats *stats,
- struct eth_queue_stats *qstats)
+ struct rte_eth_stats *stats)
{
struct sxe2_mp_shared_data *mz_data;
int32_t mp_ret;
@@ -303,7 +311,7 @@ int32_t sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
PMD_LOG_WARN(DRV, "Primary process direct execution for port %u",
dev->data->port_id);
- return sxe2_stats_info_get(dev, stats, qstats);
+ return sxe2_stats_info_get(dev, stats, NULL);
}
int32_t token_ret = sxe2_mp_acquire_token();
@@ -325,7 +333,6 @@ int32_t sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
memcpy(stats, &mz_data->payload.stats_blk.stats, sizeof(*stats));
- memcpy(qstats, &mz_data->payload.stats_blk.qstats, sizeof(*qstats));
PMD_LOG_DEBUG(DRV, "sxe2_mp: stats received via IPC for port %u",
dev->data->port_id);
ret = 0;
diff --git a/drivers/net/sxe2/sxe2_mp.h b/drivers/net/sxe2/sxe2_mp.h
index da9cc91d8d..1f779a1332 100644
--- a/drivers/net/sxe2/sxe2_mp.h
+++ b/drivers/net/sxe2/sxe2_mp.h
@@ -56,8 +56,7 @@ int sxe2_mp_request_simple(struct rte_eth_dev *dev,
int *result_out);
int sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
- struct rte_eth_stats *stats,
- struct eth_queue_stats *qstats);
+ struct rte_eth_stats *stats);
int sxe2_mp_req_get_xstats(struct rte_eth_dev *dev,
struct rte_eth_xstat *xstats, uint32_t usr_cnt);
diff --git a/drivers/net/sxe2/sxe2_stats.c b/drivers/net/sxe2/sxe2_stats.c
index 3ad8fe2fe9..b91d8d1555 100644
--- a/drivers/net/sxe2/sxe2_stats.c
+++ b/drivers/net/sxe2/sxe2_stats.c
@@ -318,7 +318,7 @@ int32_t sxe2_stats_info_get(struct rte_eth_dev *dev,
struct sxe2_stats *stats_out = &vsi->vsi_stats.stats;
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
- return sxe2_mp_req_get_stats(dev, stats, qstats);
+ return sxe2_mp_req_get_stats(dev, stats);
ret = sxe2_vsi_hw_stats_get_update(adapter);
if (ret)
@@ -328,9 +328,11 @@ int32_t sxe2_stats_info_get(struct rte_eth_dev *dev,
if (ret)
goto end;
- ret = sxe2_drv_queue_info_get_update(adapter, qstats);
- if (ret)
- goto end;
+ if (qstats) {
+ ret = sxe2_drv_queue_info_get_update(adapter, qstats);
+ if (ret)
+ goto end;
+ }
sxe2_stats_update(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (7 preceding siblings ...)
2026-08-14 12:21 ` [PATCH v1 08/13] net/sxe2: enhance repre event handling and MP code liujie5
@ 2026-08-14 12:22 ` liujie5
2026-08-14 12:22 ` [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset liujie5
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:22 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch optimizes vectorized packet processing with improved buffer
management and unified buffer structure:
- Introduce unified Tx buffer structure:
* Add union in sxe2_tx_queue for buffer_ring/buffer_ring_vec
* Use sxe2_tx_buffer_vec for vectorized Tx path
* Eliminate runtime type checking and branching
- Refactor Tx queue reset operations:
* Extract desc ring reset to sxe2_tx_queue_desc_ring_reset
* Add sxe2_tx_queue_reset_vec for vectorized queues
* Simplify buffer initialization in vector mode
- Optimize Tx vector path mbuf release:
* Remove conditional AVX512 branching
* Use direct buffer_vec access without casting
* Simplify loop logic with consistent pattern
* Remove NULL checks after initialization validation
- Refactor Tx queue operations:
* Export sxe2_tx_buffer_ring_free as public API
* Add sxe2_tx_vec_ops_get() for vector operations
* Use operation table instead of direct function calls
- Improve VSI management:
* Initialize other_vsi_list before main VSI creation
* Ignore -EPERM errors when destroying VSI in uninit
* Set main_vsi to NULL after successful destroy
* Prevent dangling pointer references
- Enhance Tx mode function selection:
* Use rte_eth_tx_pkt_prepare_dummy for vectorized paths
* Split NEON simple/offload mode selection logic
* Clean up conditional compilation structure
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_queue.h | 5 +-
drivers/net/sxe2/sxe2_rx.c | 5 +-
drivers/net/sxe2/sxe2_switchdev.c | 8 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++--
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 19 ++-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 77 +++------
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 123 +-------------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 215 ++++++++++++++++--------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
15 files changed, 247 insertions(+), 287 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index 10bdaf5b8d..e53a1ce852 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -62,7 +62,10 @@ struct sxe2_txq_ops {
};
struct sxe2_tx_queue {
volatile union sxe2_tx_data_desc *desc_ring;
- struct sxe2_tx_buffer *buffer_ring;
+ union {
+ struct sxe2_tx_buffer *buffer_ring;
+ struct sxe2_tx_buffer_vec *buffer_ring_vec;
+ };
volatile uint32_t *tdt_reg_addr;
uint64_t offloads;
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index d700c60083..6340ed933a 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -319,7 +319,8 @@ int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
}
- rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ SXE2_DEFAULT_RX_FREE_THRESH : rx_conf->rx_free_thresh;
rxq->port_id = dev->data->port_id;
rxq->offloads = offloads;
if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
@@ -550,7 +551,7 @@ void __rte_cold sxe2_rxqs_all_stop(struct rte_eth_dev *dev)
static int32_t sxe2_monitor_callback(const uint64_t value,
const uint64_t arg[RTE_POWER_MONITOR_OPAQUE_SZ] __rte_unused)
{
- const uint64_t dd_state = rte_cpu_to_le_64(SXE2_RX_DESC_STATUS_DD_MASK);
+ const uint64_t dd_state = rte_cpu_to_le_64(SXE2_RX_DESC_STATUS_DD_SHIFT);
return (value & dd_state) == dd_state ? -1 : 0;
}
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index efb1468b91..374cc4e223 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -316,13 +316,7 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
-
- repr_priv_data->repr_vf_vsi_id =
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
- SXE2_INVALID_VSI_ID ?
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
-
+ repr_priv_data->repr_vf_vsi_id = repr_priv_data->repr_vf_primary_vsi_id;
adapter->repr_priv_data = repr_priv_data;
goto l_end;
l_free:
diff --git a/drivers/net/sxe2/sxe2_tx.c b/drivers/net/sxe2/sxe2_tx.c
index f49238ceef..94a6e9afc7 100644
--- a/drivers/net/sxe2/sxe2_tx.c
+++ b/drivers/net/sxe2/sxe2_tx.c
@@ -19,6 +19,17 @@ static void *sxe2_tx_doorbell_addr_get(struct sxe2_adapter *adapter, uint16_t qu
queue_id);
}
+static void sxe2_tx_queue_desc_ring_reset(struct sxe2_tx_queue *txq)
+{
+ uint16_t i;
+ static const union sxe2_tx_data_desc zeroed_desc = {{0}};
+
+ for (i = 0; i < txq->ring_depth; i++) {
+ txq->desc_ring[i] = zeroed_desc;
+ txq->desc_ring[i].wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
+ }
+}
+
static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue *txq)
{
txq->tdt_reg_addr = sxe2_tx_doorbell_addr_get(adapter, txq->queue_id);
@@ -28,20 +39,12 @@ static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
{
uint16_t prev, i;
- volatile union sxe2_tx_data_desc *txd;
- static const union sxe2_tx_data_desc zeroed_desc = {{0}};
struct sxe2_tx_buffer *tx_buffer = txq->buffer_ring;
- for (i = 0; i < txq->ring_depth; i++)
- txq->desc_ring[i] = zeroed_desc;
+ sxe2_tx_queue_desc_ring_reset(txq);
prev = txq->ring_depth - 1;
for (i = 0; i < txq->ring_depth; i++) {
- txd = &txq->desc_ring[i];
- if (txd == NULL)
- continue;
-
- txd->wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
tx_buffer[i].mbuf = NULL;
tx_buffer[i].last_id = i;
tx_buffer[prev].next_id = i;
@@ -56,6 +59,21 @@ void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
txq->next_rs = txq->rs_thresh - 1;
}
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq)
+{
+ sxe2_tx_queue_desc_ring_reset(txq);
+
+ memset(txq->buffer_ring, 0,
+ sizeof(struct sxe2_tx_buffer) * txq->ring_depth);
+
+ txq->desc_used_num = 0;
+ txq->desc_free_num = txq->ring_depth - 1;
+ txq->next_use = 0;
+ txq->next_clean = txq->ring_depth - 1;
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
{
uint32_t i;
@@ -70,10 +88,12 @@ void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
}
}
-static void sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
{
- if (txq != NULL && txq->buffer_ring != NULL)
+ if (txq != NULL && txq->buffer_ring != NULL) {
rte_free(txq->buffer_ring);
+ txq->buffer_ring = NULL;
+ }
}
const struct sxe2_txq_ops sxe2_default_txq_ops = {
diff --git a/drivers/net/sxe2/sxe2_tx.h b/drivers/net/sxe2/sxe2_tx.h
index f4823126b3..bc5ff1c2bc 100644
--- a/drivers/net/sxe2/sxe2_tx.h
+++ b/drivers/net/sxe2/sxe2_tx.h
@@ -9,6 +9,10 @@
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq);
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq);
+
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq);
+
int32_t __rte_cold sxe2_tx_queue_start(struct rte_eth_dev *dev, uint16_t queue_id);
void sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq);
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index 79870866d1..d27d2ce630 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -358,7 +358,7 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
#ifdef RTE_ARCH_X86
if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX512) {
#ifdef CC_AVX512_SUPPORT
@@ -386,21 +386,25 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
#elif defined(RTE_ARCH_ARM64)
if (tx_mode_flags & SXE2_TX_MODE_VEC_NEON) {
- dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
- } else {
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ } else {
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ }
}
#endif
} else {
if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
dev->tx_pkt_burst = sxe2_tx_pkts_simple;
} else {
dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
dev->tx_pkt_burst = sxe2_tx_pkts;
}
}
+ PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x port_id:%u.",
+ tx_mode_flags, dev->data->port_id);
}
static const struct {
@@ -582,6 +586,9 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
else
dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
+
+ PMD_LOG_DEBUG(RX, "Rx mode flags:0x%016x port_id:%u.",
+ rx_mode_flags, dev->data->port_id);
}
static const struct {
diff --git a/drivers/net/sxe2/sxe2_txrx_poll.h b/drivers/net/sxe2/sxe2_txrx_poll.h
index 708e3839d7..bfa099c097 100644
--- a/drivers/net/sxe2/sxe2_txrx_poll.h
+++ b/drivers/net/sxe2/sxe2_txrx_poll.h
@@ -13,8 +13,6 @@ uint16_t sxe2_tx_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-
uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
#endif /* SXE2_TXRX_POLL_H */
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index cf004f5eb2..31ab66708c 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -8,6 +8,19 @@
#include "sxe2_ethdev.h"
#include "sxe2_common_log.h"
+static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq);
+
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void)
+{
+ static const struct sxe2_txq_ops ops = {
+ .queue_reset = sxe2_tx_queue_reset_vec,
+ .mbufs_release = sxe2_tx_queue_mbufs_release_vec,
+ .buffer_ring_free = sxe2_tx_buffer_ring_free,
+ };
+
+ return ops;
+}
+
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags)
{
struct sxe2_rx_queue *rxq;
@@ -157,67 +170,28 @@ int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *
static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer_vec;
uint16_t i;
if (unlikely(txq == NULL || txq->buffer_ring == NULL)) {
PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params.");
return;
}
- i = txq->next_dd - (txq->rs_thresh - 1);
-#ifdef CC_AVX512_SUPPORT
- struct rte_eth_dev *dev;
- struct sxe2_tx_buffer_vec *buffer_vec;
- dev = &rte_eth_devices[txq->port_id];
-
- if (dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512 ||
- dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512_simple) {
- buffer_vec = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ i = txq->next_dd - (txq->rs_thresh - 1);
+ buffer_vec = txq->buffer_ring_vec;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for ( ; i < txq->next_use; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
+ if (txq->next_use < i) {
+ for ( ; i < txq->ring_depth; ++i) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
- } else {
-#endif
- buffer = txq->buffer_ring;
- buffer = txq->buffer_ring;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
-#ifdef CC_AVX512_SUPPORT
+ i = 0;
}
-#endif
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
+ for ( ; i < txq->next_use; ++i) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
}
@@ -233,7 +207,8 @@ int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev)
PMD_LOG_INFO(TX, "Failed to prepare tx queue, txq[%d] is NULL", i);
continue;
}
- txq->ops.mbufs_release = sxe2_tx_queue_mbufs_release_vec;
+ txq->ops = sxe2_tx_vec_ops_get();
+ txq->ops.queue_reset(txq);
}
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index c139aed776..b9bc4f9c27 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -89,6 +89,7 @@ uint16_t sxe2_rx_pkts_scattered_vec_neon_offload(void *rx_queue, struct rte_mbuf
uint16_t sxe2_tx_pkts_vec_neon_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
#endif
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void);
int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev);
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
index 0618e6d988..da96ca3064 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -115,7 +115,7 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -134,14 +134,14 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -157,10 +157,10 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
index a830c7a33b..deea4c2720 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
*/
-
-#ifndef SXE2_TEST
#include <rte_vect.h>
#include "sxe2_ethdev.h"
@@ -12,114 +10,6 @@
#include "sxe2_txrx_vec_common.h"
#include "sxe2_vsi.h"
-static __rte_always_inline int32_t sxe2_tx_bufs_free_vec_avx512(struct sxe2_tx_queue *txq)
-{
- struct sxe2_tx_buffer_vec *buffer;
- struct rte_mbuf *mbuf;
- struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
- struct rte_mempool *mp;
- struct rte_mempool_cache *cache;
- void **cache_objs;
- uint32_t copied;
- uint32_t i;
- int32_t ret;
- uint16_t rs_thresh;
- uint16_t free_num;
-
- if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
- (txq->desc_ring[txq->next_dd].wb.dd &
- rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
- ret = 0;
- goto l_end;
- }
-
- rs_thresh = txq->rs_thresh;
-
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += txq->next_dd - (rs_thresh - 1);
-
- if ((txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
- (rs_thresh & 31) == 0) {
- mp = buffer[0].mbuf->pool;
- cache = rte_mempool_default_cache(mp, rte_lcore_id());
-
- if (cache == NULL || cache->len)
- goto normal;
-
- if (rs_thresh > RTE_MEMPOOL_CACHE_MAX_SIZE) {
- (void)rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh);
- goto done;
- }
- cache_objs = &cache->objs[cache->len];
-
- copied = 0;
- while (copied < rs_thresh) {
- const __m512i objs0 = _mm512_loadu_si512(&buffer[copied]);
- const __m512i objs1 = _mm512_loadu_si512(&buffer[copied + 8]);
- const __m512i objs2 = _mm512_loadu_si512(&buffer[copied + 16]);
- const __m512i objs3 = _mm512_loadu_si512(&buffer[copied + 24]);
-
- _mm512_storeu_si512(&cache_objs[copied], objs0);
- _mm512_storeu_si512(&cache_objs[copied + 8], objs1);
- _mm512_storeu_si512(&cache_objs[copied + 16], objs2);
- _mm512_storeu_si512(&cache_objs[copied + 24], objs3);
- copied += 32;
- }
- cache->len += rs_thresh;
-
- if (cache->len >= cache->flushthresh) {
- (void)rte_mempool_ops_enqueue_bulk(mp,
- &cache->objs[cache->size], cache->len - cache->size);
- cache->len = cache->size;
- }
- goto done;
- }
-
-normal:
- mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
-
- if (likely(mbuf)) {
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
-
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
-
- if (likely(mbuf)) {
- if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
- mbuf_free_arr[free_num] = mbuf;
- free_num++;
- } else {
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
-
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
- }
- }
- }
-
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
- } else {
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
- if (mbuf != NULL)
- rte_mempool_put(mbuf->pool, mbuf);
- }
- }
-
-done:
- txq->desc_free_num += txq->rs_thresh;
- txq->next_dd += txq->rs_thresh;
- if (txq->next_dd >= txq->ring_depth)
- txq->next_dd = txq->rs_thresh - 1;
- ret = rs_thresh;
-
-l_end:
- return ret;
-}
-
static __rte_always_inline void
sxe2_tx_desc_fill_one_avx512(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
uint64_t desc_cmd, bool with_offloads)
@@ -228,7 +118,7 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
uint16_t tx_num;
if (txq->desc_free_num < txq->free_thresh)
- (void)sxe2_tx_bufs_free_vec_avx512(txq);
+ (void)sxe2_tx_bufs_free_vec(txq);
nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
if (unlikely(nb_pkts == 0)) {
@@ -241,15 +131,14 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += next_use;
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -265,10 +154,10 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = txq->desc_ring;
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -863,5 +752,3 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
return sxe2_rx_pkts_scattered_common_vec_avx512(rx_queue,
rx_pkts, nb_pkts, true);
}
-
-#endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_common.h b/drivers/net/sxe2/sxe2_txrx_vec_common.h
index 9ac99cf0fa..d16d0a5a5a 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_common.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec_common.h
@@ -25,10 +25,11 @@
#define SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC 64
static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+sxe2_tx_pkts_mbuf_fill_vec(struct sxe2_tx_buffer_vec *buffer,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
uint16_t i;
+
for (i = 0; i < nb_pkts; ++i)
buffer[i].mbuf = tx_pkts[i];
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_neon.c b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
index 4e5cb87cd5..c39e4ad81c 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_neon.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
@@ -34,6 +34,51 @@ sxe2_tx_desc_fill_one_neon(volatile union sxe2_tx_data_desc *desc,
vst1q_u64(RTE_CAST_PTR(uint64_t *, desc), data_desc);
}
+static __rte_always_inline void
+sxe2_tx_desc_fill_4_neon_simple(volatile union sxe2_tx_data_desc *desc,
+ struct rte_mbuf **pkts)
+{
+ uint64x2_t d0, d1, d2, d3;
+ uint64x2x4_t v;
+ const u64 cmd_base = ((u64)SXE2_TX_DESC_DTYPE_DATA) |
+ ((u64)SXE2_TX_DATA_DESC_CMD_EOP) << SXE2_TX_DATA_DESC_CMD_SHIFT;
+
+ d0 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[0]),
+ cmd_base |
+ ((u64)pkts[0]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((u64)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d1 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[1]),
+ cmd_base |
+ ((u64)pkts[1]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((u64)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d2 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[2]),
+ cmd_base |
+ ((u64)pkts[2]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((u64)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d3 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[3]),
+ cmd_base |
+ ((u64)pkts[3]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((u64)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+
+ v.val[0] = d0;
+ v.val[1] = d1;
+ v.val[2] = d2;
+ v.val[3] = d3;
+ vst1q_u64_x4((u64 *)desc, v);
+}
+
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
@@ -66,11 +111,19 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
-
- for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
+ if (with_offloads) {
+ for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ }
+ } else {
+ for (i = 0; i + 3 < res_num - 1; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
sxe2_tx_desc_fill_one_neon(desc, *tx_pkts++,
@@ -82,14 +135,23 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
- for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ if (with_offloads) {
+ for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, true);
+ }
+ } else {
+ for (i = 0; i + 3 < tx_num; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
next_use += tx_num;
@@ -150,22 +212,24 @@ uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue,
}
static __rte_always_inline void
-sxe2_rx_desc_ptype_fill_neon(uint16x8_t staterr, struct rte_mbuf **__rte_restrict rx_pkts)
+sxe2_rx_desc_ptype_fill_neon(uint32x4_t desc_lo,
+ struct rte_mbuf **__rte_restrict rx_pkts,
+ const u32 *__rte_restrict ptype_tbl)
{
- uint16x8_t ptype_mask = {
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
+ const uint32x4_t ptype_mask = {
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
};
uint16x8_t ptype_all;
- ptype_all = vandq_u16(staterr, ptype_mask);
+ ptype_all = vreinterpretq_u16_u32(vandq_u32(desc_lo, ptype_mask));
- rx_pkts[3]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
- rx_pkts[2]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
- rx_pkts[1]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
- rx_pkts[0]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[0]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
+ rx_pkts[1]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
+ rx_pkts[2]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[3]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
}
static __rte_always_inline uint32x4_t
@@ -208,9 +272,10 @@ sxe2_rx_desc_fnav_flags_neon(uint64x2_t descs_arr[4])
static __rte_always_inline void
sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
volatile union sxe2_rx_desc *desc,
- uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+ uint64x2_t descs[4], uint32x4_t desc_lo, uint32x4_t desc_hi,
+ struct rte_mbuf **rx_pkts)
{
- uint32x4_t desc_lo, desc_hi, flags, tmp_flags;
+ uint32x4_t flags, tmp_flags;
const uint64x2_t mbuf_init = {rxq->mbuf_init_value, 0};
uint64x2_t rearm0, rearm1, rearm2, rearm3;
@@ -267,23 +332,6 @@ sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
0, 0, 0, 0, 0, 0, 0, 0
};
- {
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint64x2_t f64, t64;
-
- flags = vzip2q_u32(d1, d0);
- tmp_flags = vzip2q_u32(d3, d2);
- f64 = vreinterpretq_u64_u32(flags);
- t64 = vreinterpretq_u64_u32(tmp_flags);
- desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(f64),
- vget_low_u64(t64)));
- desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(f64),
- vget_high_u64(t64)));
- }
-
desc_lo = vandq_u32(desc_lo, desc_msk);
desc_hi = vandq_u32(desc_hi, rss_msk);
@@ -407,6 +455,7 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
struct rte_mbuf **buffer;
uint32_t i;
uint16_t done_num = 0;
+ const u32 *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
uint8x16_t rvp_shuf_mask = {
0xFF, 0xFF, 0xFF, 0xFF,
@@ -442,25 +491,39 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
uint64x2_t descs[SXE2_RX_NUM_PER_LOOP_NEON];
uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
uint64x2_t mbp1, mbp2;
+ uint32x4_t desc_lo, desc_hi;
uint16x8_t staterr;
uint16x8_t tmp;
uint16_t bit_num;
descs[3] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 3));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[2] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 2));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[1] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 1));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[0] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc));
rte_atomic_thread_fence(rte_memory_order_acquire);
-
descs[3] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 3), descs[3], 0);
descs[2] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 2), descs[2], 0);
descs[1] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 1), descs[1], 0);
descs[0] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc), descs[0], 0);
+ {
+ uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
+ uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
+ uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
+ uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
+
+ uint32x4_t q1_01 = vzip2q_u32(d0, d1);
+ uint32x4_t q1_23 = vzip2q_u32(d2, d3);
+ uint64x2_t q1_01_64 = vreinterpretq_u64_u32(q1_01);
+ uint64x2_t q1_23_64 = vreinterpretq_u64_u32(q1_23);
+
+ desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(q1_01_64),
+ vget_low_u64(q1_23_64)));
+ desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(q1_01_64),
+ vget_high_u64(q1_23_64)));
+ }
+
mbp1 = vld1q_u64((uint64_t *)&buffer[i]);
mbp2 = vld1q_u64((uint64_t *)&buffer[i + 2]);
@@ -480,7 +543,8 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), rvp_shuf_mask);
if (do_offload) {
- sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, &rx_pkts[i]);
+ sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, desc_lo,
+ desc_hi, &rx_pkts[i]);
} else {
const uint64x2_t mbuf_init = {
rxq->mbuf_init_value,
@@ -515,55 +579,48 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
rte_prefetch_non_temporal(desc + SXE2_RX_NUM_PER_LOOP_NEON);
{
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint32x4_t sterr_tmp1 = vzip2q_u32(d1, d0);
- uint32x4_t sterr_tmp2 = vzip2q_u32(d3, d2);
- uint32x4_t sterr_u32 = vzip1q_u32(sterr_tmp1, sterr_tmp2);
-
- staterr = vreinterpretq_u16_u32(sterr_u32);
+ uint16x8_t sterr_tmp1 = vzip2q_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+ uint16x8_t sterr_tmp2 = vzip2q_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ staterr = vzip1q_u16(sterr_tmp1, sterr_tmp2);
}
- sxe2_rx_desc_ptype_fill_neon(staterr, &rx_pkts[i]);
+ sxe2_rx_desc_ptype_fill_neon(desc_lo, &rx_pkts[i], ptype_tbl);
if (umbcast_flags != NULL) {
- uint32x4_t umbcast_mask = {
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- };
-
+ const uint32x4_t umbcast_mask =
+ vdupq_n_u32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
uint8x16_t umbcast_shuf_mask = {
- 0x0B, 0x03, 0x0F, 0x07,
+ 3, 7, 11, 15,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
};
uint8x16_t umbcast_bits =
- vreinterpretq_u8_u32(vandq_u32(vreinterpretq_u32_u16(staterr),
- umbcast_mask));
+ vreinterpretq_u8_u32(vandq_u32(desc_lo, umbcast_mask));
umbcast_bits = vqtbl1q_u8(umbcast_bits, umbcast_shuf_mask);
- vst1q_lane_u32((uint32_t *)umbcast_flags,
- vreinterpretq_u32_u8(umbcast_bits), 0);
+ *(u32 *)umbcast_flags =
+ vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
umbcast_flags += SXE2_RX_NUM_PER_LOOP_NEON;
}
if (split_rxe_flags) {
uint8x16_t eop_shuf_mask = {
- 0x08, 0x00, 0x0C, 0x04,
+ 0, 2, 4, 6,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
uint8x16_t eop_bits;
uint32x4_t rxe_mask = {
- 0x2080, 0x2080, 0x2080, 0x2080
+ 0x20802080, 0x20802080, 0x20802080, 0x20802080
};
uint32x4_t rxe_bits;
uint32x4_t eop_mask;
- eop_mask = vshlq_n_u32(vdupq_n_u32(1), SXE2_RX_DESC_STATUS_EOP_SHIFT);
+ eop_mask = vdupq_n_u32((1U << SXE2_RX_DESC_STATUS_EOP_SHIFT) |
+ (1U << (SXE2_RX_DESC_STATUS_EOP_SHIFT + 16)));
eop_bits = vandq_u8(vmvnq_u8(vreinterpretq_u8_u16(staterr)),
vreinterpretq_u8_u32(eop_mask));
@@ -587,12 +644,22 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
}
{
- uint32x4_t dd_mask = vdupq_n_u32(1);
- uint32x4_t sterr_dd = vandq_u32(vreinterpretq_u32_u16(staterr), dd_mask);
- uint16x4_t packed_lo = vmovn_u32(sterr_dd);
- uint64_t dd64 = vget_lane_u64(vreinterpret_u64_u16(packed_lo), 0);
-
- bit_num = (uint16_t)rte_popcount64(dd64);
+ const uint16x8_t dd_check = {
+ 0x0001, 0x0001, 0x0001, 0x0001,
+ 0, 0, 0, 0
+ };
+ uint16x8_t sterr_dd;
+ uint64_t stat;
+ sterr_dd = vandq_u16(staterr, dd_check);
+ sterr_dd = vshlq_n_u16(sterr_dd, 15);
+ sterr_dd =
+ vreinterpretq_u16_s16(vshrq_n_s16(vreinterpretq_s16_u16(sterr_dd),
+ 15));
+ stat = ~vgetq_lane_u64(vreinterpretq_u64_u16(sterr_dd), 0);
+ if (likely(stat == 0))
+ bit_num = SXE2_RX_NUM_PER_LOOP_NEON;
+ else
+ bit_num = (u16)(rte_ctz64(stat) / 16);
}
done_num += bit_num;
if (likely(bit_num != SXE2_RX_NUM_PER_LOOP_NEON))
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_sse.c b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
index c3e8a2983b..181bb40041 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_sse.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
@@ -40,7 +40,7 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -57,11 +57,11 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
tx_num = nb_pkts;
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
@@ -74,9 +74,9 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..ba4cc7414e 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -230,7 +230,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
uint16_t srcvsi_cnt;
PMD_INIT_FUNC_TRACE();
-
+ TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
ret = sxe2_main_vsi_create(adapter);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +283,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
l_free:
ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
goto l_end;
}
+ adapter->vsi_ctxt.main_vsi = NULL;
RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, tvar) {
ret = sxe2_vsi_destroy(adapter, var);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
break;
}
@@ -357,4 +358,5 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+ adapter->vsi_ctxt.main_vsi = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (8 preceding siblings ...)
2026-08-14 12:22 ` [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path liujie5
@ 2026-08-14 12:22 ` liujie5
2026-08-14 12:22 ` [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations liujie5
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:22 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch improves error handling and resource management:
- Add NULL pointer protection in driver remove path:
* Check cdrv and cdrv->remove before calling remove function
* Prevent NULL pointer dereference in sxe2_classes_driver_remove
* Return SXE2_SUCCESS if no driver or remove handler exists
- Allow memory unmap during kernel reset:
* Remove kernel_reset restriction in sxe2_drv_dev_munmap
* Enable cleanup operations even when kernel has been reset
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_common.c | 5 ++++-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-------
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_common.c b/drivers/common/sxe2/sxe2_common.c
index 5c5db85f29..3f60b2be11 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -465,8 +465,11 @@ static int32_t sxe2_classes_driver_probe(struct sxe2_common_device *cdev,
static int32_t sxe2_classes_driver_remove(struct sxe2_common_device *cdev)
{
struct sxe2_class_driver *cdrv = cdev->cdrv;
+ int32_t ret = 0;
- return cdrv->remove(cdev);
+ if (cdrv != NULL && cdrv->remove != NULL)
+ ret = cdrv->remove(cdev);
+ return ret;
}
static int32_t sxe2_kvargs_validate(struct sxe2_dev_kvargs_info *kv_info)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index a233a78136..3e2fbf572f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -367,16 +367,10 @@ void
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
int32_t
-sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
+sxe2_drv_dev_munmap(struct sxe2_common_device *cdev __rte_unused, void *virt, uint64_t len)
{
int32_t ret = 0;
- if (cdev->config.kernel_reset) {
- ret = -EPERM;
- PMD_LOG_WARN(COM, "kernel reset, need restart app.");
- goto l_end;
- }
-
PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
virt, len);
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (9 preceding siblings ...)
2026-08-14 12:22 ` [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset liujie5
@ 2026-08-14 12:22 ` liujie5
2026-08-14 12:22 ` [PATCH v1 12/13] net/sxe2: clean up structure definitions liujie5
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:22 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This commit removes duplicate function declarations in the sxe2
driver header files.
- Remove duplicate sxe2_drv_promisc_config declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_drv_vsi_info_get declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_drv_mac_link_status_get declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_drv_rxq_mapping_set declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_dev_pci_seg_unmap declaration
in sxe2_ethdev.h
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.h | 6 ------
drivers/net/sxe2/sxe2_ethdev.h | 2 --
2 files changed, 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 7d75a91061..7d07068bfc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -65,8 +65,6 @@ int32_t sxe2_drv_ipsec_rxsa_delete(struct sxe2_adapter *adapter,
int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
uint16_t sa_id);
-int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
-
int32_t sxe2_drv_udp_tunnel_add(struct sxe2_adapter *adapter,
enum sxe2_udp_tunnel_protocol tunnel_proto,
uint16_t udp_port);
@@ -84,8 +82,6 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-
int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
@@ -110,8 +106,6 @@ int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev);
int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev);
-int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
-
int32_t sxe2_drv_allmulti_config(struct sxe2_adapter *adapter, bool set);
int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *addr, bool add);
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 36f4cc9353..b43030deab 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -387,8 +387,6 @@ void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
-void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
-
int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
enum sxe2_udp_tunnel_protocol tunnel_proto, uint16_t udp_port);
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 12/13] net/sxe2: clean up structure definitions
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (10 preceding siblings ...)
2026-08-14 12:22 ` [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations liujie5
@ 2026-08-14 12:22 ` liujie5
2026-08-14 12:22 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
2026-08-14 18:44 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:22 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This commit removes packed attributes and unused reserved fields
from structure definitions in the sxe2 driver header file.
- Remove packed attributes and rsv[2] field from sxe2_tm_res
structure
- Remove packed attributes from sxe2_tm_info structure
- Remove packed attributes from sxe2_txq_map_info structure
- Remove packed attributes from sxe2_rxq_map_info structure
- Remove packed attributes from sxe2_queue_map_info structure
- Remove packed attributes from sxe2_drv_sfp_req structure
- Remove packed attributes from sxe2_drv_sfp_resp structure
- Remove unused rsv[3] field from sxe2_drv_link_info_resp
structure
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index aa56d9436a..34160b93cb 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -230,7 +230,6 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_info_get_resp {
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_link_info_resp {
uint32_t speed;
uint8_t status;
- uint8_t rsv[3];
} __rte_packed_end;
struct __rte_aligned(4) __rte_packed_begin sxe2_switchdev_info {
@@ -348,18 +347,17 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_rss_hf_req {
uint8_t rsv1[3];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_res {
+struct sxe2_tm_res {
uint16_t teid;
- uint8_t rsv[2];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_info {
+struct sxe2_tm_info {
uint32_t committed;
uint32_t peak;
uint8_t priority;
uint8_t reserve;
uint16_t weight;
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_mid_msg {
uint16_t parent_teid;
@@ -526,24 +524,24 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_mac_stats_resp {
uint64_t prio_xon_2_xoff[SXE2_MAX_USER_PRIORITY];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_txq_map_info {
+struct sxe2_txq_map_info {
uint32_t txq_lan_pkt_cnt;
uint32_t txq_lan_byte_cnt;
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_rxq_map_info {
+struct sxe2_rxq_map_info {
uint64_t rxq_lan_in_pkt_cnt;
uint64_t rxq_lan_in_byte_cnt;
uint64_t rxq_fd_in_pkt_cnt;
uint64_t rxq_mng_in_pkt_cnt;
uint64_t rxq_mng_in_byte_cnt;
uint64_t rxq_mng_out_pkt_cnt;
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_queue_map_info {
+struct sxe2_queue_map_info {
struct sxe2_rxq_map_info rxq_stats_map_info[SXE2_RXQ_STATS_MAP_MAX_NUM];
struct sxe2_txq_map_info txq_stats_map_info[SXE2_TXQ_STATS_MAP_MAX_NUM];
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_rx_map_req {
uint16_t queue_id;
@@ -633,7 +631,7 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_udp_tunnel_resp {
uint8_t rsv;
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
+struct sxe2_drv_sfp_req {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t bus_addr;
@@ -642,14 +640,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
uint16_t data_len;
uint16_t rvd;
uint8_t data[];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_resp {
+struct sxe2_drv_sfp_resp {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t data_len;
uint8_t data[];
-} __rte_packed_end;
+};
enum sxe2_fc_type {
SXE2_FC_T_DIS = 0,
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (11 preceding siblings ...)
2026-08-14 12:22 ` [PATCH v1 12/13] net/sxe2: clean up structure definitions liujie5
@ 2026-08-14 12:22 ` liujie5
2026-08-14 18:44 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
13 siblings, 0 replies; 15+ messages in thread
From: liujie5 @ 2026-08-14 12:22 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This commit adds documentation for the acl-stat-type parameter
which controls ACL statistics type used for ACL rule hit counting.
- 1: Only count the number of packets
- 2: Only count the number of bytes
- 3: Count both packets and bytes (default)
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 33 ++++++++++-----------------------
1 file changed, 10 insertions(+), 23 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index 8278a5f108..008d944391 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -98,29 +98,16 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
-- ``drv-sw-stats`` parameter [int]
-
- This parameter controls whether per-packet software statistics (SW stats)
- are collected in the Rx data path.
-
- Hardware packet statistic counters may be inaccurate for certain packet types
- due to hardware design limitations.
- When accuracy of Rx packet classification statistics is critical,
- enabling this parameter allows the driver to accumulate statistics in software
- as packets are received, providing an alternative statistical path
- that bypasses hardware counter inaccuracies.
-
- - 0: Disable software statistics collection (default).
- The basic port statistics (``ipackets``, ``ibytes``) are reported
- from the hardware counters.
- - 1: Enable software statistics collection.
- Per-packet software statistics are accumulated for unicast,
- multicast, broadcast, and dropped packets in the Rx data path.
-
- When enabled, the following extended statistics (xstats) are available:
- ``rx_sw_unicast_packets``, ``rx_sw_multicast_packets``,
- ``rx_sw_broadcast_packets``, ``rx_sw_drop_packets``,
- and ``rx_sw_drop_bytes``.
+- ``acl-stat-type`` parameter [int]
+
+ This parameter controls the ACL statistics type
+ used for ACL rule hit counting (via ``rte_flow_query``).
+
+ - 1: Only count the number of packets.
+ - 2: Only count the number of bytes.
+ - 3: Count both packets and bytes (default).
+
+ Default value is 3 (count both packets and bytes).
- ``no-sched-mode`` parameter [int]
--
2.52.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v1 00/13] net/sxe2: fix bugs
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (12 preceding siblings ...)
2026-08-14 12:22 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
@ 2026-08-14 18:44 ` Stephen Hemminger
13 siblings, 0 replies; 15+ messages in thread
From: Stephen Hemminger @ 2026-08-14 18:44 UTC (permalink / raw)
To: liujie5; +Cc: dev
On Fri, 14 Aug 2026 20:21:51 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> Jie Liu (13):
> net/sxe2: add Rx queue buffer split fill support
> net/sxe2: update switchdev repr VSI ID display format
> net/sxe2: add ACL engine event statistics support
> net/sxe2: enhance device cap and res management
> net/sxe2: improve representor device initialization
> net/sxe2: refactor flow tunnel port handling
> net/sxe2: validate IPsec key length against maximum limit
> net/sxe2: enhance repre event handling and MP code
> net/sxe2: optimize vectorized Tx/Rx path
> common/sxe2: allow munmap during kernel reset
> net/sxe2: clean up duplicate function declarations
> net/sxe2: clean up structure definitions
> doc/sxe2: add acl-stat-type parameter documentation
>
> doc/guides/nics/sxe2.rst | 33 +--
> drivers/common/sxe2/sxe2_common.c | 5 +-
> drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-
> drivers/net/sxe2/sxe2_cmd_chnl.c | 215 +++++++++++++++--
> drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
> drivers/net/sxe2/sxe2_drv_cmd.h | 47 ++--
> drivers/net/sxe2/sxe2_dump.c | 10 +-
> drivers/net/sxe2/sxe2_ethdev.c | 203 +++++++++-------
> drivers/net/sxe2/sxe2_ethdev.h | 38 +--
> drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +-
> drivers/net/sxe2/sxe2_flow.c | 259 +++++++++++++++++----
> drivers/net/sxe2/sxe2_flow.h | 6 +-
> drivers/net/sxe2/sxe2_flow_define.h | 13 +-
> drivers/net/sxe2/sxe2_flow_parse_action.c | 37 ++-
> drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------
> drivers/net/sxe2/sxe2_flow_parse_pattern.h | 7 -
> drivers/net/sxe2/sxe2_ipsec.c | 5 +
> drivers/net/sxe2/sxe2_irq.c | 27 ++-
> drivers/net/sxe2/sxe2_mac.c | 10 +-
> drivers/net/sxe2/sxe2_mp.c | 65 +++---
> drivers/net/sxe2/sxe2_mp.h | 3 +-
> drivers/net/sxe2/sxe2_queue.c | 2 +
> drivers/net/sxe2/sxe2_queue.h | 7 +-
> drivers/net/sxe2/sxe2_rx.c | 5 +-
> drivers/net/sxe2/sxe2_security.c | 1 +
> drivers/net/sxe2/sxe2_stats.c | 10 +-
> drivers/net/sxe2/sxe2_switchdev.c | 12 +-
> drivers/net/sxe2/sxe2_tx.c | 42 +++-
> drivers/net/sxe2/sxe2_tx.h | 4 +
> drivers/net/sxe2/sxe2_txrx.c | 19 +-
> drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
> drivers/net/sxe2/sxe2_txrx_vec.c | 77 +++---
> drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
> drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
> drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 123 +---------
> drivers/net/sxe2/sxe2_txrx_vec_common.h | 5 +-
> drivers/net/sxe2/sxe2_txrx_vec_neon.c | 215 +++++++++++------
> drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
> drivers/net/sxe2/sxe2_vsi.c | 8 +-
> 39 files changed, 993 insertions(+), 692 deletions(-)
>
Claude Opus 5 AI review found lots of things to address.
It stopped after the first 5.
Overall: the series is titled as bug fixes but most patches mix feature
work, renames, log-message rewording, and unrelated fixes into single
commits. Several of the real bug fixes are buried in patches whose
subject describes something else, and none carry Fixes:/Cc: stable.
Please split these out.
Patch 3/13 (net/sxe2: add ACL engine event statistics support)
Error: stale count-manager pointer causes double free.
In sxe2_flow_rte_list_free(), mgr is declared once outside the
TAILQ_FOREACH_SAFE loop and never reset per iteration.
sxe2_flow_query_mgr() writes *mgr_ptr only on the full success
path; every error path leaves the caller's mgr untouched.
sxe2_flow_free_mgr() is then still called (it is gated on the COUNT
bit, not on ret), so on iteration N it operates on the mgr freed in
iteration N-1: TAILQ_REMOVE() on an already-removed node plus a
second rte_free().
This is reachable whenever an expanded flow has more than one
sxe2_flow entry with a COUNT action and the FW query command fails
on a later entry.
The new "user_id == 0 && mgr" guard fixes the first-iteration NULL
case but not this one. Reset the pointer per iteration:
TAILQ_FOREACH_SAFE(hw_flow, &flow->sxe2_flow_list, next, hw_flow_temp) {
mgr = NULL;
or declare mgr inside the loop body.
Error: sxe2_flow_free_mgr() frees without unlinking on unknown engine.
If flow->engine_type is neither ACL nor FNAV, neither branch runs,
cid_mgr_list stays NULL, no TAILQ_REMOVE happens -- and the function
still falls through to rte_free(mgr). That leaves a freed node on
whichever list it came from. Add an else branch that logs and skips
the free, or return early.
Warning: sxe2_flow_query_mgr() returns 0 for an unrecognized engine
type without setting *mgr_ptr. Callers treat 0 as "mgr is valid":
sxe2_flow_query_count() does count->hits = mgr->hits with mgr still
NULL. The COUNT action is currently rejected for non-FNAV/ACL
engines in sxe2_flow_parse_action(), so this is not reachable today,
but the contract is wrong. Return -ENOTSUP on that path.
Info: the trailing else in sxe2_flow_query_mgr()
} else {
PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
ret = -ENOTSUP;
}
is dead -- the if/else-if/else at the top of the function already
goto l_end for anything that is not ACL or FNAV.
Warning: unrelated fix in this patch.
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
A VF PCI device ID correction has nothing to do with ACL statistics.
Separate patch, with Fixes: and Cc: stable@dpdk.org.
Warning: the rxq->fnav_enable assignment added to sxe2_queues_init()
is also unrelated to this patch's subject.
Warning: the acl-stat-type devarg is added here but documented in
patch 13/13. Code and documentation must land in the same commit.
Info: struct sxe2_flow_cid_mgr.stat_index is uint16_t, but
sxe2_drv_flow_acl_get_stat_id() returns uint32_t and
sxe2_drv_acl_query_stat_req.stat_id is __le32. The assignment
mgr->stat_index = stat_index truncates. Pre-existing on the fnav
side, but the new ACL path inherits it.
Patch 4/13 (net/sxe2: enhance device cap and res management)
Error: error-unwind regression in sxe2_dev_init().
Before this patch:
init_flow_err:
init_rss_err:
sxe2_security_uinit(dev);
init_security_err:
After:
init_flow_err:
sxe2_security_uinit(dev);
init_rss_err:
init_security_err:
sxe2_intr_uninit(dev);
sxe2_rss_disable() runs after sxe2_security_init() succeeded, so a
failure there now jumps past sxe2_security_uinit() and leaks the
security context. Move init_rss_err back above the security_uinit
call.
Error: buffer-split ptype count includes the sentinel.
sxe2_buffer_split_supported_hdr_ptypes_get() now sets
*no_of_elements = RTE_DIM(ptypes), but the array still ends with a
RTE_PTYPE_UNKNOWN terminator left over from the sentinel-based
convention. rte_eth_buffer_split_get_supported_hdr_ptypes() copies
all no_of_elements entries verbatim, so callers get a bogus
RTE_PTYPE_UNKNOWN entry and an inflated count. Compare ice, whose
array has no terminator. Drop the RTE_PTYPE_UNKNOWN element.
Warning: sxe2_dev_close() cleanup fixes are unlabelled.
This patch removes a duplicate sxe2_switchdev_uninit() and a
duplicate sxe2_dev_pci_map_uinit() from sxe2_dev_close(). Those are
double-free fixes and belong in their own patch with Fixes: and
Cc: stable@dpdk.org, not inside a "cap and res management" commit.
Info: dev_info->nb_rx_queues / nb_tx_queues are dead stores.
rte_eth_dev_info_get() overwrites both from dev->data after the PMD
op returns (lib/ethdev/rte_ethdev.c). Drop them.
Info: sxe2_dev_infos_get() returns -EINVAL directly on the new NULL
vsi check while the rest of the file uses goto l_end. Minor
inconsistency.
Info: after the new res_type bounds check in sxe2_dev_pci_res_seg_map(),
the following "if (!addr_info || ...)" test is redundant --
addr_info is &array[res_type] and can never be NULL.
Info: in sxe2_switchdev_repr_match(), port_idx is initialized to
UINT16_MAX and then unconditionally overwritten by the for loop.
Patch 1/13 (net/sxe2: add Rx queue buffer split fill support)
Warning: the subject describes buffer split, but the patch also drops
a debug log from __sxe2_drv_cmd_params_fill(), adds a
sxe2_link_update() call to sxe2_drv_mac_link_status_get(), fixes an
error path in sxe2_drv_udp_tunnel_get(), and rewords a dozen log
messages. The udp_tunnel_get change is a real fix (the function
previously copied response fields after a failed command); it wants
its own patch with a Fixes: tag.
Info: sxe2_rxq_buf_split_fill() re-tests
rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT, which the caller
has already tested, so the else branch clearing hdr_len /
split_type_mask is unreachable. Either drop the check in the helper
or drop it in the caller.
Patch 5/13 (net/sxe2: improve representor device initialization)
The added sxe2_stats_init() call and its l_init_irq_ctxt_err label
unwind correctly. No findings.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-08-14 18:44 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 12:21 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
2026-08-14 12:21 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
2026-08-14 12:21 ` [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format liujie5
2026-08-14 12:21 ` [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support liujie5
2026-08-14 12:21 ` [PATCH v1 04/13] net/sxe2: enhance device cap and res management liujie5
2026-08-14 12:21 ` [PATCH v1 05/13] net/sxe2: improve representor device initialization liujie5
2026-08-14 12:21 ` [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling liujie5
2026-08-14 12:21 ` [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit liujie5
2026-08-14 12:21 ` [PATCH v1 08/13] net/sxe2: enhance repre event handling and MP code liujie5
2026-08-14 12:22 ` [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path liujie5
2026-08-14 12:22 ` [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset liujie5
2026-08-14 12:22 ` [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations liujie5
2026-08-14 12:22 ` [PATCH v1 12/13] net/sxe2: clean up structure definitions liujie5
2026-08-14 12:22 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
2026-08-14 18:44 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox