Start using the new dpif-offload API by avoiding direct calls to netdev-offload. This is the first step towards removing netdev-offload as an API layer.
Signed-off-by: Eelco Chaudron <[email protected]> --- v2 changes: - Added missing newline at end of netdev-offload-tc.h. - Fixed some indentation issues. --- lib/automake.mk | 4 +++- lib/dpif-netdev.c | 2 +- lib/dpif-netlink.c | 5 ---- lib/dpif-offload-dpdk.c | 9 ++++++++ lib/dpif-offload-provider.h | 13 +++++++++++ lib/dpif-offload-tc.c | 43 +++++++++++++++++++++++++++++++++++ lib/dpif-offload.c | 36 +++++++++++++++++++++++++++++ lib/dpif-offload.h | 5 ++++ lib/dpif.c | 1 + lib/netdev-offload-dpdk.c | 4 ++-- lib/netdev-offload-dpdk.h | 27 ++++++++++++++++++++++ lib/netdev-offload-provider.h | 3 --- lib/netdev-offload-tc.c | 6 ++--- lib/netdev-offload-tc.h | 27 ++++++++++++++++++++++ lib/netdev-offload.c | 25 -------------------- lib/netdev-offload.h | 2 -- 16 files changed, 170 insertions(+), 42 deletions(-) create mode 100644 lib/netdev-offload-dpdk.h create mode 100644 lib/netdev-offload-tc.h diff --git a/lib/automake.mk b/lib/automake.mk index 6db7daa9f..229064716 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -481,6 +481,7 @@ lib_libopenvswitch_la_SOURCES += \ lib/netdev-linux.h \ lib/netdev-linux-private.h \ lib/netdev-offload-tc.c \ + lib/netdev-offload-tc.h \ lib/netlink-conntrack.c \ lib/netlink-conntrack.h \ lib/netlink-notifier.c \ @@ -509,7 +510,8 @@ lib_libopenvswitch_la_SOURCES += \ lib/dpdk.c \ lib/dpif-offload-dpdk.c \ lib/netdev-dpdk.c \ - lib/netdev-offload-dpdk.c + lib/netdev-offload-dpdk.c \ + lib/netdev-offload-dpdk.h else lib_libopenvswitch_la_SOURCES += \ lib/dpdk-stub.c diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2e31041ef..79b05bc0d 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2911,7 +2911,7 @@ dp_offload_flush(struct dp_offload_thread_item *item) struct dp_offload_flush_item *flush = &item->data->flush; ovs_rwlock_rdlock(&item->dp->port_rwlock); - netdev_flow_flush(flush->netdev); + dpif_offload_netdev_flush_flows(flush->netdev); ovs_rwlock_unlock(&item->dp->port_rwlock); ovs_barrier_block(flush->barrier); diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index e7e55bc05..6241ba8f7 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -1309,7 +1309,6 @@ dpif_netlink_port_get_pid(const struct dpif *dpif_, odp_port_t port_no) static int dpif_netlink_flow_flush(struct dpif *dpif_) { - const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif_)); const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); struct dpif_netlink_flow flow; @@ -1317,10 +1316,6 @@ dpif_netlink_flow_flush(struct dpif *dpif_) flow.cmd = OVS_FLOW_CMD_DEL; flow.dp_ifindex = dpif->dp_ifindex; - if (dpif_offload_is_offload_enabled()) { - netdev_ports_flow_flush(dpif_type_str); - } - return dpif_netlink_flow_transact(&flow, NULL, NULL); } diff --git a/lib/dpif-offload-dpdk.c b/lib/dpif-offload-dpdk.c index 1f097bfc9..f231a1c68 100644 --- a/lib/dpif-offload-dpdk.c +++ b/lib/dpif-offload-dpdk.c @@ -19,6 +19,7 @@ #include "dpif-offload.h" #include "dpif-offload-provider.h" +#include "netdev-offload-dpdk.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "util.h" @@ -252,6 +253,13 @@ dpif_offload_dpdk_can_offload(struct dpif_offload *offload OVS_UNUSED, return netdev_dpdk_flow_api_supported(netdev, true); } +static int +dpif_offload_dpdk_netdev_flow_flush(const struct dpif_offload *offload + OVS_UNUSED, struct netdev *netdev) +{ + return netdev_offload_dpdk_flow_flush(netdev); +} + struct dpif_offload_class dpif_offload_dpdk_class = { .type = "dpdk", .supported_dpif_types = (const char *const[]) { @@ -264,6 +272,7 @@ struct dpif_offload_class dpif_offload_dpdk_class = { .can_offload = dpif_offload_dpdk_can_offload, .port_add = dpif_offload_dpdk_port_add, .port_del = dpif_offload_dpdk_port_del, + .netdev_flow_flush = dpif_offload_dpdk_netdev_flow_flush, }; /* XXX: Temporary functions below, which will be removed once fully diff --git a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h index 50f9a53c2..4439e9f71 100644 --- a/lib/dpif-offload-provider.h +++ b/lib/dpif-offload-provider.h @@ -126,6 +126,19 @@ struct dpif_offload_class { * as above in 'port_deleted' applies here.*/ void (*port_set_config)(struct dpif_offload *, odp_port_t port_no, const struct smap *cfg); + + /* Deletes all offloaded flows for this offload_provider. Return 0 if + * successful, otherwise returns a positive errno value. */ + int (*flow_flush)(const struct dpif_offload *); + + + /* These APIs operate directly on the provided netdev for performance + * reasons. They are intended for use in fast path processing and should + * be designed with speed and efficiency in mind. */ + + /* Deletes all offloaded flows on this netdev. Return 0 if successful, + * otherwise returns a positive errno value. */ + int (*netdev_flow_flush)(const struct dpif_offload *, struct netdev *); }; diff --git a/lib/dpif-offload-tc.c b/lib/dpif-offload-tc.c index 66d52851a..63ce789c6 100644 --- a/lib/dpif-offload-tc.c +++ b/lib/dpif-offload-tc.c @@ -19,6 +19,7 @@ #include "dpif-offload.h" #include "dpif-offload-provider.h" +#include "netdev-offload-tc.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "util.h" @@ -236,6 +237,46 @@ dpif_offload_tc_can_offload(struct dpif_offload *dpif_offload OVS_UNUSED, return true; } +static int +dpif_offload_tc_netdev_flow_flush_(struct netdev *netdev) +{ + return netdev_offload_tc_flow_flush(netdev); +} + +static int +dpif_offload_tc_netdev_flow_flush(const struct dpif_offload *offload + OVS_UNUSED, struct netdev *netdev) +{ + return dpif_offload_tc_netdev_flow_flush_(netdev); +} + +static bool +dpif_offload_tc_flow_flush_cb(struct dpif_offload_port_mgr_port *port, + void *aux) +{ + int *err_ptr = aux; + int err; + + err = dpif_offload_tc_netdev_flow_flush_(port->netdev); + if (err && *err_ptr == 0) { + *err_ptr = err; + } + + return false; +} + +static int +dpif_offload_tc_flow_flush(const struct dpif_offload *offload) +{ + struct dpif_offload_tc *offload_tc = dpif_offload_tc_cast(offload); + int err = 0; + + dpif_offload_port_mgr_traverse_ports( + offload_tc->port_mgr, dpif_offload_tc_flow_flush_cb, &err); + + return err; +} + struct dpif_offload_class dpif_offload_tc_class = { .type = "tc", .supported_dpif_types = (const char *const[]) { @@ -248,4 +289,6 @@ struct dpif_offload_class dpif_offload_tc_class = { .can_offload = dpif_offload_tc_can_offload, .port_add = dpif_offload_tc_port_add, .port_del = dpif_offload_tc_port_del, + .flow_flush = dpif_offload_tc_flow_flush, + .netdev_flow_flush = dpif_offload_tc_netdev_flow_flush, }; diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c index bfaa953b5..5f2be95ee 100644 --- a/lib/dpif-offload.c +++ b/lib/dpif-offload.c @@ -713,6 +713,42 @@ dpif_offload_set_global_cfg(const struct ovsrec_open_vswitch *cfg) } } +void +dpif_offload_flow_flush(struct dpif *dpif) +{ + struct dp_offload *dp_offload = dpif_offload_get_dp_offload(dpif); + const struct dpif_offload *offload; + + if (!dp_offload) { + return; + } + + LIST_FOR_EACH (offload, dpif_list_node, &dp_offload->offload_providers) { + if (offload->class->flow_flush) { + int err = offload->class->flow_flush(offload); + if (err) { + VLOG_ERR("Failed flow flush on dpif-offload provider " + "%s, error %s", dpif_offload_name(offload), + ovs_strerror(err)); + } + } + } +} + + +int +dpif_offload_netdev_flush_flows(struct netdev *netdev) +{ + const struct dpif_offload *offload; + + offload = ovsrcu_get(const struct dpif_offload *, &netdev->dpif_offload); + + if (offload && offload->class->netdev_flow_flush) { + return offload->class->netdev_flow_flush(offload, netdev); + } + return EOPNOTSUPP; +} + struct dpif_offload_port_mgr * dpif_offload_port_mgr_init(void) diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h index 5b6c3038e..2d8778f7b 100644 --- a/lib/dpif-offload.h +++ b/lib/dpif-offload.h @@ -46,6 +46,7 @@ const char *dpif_offload_name(const struct dpif_offload *); const char *dpif_offload_class_type(const struct dpif_offload *); bool dpif_offload_get_debug(const struct dpif_offload *, struct ds *, struct json *); +void dpif_offload_flow_flush(struct dpif *); void dpif_offload_dump_start(struct dpif_offload_dump *, const struct dpif *); bool dpif_offload_dump_next(struct dpif_offload_dump *, struct dpif_offload **); @@ -64,4 +65,8 @@ int dpif_offload_dump_done(struct dpif_offload_dump *); : (dpif_offload_dump_done(DUMP), false)); \ ) + +/* Netdev specific function, which can be used in the fast path. */ +int dpif_offload_netdev_flush_flows(struct netdev *); + #endif /* DPIF_OFFLOAD_H */ diff --git a/lib/dpif.c b/lib/dpif.c index fb889322a..4e6f13255 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -958,6 +958,7 @@ dpif_flow_flush(struct dpif *dpif) error = dpif->dpif_class->flow_flush(dpif); log_operation(dpif, "flow_flush", error); + dpif_offload_flow_flush(dpif); return error; } diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index c4f97be70..072103596 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -25,6 +25,7 @@ #include "cmap.h" #include "dpif-netdev.h" +#include "netdev-offload-dpdk.h" #include "netdev-offload-provider.h" #include "netdev-provider.h" #include "netdev-vport.h" @@ -2609,7 +2610,7 @@ flush_in_vport_cb(struct netdev *vport, return false; } -static int +int netdev_offload_dpdk_flow_flush(struct netdev *netdev) { flush_netdev_flows_in_related(netdev, netdev); @@ -2802,7 +2803,6 @@ const struct netdev_flow_api netdev_offload_dpdk = { .init_flow_api = netdev_offload_dpdk_init_flow_api, .uninit_flow_api = netdev_offload_dpdk_uninit_flow_api, .flow_get = netdev_offload_dpdk_flow_get, - .flow_flush = netdev_offload_dpdk_flow_flush, .hw_miss_packet_recover = netdev_offload_dpdk_hw_miss_packet_recover, .flow_get_n_flows = netdev_offload_dpdk_get_n_flows, }; diff --git a/lib/netdev-offload-dpdk.h b/lib/netdev-offload-dpdk.h new file mode 100644 index 000000000..feded432f --- /dev/null +++ b/lib/netdev-offload-dpdk.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef NETDEV_OFFLOAD_DPDK_H + #define NETDEV_OFFLOAD_DPDK_H + +/* Forward declarations of private structures. */ +struct netdev; + +/* Netdev-specific offload functions. These should only be used by the + * associated dpif offload provider. */ +int netdev_offload_dpdk_flow_flush(struct netdev *); + +#endif /* NETDEV_OFFLOAD_DPDK_H */ diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index 9108856d1..6e36ed4c8 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -30,9 +30,6 @@ extern "C" { struct netdev_flow_api { char *type; - /* Flush all offloaded flows from a netdev. - * Return 0 if successful, otherwise returns a positive errno value. */ - int (*flow_flush)(struct netdev *); /* Flow dumping interface. * diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 9491dc90e..1c554416c 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -32,6 +32,7 @@ #include "openvswitch/vlog.h" #include "netdev-linux.h" #include "netdev-offload-provider.h" +#include "netdev-offload-tc.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "netlink.h" @@ -562,8 +563,8 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id) return error; } -static int -netdev_tc_flow_flush(struct netdev *netdev) +int +netdev_offload_tc_flow_flush(struct netdev *netdev) { struct ufid_tc_data *data; int err; @@ -3426,7 +3427,6 @@ meter_tc_del_policer(ofproto_meter_id meter_id, const struct netdev_flow_api netdev_offload_tc = { .type = "linux_tc", - .flow_flush = netdev_tc_flow_flush, .flow_dump_create = netdev_tc_flow_dump_create, .flow_dump_destroy = netdev_tc_flow_dump_destroy, .flow_dump_next = netdev_tc_flow_dump_next, diff --git a/lib/netdev-offload-tc.h b/lib/netdev-offload-tc.h new file mode 100644 index 000000000..964559728 --- /dev/null +++ b/lib/netdev-offload-tc.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETDEV_OFFLOAD_TC_H +#define NETDEV_OFFLOAD_TC_H + +/* Forward declarations of private structures. */ +struct netdev; + +/* Netdev-specific offload functions. These should only be used by the + * associated dpif offload provider. */ +int netdev_offload_tc_flow_flush(struct netdev *); + +#endif /* NETDEV_OFFLOAD_TC_H */ diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index 0fad1b983..2b1c99fb6 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -262,17 +262,6 @@ meter_offload_del(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats) return 0; } -int -netdev_flow_flush(struct netdev *netdev) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); - - return (flow_api && flow_api->flow_flush) - ? flow_api->flow_flush(netdev) - : EOPNOTSUPP; -} - int netdev_flow_dump_create(struct netdev *netdev, struct netdev_flow_dump **dump, bool terse) @@ -591,20 +580,6 @@ netdev_offload_thread_init(void) } } -void -netdev_ports_flow_flush(const char *dpif_type) -{ - struct port_to_netdev_data *data; - - ovs_rwlock_rdlock(&port_to_netdev_rwlock); - HMAP_FOR_EACH (data, portno_node, &port_to_netdev) { - if (netdev_get_dpif_type(data->netdev) == dpif_type) { - netdev_flow_flush(data->netdev); - } - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); -} - void netdev_ports_traverse(const char *dpif_type, bool (*cb)(struct netdev *, odp_port_t, void *), diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 5a18727eb..0bee005fd 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -100,7 +100,6 @@ netdev_offload_thread_id(void) return id; } -int netdev_flow_flush(struct netdev *); int netdev_flow_dump_create(struct netdev *, struct netdev_flow_dump **dump, bool terse); int netdev_flow_dump_destroy(struct netdev_flow_dump *); @@ -144,7 +143,6 @@ struct netdev_flow_dump **netdev_ports_flow_dump_create( const char *dpif_type, int *ports, bool terse); -void netdev_ports_flow_flush(const char *dpif_type); int netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid, struct dpif_flow_stats *stats); int netdev_ports_flow_get(const char *dpif_type, struct match *match, -- 2.50.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
