Recover the packet if it was partially processed by the HW. Fallback to lookup flow by mark association.
Signed-off-by: Eli Britstein <el...@nvidia.com> Reviewed-by: Gaetan Rivet <gaet...@nvidia.com> Acked-by: Sriharsha Basavapatna <sriharsha.basavapa...@broadcom.com> Tested-by: Emma Finn <emma.f...@intel.com> Tested-by: Marko Kovacevic <marko.kovace...@intel.com> Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> --- lib/dpif-netdev.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 8fa7eb6d4..d5b7d5b73 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -114,6 +114,7 @@ COVERAGE_DEFINE(datapath_drop_invalid_port); COVERAGE_DEFINE(datapath_drop_invalid_bond); COVERAGE_DEFINE(datapath_drop_invalid_tnl_port); COVERAGE_DEFINE(datapath_drop_rx_invalid_packet); +COVERAGE_DEFINE(datapath_drop_hw_miss_recover); /* Protects against changes to 'dp_netdevs'. */ static struct ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER; @@ -7062,6 +7063,39 @@ smc_lookup_batch(struct dp_netdev_pmd_thread *pmd, pmd_perf_update_counter(&pmd->perf_stats, PMD_STAT_SMC_HIT, n_smc_hit); } +static struct tx_port * pmd_send_port_cache_lookup( + const struct dp_netdev_pmd_thread *pmd, odp_port_t port_no); + +static inline int +dp_netdev_hw_flow(const struct dp_netdev_pmd_thread *pmd, + odp_port_t port_no, + struct dp_packet *packet, + struct dp_netdev_flow **flow) +{ + struct tx_port *p; + uint32_t mark; + + /* Restore the packet if HW processing was terminated before completion. */ + p = pmd_send_port_cache_lookup(pmd, port_no); + if (OVS_LIKELY(p)) { + int err = netdev_hw_miss_packet_recover(p->port->netdev, packet); + + if (err && err != EOPNOTSUPP) { + COVERAGE_INC(datapath_drop_hw_miss_recover); + return -1; + } + } + + /* If no mark, no flow to find. */ + if (!dp_packet_has_flow_mark(packet, &mark)) { + *flow = NULL; + return 0; + } + + *flow = mark_to_flow_find(pmd, mark); + return 0; +} + /* Try to process all ('cnt') the 'packets' using only the datapath flow cache * 'pmd->flow_cache'. If a flow is not found for a packet 'packets[i]', the * miniflow is copied into 'keys' and the packet pointer is moved at the @@ -7106,7 +7140,6 @@ dfc_processing(struct dp_netdev_pmd_thread *pmd, DP_PACKET_BATCH_REFILL_FOR_EACH (i, cnt, packet, packets_) { struct dp_netdev_flow *flow; - uint32_t mark; if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) { dp_packet_delete(packet); @@ -7125,9 +7158,13 @@ dfc_processing(struct dp_netdev_pmd_thread *pmd, pkt_metadata_init(&packet->md, port_no); } - if ((*recirc_depth_get() == 0) && - dp_packet_has_flow_mark(packet, &mark)) { - flow = mark_to_flow_find(pmd, mark); + if (netdev_is_flow_api_enabled() && *recirc_depth_get() == 0) { + if (OVS_UNLIKELY(dp_netdev_hw_flow(pmd, port_no, packet, &flow))) { + /* Packet restoration failed and it was dropped, do not + * continue processing. + */ + continue; + } if (OVS_LIKELY(flow)) { tcp_flags = parse_tcp_flags(packet); if (OVS_LIKELY(batch_enable)) { -- 2.28.0.2311.g225365fb51 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev