Partial offload was not working if the NIC did not support the tunnel
restoration API and OVS was compiled with ALLOW_EXPERIMENTAL_API.
This is fixed by returning success instead of EOPNOTSUPP when the
tunnel restoration API is not supported.
In addition to avoid a performance penalty, cache the tunnel restore
API support state per port and skip calling into the DPDK API on
subsequent packets when unsupported.
Fixes: 7bd1867b6d6a ("dpif-offload-dpdk: Abstract rte_flow implementation from
dpif-netdev.")
Reported-by: Ilya Maximets <[email protected]>
Signed-off-by: Eelco Chaudron <[email protected]>
---
lib/dpif-offload-dpdk-netdev.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/lib/dpif-offload-dpdk-netdev.c b/lib/dpif-offload-dpdk-netdev.c
index efe99065e..aa27d22c8 100644
--- a/lib/dpif-offload-dpdk-netdev.c
+++ b/lib/dpif-offload-dpdk-netdev.c
@@ -91,6 +91,7 @@ struct dpdk_offload_netdev_data {
struct cmap mark_to_rte_flow;
uint64_t *rte_flow_counters;
struct ovs_mutex map_lock;
+ atomic_bool tunnel_restore_api_supported;
};
static struct pmd_data *
@@ -243,6 +244,7 @@ offload_data_init(struct netdev *netdev, unsigned int
offload_thread_count)
ovs_mutex_init(&data->map_lock);
cmap_init(&data->ufid_to_rte_flow);
cmap_init(&data->mark_to_rte_flow);
+ atomic_init(&data->tunnel_restore_api_supported, true);
data->rte_flow_counters = xcalloc(offload_thread_count,
sizeof *data->rte_flow_counters);
@@ -3001,6 +3003,8 @@ dpdk_netdev_hw_miss_packet_recover(struct dpdk_offload
*offload,
{
struct pmd_id_to_flow_ref_data *pmd_data = NULL;
struct rte_flow_restore_info rte_restore_info;
+ struct dpdk_offload_netdev_data *netdev_data;
+ bool tunnel_restore_api_supported;
struct rte_flow_tunnel *rte_tnl;
struct netdev *vport_netdev;
struct pkt_metadata *md;
@@ -3023,11 +3027,24 @@ dpdk_netdev_hw_miss_packet_recover(struct dpdk_offload
*offload,
*flow_reference = NULL;
}
+ netdev_data = ovsrcu_get(void *, &netdev->hw_info.offload_data);
+ if (!netdev_data) {
+ return 0;
+ }
+
+ atomic_read_relaxed(&netdev_data->tunnel_restore_api_supported,
+ &tunnel_restore_api_supported);
+ if (!tunnel_restore_api_supported) {
+ return 0;
+ }
+
ret = netdev_dpdk_rte_flow_get_restore_info(netdev, packet,
&rte_restore_info, NULL);
if (ret) {
- if (ret == -EOPNOTSUPP) {
- return -ret;
+ if (ret == -ENOTSUP) {
+ /* Tunnel restore API not supported, avoid subsequent calls. */
+ atomic_store_relaxed(&netdev_data->tunnel_restore_api_supported,
+ false);
}
/* This function is called for every packet, and in most cases there
* will be no restore info from the HW, thus error is expected.
--
2.54.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev