| Message ID | 45036396e49ed6d7b5022e8dd6c436d67c3f74da.1762950453.git.echaudro@redhat.com |
|---|---|
| State | Changes Requested |
| Headers | show |
| Series | Architectural refactoring of hardware offload infrastructure | expand |
| Context | Check | Description |
|---|---|---|
| ovsrobot/apply-robot | warning | apply and check: warning |
| ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
| ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
Git commit: 45036396e49ed6d7b5022e8dd6c436d67c3f74da Author: Eelco Chaudron <echaudro@redhat.com> Subject: netdev-offload: Remove the global netdev-offload API. This patch removes the global netdev_flow_api in favor of the new dpif-offload infrastructure. All offload-related handling is now performed via the dpif-offload layer, simplifying the code and removing redundant global interfaces from netdev-offload. > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index df6c94912..484eefccb 100644 > --- a/lib/dpif-netdev.c > +++ b/lib/dpif-netdev.c > @@ -2404,7 +2404,6 @@ do_del_port(struct dp_netdev *dp, struct dp_netdev_port *port) > * offload modification or deletion. Managing those stray requests > * is done in the offload threads. */ > dp_netdev_offload_flush(dp, port); > - netdev_uninit_flow_api(port->netdev); Does this removal risk leaving flow offload resources uninitialized on the netdev when a port is deleted? The original call to netdev_uninit_flow_api() appears to have cleaned up flow API state. > @@ -2813,7 +2812,7 @@ dp_netdev_flow_offload_put(struct dp_offload_thread_item *item) > odp_port_t in_port = flow->flow.in_port.odp_port; > bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD > && flow->mark != INVALID_FLOW_MARK; > - struct offload_info info; > + struct dpif_netdev_offload_info info; [ ... ] > diff --git a/lib/dpif-netdev.h b/lib/dpif-netdev.h > index 6db6ed2e2..5df344367 100644 > --- a/lib/dpif-netdev.h > +++ b/lib/dpif-netdev.h > @@ -38,6 +38,18 @@ bool dpif_is_netdev(const struct dpif *); > #define NR_QUEUE 1 > #define NR_PMD_THREADS 1 > > +/* Flow offloading info structure. XXX: This needs to be moved once the > + * implementation is migrated to dpif-offload-dpdk. */ > +struct dpif_netdev_offload_info { > + /* > + * The flow mark id assigned to the flow. If any pkts hit the flow, > + * it will be in the pkt meta data. > + */ > + uint32_t flow_mark; > + > + odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ > +}; [ ... ] > diff --git a/lib/dpif.c b/lib/dpif.c > index 323a2bf6c..006d9276e 100644 > --- a/lib/dpif.c > +++ b/lib/dpif.c > @@ -378,7 +378,6 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp) > > if (!err) { > netdev_set_dpif_type(netdev, dpif_type_str); > - netdev_ports_insert(netdev, &dpif_port); Does removing this netdev_ports_insert() call break the global port tracking that other parts of the code might depend on? The function appeared to maintain port-to-netdev mappings. > @@ -443,19 +442,6 @@ dpif_create_and_open(const char *name, const char *type, struct dpif **dpifp) > return error; > } > > -static void > -dpif_remove_netdev_ports(struct dpif *dpif) { > - const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); > - struct dpif_port_dump port_dump; > - struct dpif_port dpif_port; > - > - DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) { > - if (!dpif_is_tap_port(dpif_port.type)) { > - netdev_ports_remove(dpif_port.port_no, dpif_type_str); > - } > - } > -} [ ... ] > @@ -626,17 +609,9 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop) > dpif_name(dpif), netdev_name, port_no); > > if (!dpif_is_tap_port(netdev_get_type(netdev))) { > - > const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); > > netdev_set_dpif_type(netdev, dpif_type_str); > - > - dpif_port.type = CONST_CAST(char *, netdev_get_type(netdev)); > - dpif_port.name = CONST_CAST(char *, netdev_name); > - dpif_port.port_no = port_no; > - netdev_ports_insert(netdev, &dpif_port); Does removing this netdev_ports_insert() call in dpif_port_add() leave the newly added port untracked in global mappings? This could affect functions that look up netdevs by port number. > @@ -645,8 +645,6 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no, bool local_delete) > } > > dpif_offload_port_del(dpif, port_no); > - > - netdev_ports_remove(port_no, dpif_normalize_type(dpif_type(dpif))); [ ... ] > diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c > index fff49240d..f24c415a2 100644 > --- a/lib/netdev-offload.c > +++ b/lib/netdev-offload.c > @@ -16,248 +16,13 @@ > */ > > #include <config.h> > -#include "netdev-offload.h" [ ... ] Does this massive removal of the port tracking infrastructure (netdev_ports_insert, netdev_ports_remove, netdev_ports_get, etc.) break any code that relied on the global port-to-netdev mappings maintained in port_to_netdev and ifindex_to_port hashmaps? Functions like netdev_ifindex_to_odp_port() appear to be completely removed.
On 12 Nov 2025, at 16:35, Eelco Chaudron via dev wrote: > This patch removes the global netdev_flow_api in favor of the new > dpif-offload infrastructure. All offload-related handling is now > performed via the dpif-offload layer, simplifying the code and > removing redundant global interfaces from netdev-offload. > > Signed-off-by: Eelco Chaudron <echaudro@redhat.com> Oops, I forgot to include a patch modification before sending it out :( I added the diff inline below, and will incorporate it in a v3 once more people have reviewed the series. //Eelco > --- > lib/automake.mk | 1 - > lib/dpif-netdev.c | 3 +- > lib/dpif-netdev.h | 12 + > lib/dpif.c | 27 -- > lib/netdev-dummy.c | 1 - > lib/netdev-offload-dpdk.c | 5 +- > lib/netdev-offload-dpdk.h | 7 +- > lib/netdev-offload-provider.h | 79 ------ > lib/netdev-offload.c | 457 +--------------------------------- > lib/netdev-offload.h | 63 ----- > lib/netdev-provider.h | 8 +- > lib/netdev.c | 4 - > ofproto/ofproto-dpif.c | 2 +- > vswitchd/bridge.c | 1 - > 14 files changed, 27 insertions(+), 643 deletions(-) > delete mode 100644 lib/netdev-offload-provider.h > > diff --git a/lib/automake.mk b/lib/automake.mk > index 229064716..f7586bb0a 100644 > --- a/lib/automake.mk > +++ b/lib/automake.mk > @@ -212,7 +212,6 @@ lib_libopenvswitch_la_SOURCES = \ > lib/netdev-dummy.c \ > lib/netdev-offload.c \ > lib/netdev-offload.h \ > - lib/netdev-offload-provider.h \ > lib/netdev-provider.h \ > lib/netdev-vport.c \ > lib/netdev-vport.h \ > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index df6c94912..484eefccb 100644 > --- a/lib/dpif-netdev.c > +++ b/lib/dpif-netdev.c > @@ -2404,7 +2404,6 @@ do_del_port(struct dp_netdev *dp, struct dp_netdev_port *port) > * offload modification or deletion. Managing those stray requests > * is done in the offload threads. */ > dp_netdev_offload_flush(dp, port); > - netdev_uninit_flow_api(port->netdev); > > port_destroy(port); > } > @@ -2813,7 +2812,7 @@ dp_netdev_flow_offload_put(struct dp_offload_thread_item *item) > odp_port_t in_port = flow->flow.in_port.odp_port; > bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD > && flow->mark != INVALID_FLOW_MARK; > - struct offload_info info; > + struct dpif_netdev_offload_info info; > struct netdev *port; > uint32_t mark; > int ret; > diff --git a/lib/dpif-netdev.h b/lib/dpif-netdev.h > index 6db6ed2e2..5df344367 100644 > --- a/lib/dpif-netdev.h > +++ b/lib/dpif-netdev.h > @@ -38,6 +38,18 @@ bool dpif_is_netdev(const struct dpif *); > #define NR_QUEUE 1 > #define NR_PMD_THREADS 1 > > +/* Flow offloading info structure. XXX: This needs to be moved once the > + * implementation is migrated to dpif-offload-dpdk. */ > +struct dpif_netdev_offload_info { > + /* > + * The flow mark id assigned to the flow. If any pkts hit the flow, > + * it will be in the pkt meta data. > + */ > + uint32_t flow_mark; > + > + odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ > +}; > + > #ifdef __cplusplus > } > #endif > diff --git a/lib/dpif.c b/lib/dpif.c > index 323a2bf6c..006d9276e 100644 > --- a/lib/dpif.c > +++ b/lib/dpif.c > @@ -378,7 +378,6 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp) > > if (!err) { > netdev_set_dpif_type(netdev, dpif_type_str); > - netdev_ports_insert(netdev, &dpif_port); > if (new_offload_provider) { > dpif_offload_port_add(dpif, netdev, dpif_port.port_no); > } > @@ -443,19 +442,6 @@ dpif_create_and_open(const char *name, const char *type, struct dpif **dpifp) > return error; > } What was missing in this patch: diff --git a/lib/dpif.c b/lib/dpif.c index 089043ad4..817cb941a 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -359,32 +359,31 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp) const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); struct dpif_port_dump port_dump; struct dpif_port dpif_port; - bool new_offload_provider; ovs_assert(dpif->dpif_class == registered_class->dpif_class); - new_offload_provider = dpif_offload_attach_providers(dpif) == EEXIST - ? false : true; + /* Only if a new provider was attached should we try to add already + * existing ports. */ + if (dpif_offload_attach_providers(dpif) == 0) { + DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) { + struct netdev *netdev; + int err; - DPIF_PORT_FOR_EACH(&dpif_port, &port_dump, dpif) { - struct netdev *netdev; - int err; - - if (dpif_is_tap_port(dpif_port.type)) { - continue; - } + if (dpif_is_tap_port(dpif_port.type)) { + continue; + } - err = netdev_open(dpif_port.name, dpif_port.type, &netdev); + err = netdev_open(dpif_port.name, dpif_port.type, &netdev); + if (err) { + VLOG_WARN("could not open netdev %s type %s: %s", + dpif_port.name, dpif_port.type, + ovs_strerror(err)); + continue; + } - if (!err) { netdev_set_dpif_type(netdev, dpif_type_str); - if (new_offload_provider) { - dpif_offload_port_add(dpif, netdev, dpif_port.port_no); - } + dpif_offload_port_add(dpif, netdev, dpif_port.port_no); netdev_close(netdev); - } else { - VLOG_WARN("could not open netdev %s type %s: %s", - dpif_port.name, dpif_port.type, ovs_strerror(err)); } } } else { > -static void > -dpif_remove_netdev_ports(struct dpif *dpif) { > - const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); > - struct dpif_port_dump port_dump; > - struct dpif_port dpif_port; > - > - DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) { > - if (!dpif_is_tap_port(dpif_port.type)) { > - netdev_ports_remove(dpif_port.port_no, dpif_type_str); > - } > - } > -} > - > /* Closes and frees the connection to 'dpif'. Does not destroy the datapath > * itself; call dpif_delete() first, instead, if that is desirable. */ > void > @@ -466,9 +452,6 @@ dpif_close(struct dpif *dpif) > > rc = shash_find_data(&dpif_classes, dpif->dpif_class->type); > > - if (rc->refcount == 1) { > - dpif_remove_netdev_ports(dpif); > - } > dpif_offload_detach_providers(dpif); > dpif_uninit(dpif, true); > dp_class_unref(rc); > @@ -626,17 +609,9 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop) > dpif_name(dpif), netdev_name, port_no); > > if (!dpif_is_tap_port(netdev_get_type(netdev))) { > - > const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); > - struct dpif_port dpif_port; > > netdev_set_dpif_type(netdev, dpif_type_str); > - > - dpif_port.type = CONST_CAST(char *, netdev_get_type(netdev)); > - dpif_port.name = CONST_CAST(char *, netdev_name); > - dpif_port.port_no = port_no; > - netdev_ports_insert(netdev, &dpif_port); > - > dpif_offload_port_add(dpif, netdev, port_no); > } > } else { > @@ -670,8 +645,6 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no, bool local_delete) > } > > dpif_offload_port_del(dpif, port_no); > - > - netdev_ports_remove(port_no, dpif_normalize_type(dpif_type(dpif))); > return error; > } > > diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c > index 8ae1151ea..6a99f4ced 100644 > --- a/lib/netdev-dummy.c > +++ b/lib/netdev-dummy.c > @@ -24,7 +24,6 @@ > #include "dp-packet.h" > #include "dpif-netdev.h" > #include "flow.h" > -#include "netdev-offload-provider.h" > #include "netdev-provider.h" > #include "netdev-vport.h" > #include "odp-util.h" > diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c > index cda5f3dbb..de10a71c4 100644 > --- a/lib/netdev-offload-dpdk.c > +++ b/lib/netdev-offload-dpdk.c > @@ -2311,7 +2311,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, > struct nlattr *nl_actions, > size_t actions_len, > const ovs_u128 *ufid, > - struct offload_info *info) > + struct dpif_netdev_offload_info *info) > { > struct flow_patterns patterns = { > .items = NULL, > @@ -2428,7 +2428,8 @@ get_netdev_odp_cb(struct netdev *netdev, > int > netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, > struct nlattr *actions, size_t actions_len, > - const ovs_u128 *ufid, struct offload_info *info, > + const ovs_u128 *ufid, > + struct dpif_netdev_offload_info *info, > struct dpif_flow_stats *stats) > { > struct ufid_to_rte_flow_data *rte_flow_data; > diff --git a/lib/netdev-offload-dpdk.h b/lib/netdev-offload-dpdk.h > index 835220974..3587a3a72 100644 > --- a/lib/netdev-offload-dpdk.h > +++ b/lib/netdev-offload-dpdk.h > @@ -19,7 +19,7 @@ > > /* Forward declarations of private structures. */ > struct netdev; > -struct offload_info; > +struct dpif_netdev_offload_info; > > /* Netdev-specific offload functions. These should only be used by the > * associated dpif offload provider. */ > @@ -32,7 +32,8 @@ int netdev_offload_dpdk_hw_miss_packet_recover(struct netdev *, > #ifdef DPDK_NETDEV > int netdev_offload_dpdk_flow_put(struct netdev *, struct match *, > struct nlattr *actions, size_t actions_len, > - const ovs_u128 *ufid, struct offload_info *, > + const ovs_u128 *ufid, > + struct dpif_netdev_offload_info *, > struct dpif_flow_stats *); > int netdev_offload_dpdk_flow_del(struct netdev *, const ovs_u128 *ufid, > struct dpif_flow_stats *); > @@ -47,7 +48,7 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev OVS_UNUSED, > struct nlattr *actions OVS_UNUSED, > size_t actions_len OVS_UNUSED, > const ovs_u128 *ufid OVS_UNUSED, > - struct offload_info *info OVS_UNUSED, > + struct dpif_netdev_offload_info *info OVS_UNUSED, > struct dpif_flow_stats *stats OVS_UNUSED) > { > return EOPNOTSUPP; > diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h > deleted file mode 100644 > index 8087b84e3..000000000 > --- a/lib/netdev-offload-provider.h > +++ /dev/null > @@ -1,79 +0,0 @@ > -/* > - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc. > - * Copyright (c) 2019 Samsung Electronics Co.,Ltd. > - * > - * 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_FLOW_API_PROVIDER_H > -#define NETDEV_FLOW_API_PROVIDER_H 1 > - > -#include "flow.h" > -#include "netdev-offload.h" > -#include "openvswitch/netdev.h" > -#include "openvswitch/types.h" > -#include "packets.h" > - > -#ifdef __cplusplus > -extern "C" { > -#endif > - > -struct netdev_flow_api { > - char *type; > - > - /* Offload the given flow on netdev. > - * To modify a flow, use the same ufid. > - * 'actions' are in netlink format, as with struct dpif_flow_put. > - * 'info' is extra info needed to offload the flow. > - * 'stats' is populated according to the rules set out in the description > - * above 'struct dpif_flow_put'. > - * Return 0 if successful, otherwise returns a positive errno value. */ > - int (*flow_put)(struct netdev *, struct match *, struct nlattr *actions, > - size_t actions_len, const ovs_u128 *ufid, > - struct offload_info *info, struct dpif_flow_stats *); > - > - /* Queries a flow specified by ufid on netdev. > - * Fills output buffer as 'wbuffer' in flow_dump_next, which > - * needs to be be pre allocated. > - * Return 0 if successful, otherwise returns a positive errno value. */ > - int (*flow_get)(struct netdev *, struct match *, struct nlattr **actions, > - const ovs_u128 *ufid, struct dpif_flow_stats *, > - struct dpif_flow_attrs *, struct ofpbuf *wbuffer); > - > - /* Delete a flow specified by ufid from netdev. > - * 'stats' is populated according to the rules set out in the description > - * above 'struct dpif_flow_del'. > - * Return 0 if successful, otherwise returns a positive errno value. */ > - int (*flow_del)(struct netdev *, const ovs_u128 *ufid, > - struct dpif_flow_stats *); > - > - /* Initializies the netdev flow api. > - * Return 0 if successful, otherwise returns a positive errno value. */ > - int (*init_flow_api)(struct netdev *); > - > - /* Uninitializes the netdev flow api. */ > - void (*uninit_flow_api)(struct netdev *); > -}; > - > -int netdev_register_flow_api_provider(const struct netdev_flow_api *); > -int netdev_unregister_flow_api_provider(const char *type); > - > -#ifdef __linux__ > -extern const struct netdev_flow_api netdev_offload_tc; > -#endif > - > -#ifdef __cplusplus > -} > -#endif > - > -#endif /* NETDEV_FLOW_API_PROVIDER_H */ > diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c > index fff49240d..f24c415a2 100644 > --- a/lib/netdev-offload.c > +++ b/lib/netdev-offload.c > @@ -16,248 +16,13 @@ > */ > > #include <config.h> > -#include "netdev-offload.h" > - > -#include <errno.h> > -#include <inttypes.h> > -#include <sys/types.h> > -#include <netinet/in.h> > -#include <stdlib.h> > -#include <string.h> > -#include <unistd.h> > > -#include "cmap.h" > -#include "coverage.h" > -#include "dpif.h" > -#include "dpif-offload.h" > -#include "dp-packet.h" > -#include "openvswitch/dynamic-string.h" > -#include "fatal-signal.h" > -#include "hash.h" > -#include "openvswitch/list.h" > -#include "netdev-offload-provider.h" > +#include "netdev-offload.h" > #include "netdev-provider.h" > -#include "netdev-vport.h" > -#include "odp-netlink.h" > -#include "openflow/openflow.h" > -#include "packets.h" > -#include "openvswitch/ofp-print.h" > -#include "openvswitch/poll-loop.h" > -#include "seq.h" > -#include "openvswitch/shash.h" > -#include "smap.h" > -#include "socket-util.h" > -#include "sset.h" > -#include "svec.h" > #include "openvswitch/vlog.h" > -#include "flow.h" > -#include "util.h" > -#ifdef __linux__ > -#include "tc.h" > -#endif > > VLOG_DEFINE_THIS_MODULE(netdev_offload); > > -/* Protects 'netdev_flow_apis'. */ > -static struct ovs_mutex netdev_flow_api_provider_mutex = OVS_MUTEX_INITIALIZER; > - > -/* Contains 'struct netdev_registered_flow_api's. */ > -static struct cmap netdev_flow_apis = CMAP_INITIALIZER; > - > -struct netdev_registered_flow_api { > - struct cmap_node cmap_node; /* In 'netdev_flow_apis', by flow_api->type. */ > - const struct netdev_flow_api *flow_api; > - > - /* Number of references: one for the flow_api itself and one for every > - * instance of the netdev that uses it. */ > - struct ovs_refcount refcnt; > -}; > - > -static struct netdev_registered_flow_api * > -netdev_lookup_flow_api(const char *type) > -{ > - struct netdev_registered_flow_api *rfa; > - CMAP_FOR_EACH_WITH_HASH (rfa, cmap_node, hash_string(type, 0), > - &netdev_flow_apis) { > - if (!strcmp(type, rfa->flow_api->type)) { > - return rfa; > - } > - } > - return NULL; > -} > - > -/* Registers a new netdev flow api provider. */ > -int > -netdev_register_flow_api_provider(const struct netdev_flow_api *new_flow_api) > - OVS_EXCLUDED(netdev_flow_api_provider_mutex) > -{ > - int error = 0; > - > - if (!new_flow_api->init_flow_api) { > - VLOG_WARN("attempted to register invalid flow api provider: %s", > - new_flow_api->type); > - error = EINVAL; > - } > - > - ovs_mutex_lock(&netdev_flow_api_provider_mutex); > - if (netdev_lookup_flow_api(new_flow_api->type)) { > - VLOG_WARN("attempted to register duplicate flow api provider: %s", > - new_flow_api->type); > - error = EEXIST; > - } else { > - struct netdev_registered_flow_api *rfa; > - > - rfa = xmalloc(sizeof *rfa); > - cmap_insert(&netdev_flow_apis, &rfa->cmap_node, > - hash_string(new_flow_api->type, 0)); > - rfa->flow_api = new_flow_api; > - ovs_refcount_init(&rfa->refcnt); > - VLOG_DBG("netdev: flow API '%s' registered.", new_flow_api->type); > - } > - ovs_mutex_unlock(&netdev_flow_api_provider_mutex); > - > - return error; > -} > - > -/* Unregisters a netdev flow api provider. 'type' must have been previously > - * registered and not currently be in use by any netdevs. After unregistration > - * netdev flow api of that type cannot be used for netdevs. (However, the > - * provider may still be accessible from other threads until the next RCU grace > - * period, so the caller must not free or re-register the same netdev_flow_api > - * until that has passed.) */ > -int > -netdev_unregister_flow_api_provider(const char *type) > - OVS_EXCLUDED(netdev_flow_api_provider_mutex) > -{ > - struct netdev_registered_flow_api *rfa; > - int error; > - > - ovs_mutex_lock(&netdev_flow_api_provider_mutex); > - rfa = netdev_lookup_flow_api(type); > - if (!rfa) { > - VLOG_WARN("attempted to unregister a flow api provider that is not " > - "registered: %s", type); > - error = EAFNOSUPPORT; > - } else if (ovs_refcount_unref(&rfa->refcnt) != 1) { > - ovs_refcount_ref(&rfa->refcnt); > - VLOG_WARN("attempted to unregister in use flow api provider: %s", > - type); > - error = EBUSY; > - } else { > - cmap_remove(&netdev_flow_apis, &rfa->cmap_node, > - hash_string(rfa->flow_api->type, 0)); > - ovsrcu_postpone(free, rfa); > - error = 0; > - } > - ovs_mutex_unlock(&netdev_flow_api_provider_mutex); > - > - return error; > -} > - > -static int > -netdev_assign_flow_api(struct netdev *netdev) > -{ > - struct netdev_registered_flow_api *rfa; > - > - CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) { > - if (!rfa->flow_api->init_flow_api(netdev)) { > - ovs_refcount_ref(&rfa->refcnt); > - atomic_store_relaxed(&netdev->hw_info.postprocess_api_supported, > - true); > - ovsrcu_set(&netdev->flow_api, rfa->flow_api); > - VLOG_INFO("%s: Assigned flow API '%s'.", > - netdev_get_name(netdev), rfa->flow_api->type); > - return 0; > - } > - VLOG_DBG("%s: flow API '%s' is not suitable.", > - netdev_get_name(netdev), rfa->flow_api->type); > - } > - atomic_store_relaxed(&netdev->hw_info.postprocess_api_supported, false); > - VLOG_INFO("%s: No suitable flow API found.", netdev_get_name(netdev)); > - > - return -1; > -} > - > -int > -netdev_flow_put(struct netdev *netdev, struct match *match, > - struct nlattr *actions, size_t act_len, > - const ovs_u128 *ufid, struct offload_info *info, > - struct dpif_flow_stats *stats) > -{ > - const struct netdev_flow_api *flow_api = > - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); > - > - return (flow_api && flow_api->flow_put) > - ? flow_api->flow_put(netdev, match, actions, act_len, ufid, > - info, stats) > - : EOPNOTSUPP; > -} > - > -int > -netdev_flow_get(struct netdev *netdev, struct match *match, > - struct nlattr **actions, const ovs_u128 *ufid, > - struct dpif_flow_stats *stats, > - struct dpif_flow_attrs *attrs, struct ofpbuf *buf) > -{ > - const struct netdev_flow_api *flow_api = > - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); > - > - return (flow_api && flow_api->flow_get) > - ? flow_api->flow_get(netdev, match, actions, ufid, > - stats, attrs, buf) > - : EOPNOTSUPP; > -} > - > -int > -netdev_flow_del(struct netdev *netdev, const ovs_u128 *ufid, > - struct dpif_flow_stats *stats) > -{ > - const struct netdev_flow_api *flow_api = > - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); > - > - return (flow_api && flow_api->flow_del) > - ? flow_api->flow_del(netdev, ufid, stats) > - : EOPNOTSUPP; > -} > - > -int > -netdev_init_flow_api(struct netdev *netdev) > -{ > - if (!dpif_offload_is_offload_enabled()) { > - return EOPNOTSUPP; > - } > - > - if (ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api)) { > - return 0; > - } > - > - if (netdev_assign_flow_api(netdev)) { > - return EOPNOTSUPP; > - } > - > - return 0; > -} > - > -void > -netdev_uninit_flow_api(struct netdev *netdev) > -{ > - struct netdev_registered_flow_api *rfa; > - const struct netdev_flow_api *flow_api = > - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); > - > - if (!flow_api) { > - return; > - } > - > - if (flow_api->uninit_flow_api) { > - flow_api->uninit_flow_api(netdev); > - } > - > - ovsrcu_set(&netdev->flow_api, NULL); > - rfa = netdev_lookup_flow_api(flow_api->type); > - ovs_refcount_unref(&rfa->refcnt); > -} > - > /* > * Get the value of the hw info parameter specified by type. > * Returns the value on success (>= 0). Returns -1 on failure. > @@ -307,223 +72,3 @@ netdev_set_hw_info(struct netdev *netdev, int type, int val) > break; > } > } > - > -/* Protects below port hashmaps. */ > -static struct ovs_rwlock ifindex_to_port_rwlock = OVS_RWLOCK_INITIALIZER; > -static struct ovs_rwlock port_to_netdev_rwlock > - OVS_ACQ_BEFORE(ifindex_to_port_rwlock) = OVS_RWLOCK_INITIALIZER; > - > -static struct hmap port_to_netdev OVS_GUARDED_BY(port_to_netdev_rwlock) > - = HMAP_INITIALIZER(&port_to_netdev); > -static struct hmap ifindex_to_port OVS_GUARDED_BY(ifindex_to_port_rwlock) > - = HMAP_INITIALIZER(&ifindex_to_port); > - > -struct port_to_netdev_data { > - struct hmap_node portno_node; /* By (dpif_type, dpif_port.port_no). */ > - struct hmap_node ifindex_node; /* By (dpif_type, ifindex). */ > - struct netdev *netdev; > - struct dpif_port dpif_port; > - int ifindex; > -}; > - > -void > -netdev_ports_traverse(const char *dpif_type, > - bool (*cb)(struct netdev *, odp_port_t, void *), > - void *aux) > -{ > - 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) { > - if (cb(data->netdev, data->dpif_port.port_no, aux)) { > - break; > - } > - } > - } > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > -} > - > -int > -netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid, > - struct dpif_flow_stats *stats) > -{ > - 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_del(data->netdev, ufid, stats)) { > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - return 0; > - } > - } > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - > - return ENOENT; > -} > - > -int > -netdev_ports_flow_get(const char *dpif_type, struct match *match, > - struct nlattr **actions, const ovs_u128 *ufid, > - struct dpif_flow_stats *stats, > - struct dpif_flow_attrs *attrs, struct ofpbuf *buf) > -{ > - 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_get(data->netdev, match, actions, > - ufid, stats, attrs, buf)) { > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - return 0; > - } > - } > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - return ENOENT; > -} > - > -static uint32_t > -netdev_ports_hash(odp_port_t port, const char *dpif_type) > -{ > - return hash_int(odp_to_u32(port), hash_pointer(dpif_type, 0)); > -} > - > -static struct port_to_netdev_data * > -netdev_ports_lookup(odp_port_t port_no, const char *dpif_type) > - OVS_REQ_RDLOCK(port_to_netdev_rwlock) > -{ > - struct port_to_netdev_data *data; > - > - HMAP_FOR_EACH_WITH_HASH (data, portno_node, > - netdev_ports_hash(port_no, dpif_type), > - &port_to_netdev) { > - if (netdev_get_dpif_type(data->netdev) == dpif_type > - && data->dpif_port.port_no == port_no) { > - return data; > - } > - } > - return NULL; > -} > - > -int > -netdev_ports_insert(struct netdev *netdev, struct dpif_port *dpif_port) > -{ > - const char *dpif_type = netdev_get_dpif_type(netdev); > - struct port_to_netdev_data *data; > - int ifindex = netdev_get_ifindex(netdev); > - > - ovs_assert(dpif_type); > - > - ovs_rwlock_wrlock(&port_to_netdev_rwlock); > - if (netdev_ports_lookup(dpif_port->port_no, dpif_type)) { > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - return EEXIST; > - } > - > - data = xzalloc(sizeof *data); > - data->netdev = netdev_ref(netdev); > - dpif_port_clone(&data->dpif_port, dpif_port); > - > - if (ifindex >= 0) { > - data->ifindex = ifindex; > - ovs_rwlock_wrlock(&ifindex_to_port_rwlock); > - hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex); > - ovs_rwlock_unlock(&ifindex_to_port_rwlock); > - } else { > - data->ifindex = -1; > - } > - > - hmap_insert(&port_to_netdev, &data->portno_node, > - netdev_ports_hash(dpif_port->port_no, dpif_type)); > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - > - netdev_init_flow_api(netdev); > - > - return 0; > -} > - > -struct netdev * > -netdev_ports_get(odp_port_t port_no, const char *dpif_type) > -{ > - struct port_to_netdev_data *data; > - struct netdev *ret = NULL; > - > - ovs_rwlock_rdlock(&port_to_netdev_rwlock); > - data = netdev_ports_lookup(port_no, dpif_type); > - if (data) { > - ret = netdev_ref(data->netdev); > - } > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - > - return ret; > -} > - > -int > -netdev_ports_remove(odp_port_t port_no, const char *dpif_type) > -{ > - struct port_to_netdev_data *data; > - int ret = ENOENT; > - > - ovs_rwlock_wrlock(&port_to_netdev_rwlock); > - data = netdev_ports_lookup(port_no, dpif_type); > - if (data) { > - dpif_port_destroy(&data->dpif_port); > - netdev_close(data->netdev); /* unref and possibly close */ > - hmap_remove(&port_to_netdev, &data->portno_node); > - if (data->ifindex >= 0) { > - ovs_rwlock_wrlock(&ifindex_to_port_rwlock); > - hmap_remove(&ifindex_to_port, &data->ifindex_node); > - ovs_rwlock_unlock(&ifindex_to_port_rwlock); > - } > - free(data); > - ret = 0; > - } > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > - > - return ret; > -} > - > -odp_port_t > -netdev_ifindex_to_odp_port(int ifindex) > -{ > - struct port_to_netdev_data *data; > - odp_port_t ret = 0; > - > - ovs_rwlock_rdlock(&ifindex_to_port_rwlock); > - HMAP_FOR_EACH_WITH_HASH (data, ifindex_node, ifindex, &ifindex_to_port) { > - if (data->ifindex == ifindex) { > - ret = data->dpif_port.port_no; > - break; > - } > - } > - ovs_rwlock_unlock(&ifindex_to_port_rwlock); > - > - return ret; > -} > - > -static void > -netdev_ports_flow_init(void) > -{ > - struct port_to_netdev_data *data; > - > - ovs_rwlock_rdlock(&port_to_netdev_rwlock); > - HMAP_FOR_EACH (data, portno_node, &port_to_netdev) { > - netdev_init_flow_api(data->netdev); > - } > - ovs_rwlock_unlock(&port_to_netdev_rwlock); > -} > - > -void > -netdev_set_flow_api_enabled(const struct smap *ovs_other_config OVS_UNUSED) > -{ > - if (dpif_offload_is_offload_enabled()) { > - static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; > - > - if (ovsthread_once_start(&once)) { > - netdev_ports_flow_init(); > - ovsthread_once_done(&once); > - } > - } > -} > diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h > index b8701bad6..fe42c9b4d 100644 > --- a/lib/netdev-offload.h > +++ b/lib/netdev-offload.h > @@ -19,31 +19,13 @@ > #define NETDEV_OFFLOAD_H 1 > > #include "openvswitch/netdev.h" > -#include "openvswitch/types.h" > #include "ovs-atomic.h" > #include "ovs-rcu.h" > -#include "ovs-thread.h" > -#include "openvswitch/ofp-meter.h" > -#include "packets.h" > -#include "flow.h" > > #ifdef __cplusplus > extern "C" { > #endif > > -struct dp_packet_batch; > -struct dp_packet; > -struct netdev_class; > -struct netdev_rxq; > -struct netdev_saved_flags; > -struct ofpbuf; > -struct in_addr; > -struct in6_addr; > -struct smap; > -struct sset; > -struct ovs_action_push_tnl; > - > - > /* Offload-capable (HW) netdev information */ > struct netdev_hw_info { > bool oor; /* Out of Offload Resources ? */ > @@ -60,53 +42,8 @@ enum hw_info_type { > HW_INFO_TYPE_OFFL_COUNT = 3 /* Offloaded flow count */ > }; > > -/* Flow offloading. */ > -struct offload_info { > - /* > - * The flow mark id assigned to the flow. If any pkts hit the flow, > - * it will be in the pkt meta data. > - */ > - uint32_t flow_mark; > - > - odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ > -}; > - > -int netdev_flow_put(struct netdev *, struct match *, struct nlattr *actions, > - size_t actions_len, const ovs_u128 *, > - struct offload_info *, struct dpif_flow_stats *); > -int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions, > - const ovs_u128 *, struct dpif_flow_stats *, > - struct dpif_flow_attrs *, struct ofpbuf *wbuffer); > -int netdev_flow_del(struct netdev *, const ovs_u128 *, > - struct dpif_flow_stats *); > -int netdev_init_flow_api(struct netdev *); > -void netdev_uninit_flow_api(struct netdev *); > int netdev_get_hw_info(struct netdev *, int); > void netdev_set_hw_info(struct netdev *, int, int); > -void netdev_set_flow_api_enabled(const struct smap *ovs_other_config); > - > -struct dpif_port; > -int netdev_ports_insert(struct netdev *, struct dpif_port *); > -struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type); > -int netdev_ports_remove(odp_port_t port, const char *dpif_type); > -odp_port_t netdev_ifindex_to_odp_port(int ifindex); > - > -/* For each of the ports with dpif_type, call cb with the netdev and port > - * number of the port, and an opaque user argument. > - * The returned value is used to continue traversing upon false or stop if > - * true. > - */ > -void netdev_ports_traverse(const char *dpif_type, > - bool (*cb)(struct netdev *, odp_port_t, void *), > - void *aux); > -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, > - struct nlattr **actions, > - const ovs_u128 *ufid, > - struct dpif_flow_stats *stats, > - struct dpif_flow_attrs *attrs, > - struct ofpbuf *buf); > > #ifdef __cplusplus > } > diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h > index 87bc95180..753151330 100644 > --- a/lib/netdev-provider.h > +++ b/lib/netdev-provider.h > @@ -99,10 +99,12 @@ struct netdev { > struct shash_node *node; /* Pointer to element in global map. */ > struct ovs_list saved_flags_list; /* Contains "struct netdev_saved_flags". */ > > - /* Functions to control flow offloading. */ > + /* The type of dpif this netdev is associated with. This is set once > + * when the netdev is added to a specific dpif. */ > + const char *dpif_type; > + > + /* Data used for controlling flow offloading via dpif-offload. */ > OVSRCU_TYPE(const struct dpif_offload *) dpif_offload; > - OVSRCU_TYPE(const struct netdev_flow_api *) flow_api; > - const char *dpif_type; /* Type of dpif this netdev belongs to. */ > struct netdev_hw_info hw_info; /* Offload-capable netdev info. */ > }; > > diff --git a/lib/netdev.c b/lib/netdev.c > index 6a4218553..6b0ea8e11 100644 > --- a/lib/netdev.c > +++ b/lib/netdev.c > @@ -40,7 +40,6 @@ > #include "fatal-signal.h" > #include "hash.h" > #include "openvswitch/list.h" > -#include "netdev-offload-provider.h" > #include "netdev-provider.h" > #include "netdev-vport.h" > #include "odp-netlink.h" > @@ -431,7 +430,6 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp) > netdev->reconfigure_seq = seq_create(); > netdev->last_reconfigure_seq = > seq_read(netdev->reconfigure_seq); > - ovsrcu_set(&netdev->flow_api, NULL); > netdev->hw_info.oor = false; > atomic_init(&netdev->hw_info.postprocess_api_supported, false); > netdev->node = shash_add(&netdev_shash, name, netdev); > @@ -583,8 +581,6 @@ netdev_unref(struct netdev *dev) > const struct netdev_class *class = dev->netdev_class; > struct netdev_registered_class *rc; > > - netdev_uninit_flow_api(dev); > - > dev->netdev_class->destruct(dev); > > if (dev->node) { > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > index f751cdd4f..a7395ce09 100644 > --- a/ofproto/ofproto-dpif.c > +++ b/ofproto/ofproto-dpif.c > @@ -1765,7 +1765,7 @@ check_support(struct dpif_backer *backer) > /* TC does not support offloading the explicit drop action. As such we need to > * re-probe the datapath if hw-offload has been modified. > * Note: We don't support true --> false transition as that requires a restart. > - * See netdev_set_flow_api_enabled(). */ > + * See dpif_offload_set_global_cfg(). */ > static bool > recheck_support_explicit_drop_action(struct dpif_backer *backer) > { > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c > index 20eec1e4d..b82338b2d 100644 > --- a/vswitchd/bridge.c > +++ b/vswitchd/bridge.c > @@ -3400,7 +3400,6 @@ bridge_run(void) > } > > if (cfg) { > - netdev_set_flow_api_enabled(&cfg->other_config); > dpdk_init(&cfg->other_config); > userspace_tso_init(&cfg->other_config); > } > -- > 2.50.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff --git a/lib/automake.mk b/lib/automake.mk index 229064716..f7586bb0a 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -212,7 +212,6 @@ lib_libopenvswitch_la_SOURCES = \ lib/netdev-dummy.c \ lib/netdev-offload.c \ lib/netdev-offload.h \ - lib/netdev-offload-provider.h \ lib/netdev-provider.h \ lib/netdev-vport.c \ lib/netdev-vport.h \ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index df6c94912..484eefccb 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2404,7 +2404,6 @@ do_del_port(struct dp_netdev *dp, struct dp_netdev_port *port) * offload modification or deletion. Managing those stray requests * is done in the offload threads. */ dp_netdev_offload_flush(dp, port); - netdev_uninit_flow_api(port->netdev); port_destroy(port); } @@ -2813,7 +2812,7 @@ dp_netdev_flow_offload_put(struct dp_offload_thread_item *item) odp_port_t in_port = flow->flow.in_port.odp_port; bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD && flow->mark != INVALID_FLOW_MARK; - struct offload_info info; + struct dpif_netdev_offload_info info; struct netdev *port; uint32_t mark; int ret; diff --git a/lib/dpif-netdev.h b/lib/dpif-netdev.h index 6db6ed2e2..5df344367 100644 --- a/lib/dpif-netdev.h +++ b/lib/dpif-netdev.h @@ -38,6 +38,18 @@ bool dpif_is_netdev(const struct dpif *); #define NR_QUEUE 1 #define NR_PMD_THREADS 1 +/* Flow offloading info structure. XXX: This needs to be moved once the + * implementation is migrated to dpif-offload-dpdk. */ +struct dpif_netdev_offload_info { + /* + * The flow mark id assigned to the flow. If any pkts hit the flow, + * it will be in the pkt meta data. + */ + uint32_t flow_mark; + + odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ +}; + #ifdef __cplusplus } #endif diff --git a/lib/dpif.c b/lib/dpif.c index 323a2bf6c..006d9276e 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -378,7 +378,6 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp) if (!err) { netdev_set_dpif_type(netdev, dpif_type_str); - netdev_ports_insert(netdev, &dpif_port); if (new_offload_provider) { dpif_offload_port_add(dpif, netdev, dpif_port.port_no); } @@ -443,19 +442,6 @@ dpif_create_and_open(const char *name, const char *type, struct dpif **dpifp) return error; } -static void -dpif_remove_netdev_ports(struct dpif *dpif) { - const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); - struct dpif_port_dump port_dump; - struct dpif_port dpif_port; - - DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) { - if (!dpif_is_tap_port(dpif_port.type)) { - netdev_ports_remove(dpif_port.port_no, dpif_type_str); - } - } -} - /* Closes and frees the connection to 'dpif'. Does not destroy the datapath * itself; call dpif_delete() first, instead, if that is desirable. */ void @@ -466,9 +452,6 @@ dpif_close(struct dpif *dpif) rc = shash_find_data(&dpif_classes, dpif->dpif_class->type); - if (rc->refcount == 1) { - dpif_remove_netdev_ports(dpif); - } dpif_offload_detach_providers(dpif); dpif_uninit(dpif, true); dp_class_unref(rc); @@ -626,17 +609,9 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop) dpif_name(dpif), netdev_name, port_no); if (!dpif_is_tap_port(netdev_get_type(netdev))) { - const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif)); - struct dpif_port dpif_port; netdev_set_dpif_type(netdev, dpif_type_str); - - dpif_port.type = CONST_CAST(char *, netdev_get_type(netdev)); - dpif_port.name = CONST_CAST(char *, netdev_name); - dpif_port.port_no = port_no; - netdev_ports_insert(netdev, &dpif_port); - dpif_offload_port_add(dpif, netdev, port_no); } } else { @@ -670,8 +645,6 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no, bool local_delete) } dpif_offload_port_del(dpif, port_no); - - netdev_ports_remove(port_no, dpif_normalize_type(dpif_type(dpif))); return error; } diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 8ae1151ea..6a99f4ced 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -24,7 +24,6 @@ #include "dp-packet.h" #include "dpif-netdev.h" #include "flow.h" -#include "netdev-offload-provider.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "odp-util.h" diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c index cda5f3dbb..de10a71c4 100644 --- a/lib/netdev-offload-dpdk.c +++ b/lib/netdev-offload-dpdk.c @@ -2311,7 +2311,7 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev, struct nlattr *nl_actions, size_t actions_len, const ovs_u128 *ufid, - struct offload_info *info) + struct dpif_netdev_offload_info *info) { struct flow_patterns patterns = { .items = NULL, @@ -2428,7 +2428,8 @@ get_netdev_odp_cb(struct netdev *netdev, int netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match, struct nlattr *actions, size_t actions_len, - const ovs_u128 *ufid, struct offload_info *info, + const ovs_u128 *ufid, + struct dpif_netdev_offload_info *info, struct dpif_flow_stats *stats) { struct ufid_to_rte_flow_data *rte_flow_data; diff --git a/lib/netdev-offload-dpdk.h b/lib/netdev-offload-dpdk.h index 835220974..3587a3a72 100644 --- a/lib/netdev-offload-dpdk.h +++ b/lib/netdev-offload-dpdk.h @@ -19,7 +19,7 @@ /* Forward declarations of private structures. */ struct netdev; -struct offload_info; +struct dpif_netdev_offload_info; /* Netdev-specific offload functions. These should only be used by the * associated dpif offload provider. */ @@ -32,7 +32,8 @@ int netdev_offload_dpdk_hw_miss_packet_recover(struct netdev *, #ifdef DPDK_NETDEV int netdev_offload_dpdk_flow_put(struct netdev *, struct match *, struct nlattr *actions, size_t actions_len, - const ovs_u128 *ufid, struct offload_info *, + const ovs_u128 *ufid, + struct dpif_netdev_offload_info *, struct dpif_flow_stats *); int netdev_offload_dpdk_flow_del(struct netdev *, const ovs_u128 *ufid, struct dpif_flow_stats *); @@ -47,7 +48,7 @@ netdev_offload_dpdk_flow_put(struct netdev *netdev OVS_UNUSED, struct nlattr *actions OVS_UNUSED, size_t actions_len OVS_UNUSED, const ovs_u128 *ufid OVS_UNUSED, - struct offload_info *info OVS_UNUSED, + struct dpif_netdev_offload_info *info OVS_UNUSED, struct dpif_flow_stats *stats OVS_UNUSED) { return EOPNOTSUPP; diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h deleted file mode 100644 index 8087b84e3..000000000 --- a/lib/netdev-offload-provider.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc. - * Copyright (c) 2019 Samsung Electronics Co.,Ltd. - * - * 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_FLOW_API_PROVIDER_H -#define NETDEV_FLOW_API_PROVIDER_H 1 - -#include "flow.h" -#include "netdev-offload.h" -#include "openvswitch/netdev.h" -#include "openvswitch/types.h" -#include "packets.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct netdev_flow_api { - char *type; - - /* Offload the given flow on netdev. - * To modify a flow, use the same ufid. - * 'actions' are in netlink format, as with struct dpif_flow_put. - * 'info' is extra info needed to offload the flow. - * 'stats' is populated according to the rules set out in the description - * above 'struct dpif_flow_put'. - * Return 0 if successful, otherwise returns a positive errno value. */ - int (*flow_put)(struct netdev *, struct match *, struct nlattr *actions, - size_t actions_len, const ovs_u128 *ufid, - struct offload_info *info, struct dpif_flow_stats *); - - /* Queries a flow specified by ufid on netdev. - * Fills output buffer as 'wbuffer' in flow_dump_next, which - * needs to be be pre allocated. - * Return 0 if successful, otherwise returns a positive errno value. */ - int (*flow_get)(struct netdev *, struct match *, struct nlattr **actions, - const ovs_u128 *ufid, struct dpif_flow_stats *, - struct dpif_flow_attrs *, struct ofpbuf *wbuffer); - - /* Delete a flow specified by ufid from netdev. - * 'stats' is populated according to the rules set out in the description - * above 'struct dpif_flow_del'. - * Return 0 if successful, otherwise returns a positive errno value. */ - int (*flow_del)(struct netdev *, const ovs_u128 *ufid, - struct dpif_flow_stats *); - - /* Initializies the netdev flow api. - * Return 0 if successful, otherwise returns a positive errno value. */ - int (*init_flow_api)(struct netdev *); - - /* Uninitializes the netdev flow api. */ - void (*uninit_flow_api)(struct netdev *); -}; - -int netdev_register_flow_api_provider(const struct netdev_flow_api *); -int netdev_unregister_flow_api_provider(const char *type); - -#ifdef __linux__ -extern const struct netdev_flow_api netdev_offload_tc; -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* NETDEV_FLOW_API_PROVIDER_H */ diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index fff49240d..f24c415a2 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -16,248 +16,13 @@ */ #include <config.h> -#include "netdev-offload.h" - -#include <errno.h> -#include <inttypes.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "cmap.h" -#include "coverage.h" -#include "dpif.h" -#include "dpif-offload.h" -#include "dp-packet.h" -#include "openvswitch/dynamic-string.h" -#include "fatal-signal.h" -#include "hash.h" -#include "openvswitch/list.h" -#include "netdev-offload-provider.h" +#include "netdev-offload.h" #include "netdev-provider.h" -#include "netdev-vport.h" -#include "odp-netlink.h" -#include "openflow/openflow.h" -#include "packets.h" -#include "openvswitch/ofp-print.h" -#include "openvswitch/poll-loop.h" -#include "seq.h" -#include "openvswitch/shash.h" -#include "smap.h" -#include "socket-util.h" -#include "sset.h" -#include "svec.h" #include "openvswitch/vlog.h" -#include "flow.h" -#include "util.h" -#ifdef __linux__ -#include "tc.h" -#endif VLOG_DEFINE_THIS_MODULE(netdev_offload); -/* Protects 'netdev_flow_apis'. */ -static struct ovs_mutex netdev_flow_api_provider_mutex = OVS_MUTEX_INITIALIZER; - -/* Contains 'struct netdev_registered_flow_api's. */ -static struct cmap netdev_flow_apis = CMAP_INITIALIZER; - -struct netdev_registered_flow_api { - struct cmap_node cmap_node; /* In 'netdev_flow_apis', by flow_api->type. */ - const struct netdev_flow_api *flow_api; - - /* Number of references: one for the flow_api itself and one for every - * instance of the netdev that uses it. */ - struct ovs_refcount refcnt; -}; - -static struct netdev_registered_flow_api * -netdev_lookup_flow_api(const char *type) -{ - struct netdev_registered_flow_api *rfa; - CMAP_FOR_EACH_WITH_HASH (rfa, cmap_node, hash_string(type, 0), - &netdev_flow_apis) { - if (!strcmp(type, rfa->flow_api->type)) { - return rfa; - } - } - return NULL; -} - -/* Registers a new netdev flow api provider. */ -int -netdev_register_flow_api_provider(const struct netdev_flow_api *new_flow_api) - OVS_EXCLUDED(netdev_flow_api_provider_mutex) -{ - int error = 0; - - if (!new_flow_api->init_flow_api) { - VLOG_WARN("attempted to register invalid flow api provider: %s", - new_flow_api->type); - error = EINVAL; - } - - ovs_mutex_lock(&netdev_flow_api_provider_mutex); - if (netdev_lookup_flow_api(new_flow_api->type)) { - VLOG_WARN("attempted to register duplicate flow api provider: %s", - new_flow_api->type); - error = EEXIST; - } else { - struct netdev_registered_flow_api *rfa; - - rfa = xmalloc(sizeof *rfa); - cmap_insert(&netdev_flow_apis, &rfa->cmap_node, - hash_string(new_flow_api->type, 0)); - rfa->flow_api = new_flow_api; - ovs_refcount_init(&rfa->refcnt); - VLOG_DBG("netdev: flow API '%s' registered.", new_flow_api->type); - } - ovs_mutex_unlock(&netdev_flow_api_provider_mutex); - - return error; -} - -/* Unregisters a netdev flow api provider. 'type' must have been previously - * registered and not currently be in use by any netdevs. After unregistration - * netdev flow api of that type cannot be used for netdevs. (However, the - * provider may still be accessible from other threads until the next RCU grace - * period, so the caller must not free or re-register the same netdev_flow_api - * until that has passed.) */ -int -netdev_unregister_flow_api_provider(const char *type) - OVS_EXCLUDED(netdev_flow_api_provider_mutex) -{ - struct netdev_registered_flow_api *rfa; - int error; - - ovs_mutex_lock(&netdev_flow_api_provider_mutex); - rfa = netdev_lookup_flow_api(type); - if (!rfa) { - VLOG_WARN("attempted to unregister a flow api provider that is not " - "registered: %s", type); - error = EAFNOSUPPORT; - } else if (ovs_refcount_unref(&rfa->refcnt) != 1) { - ovs_refcount_ref(&rfa->refcnt); - VLOG_WARN("attempted to unregister in use flow api provider: %s", - type); - error = EBUSY; - } else { - cmap_remove(&netdev_flow_apis, &rfa->cmap_node, - hash_string(rfa->flow_api->type, 0)); - ovsrcu_postpone(free, rfa); - error = 0; - } - ovs_mutex_unlock(&netdev_flow_api_provider_mutex); - - return error; -} - -static int -netdev_assign_flow_api(struct netdev *netdev) -{ - struct netdev_registered_flow_api *rfa; - - CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) { - if (!rfa->flow_api->init_flow_api(netdev)) { - ovs_refcount_ref(&rfa->refcnt); - atomic_store_relaxed(&netdev->hw_info.postprocess_api_supported, - true); - ovsrcu_set(&netdev->flow_api, rfa->flow_api); - VLOG_INFO("%s: Assigned flow API '%s'.", - netdev_get_name(netdev), rfa->flow_api->type); - return 0; - } - VLOG_DBG("%s: flow API '%s' is not suitable.", - netdev_get_name(netdev), rfa->flow_api->type); - } - atomic_store_relaxed(&netdev->hw_info.postprocess_api_supported, false); - VLOG_INFO("%s: No suitable flow API found.", netdev_get_name(netdev)); - - return -1; -} - -int -netdev_flow_put(struct netdev *netdev, struct match *match, - struct nlattr *actions, size_t act_len, - const ovs_u128 *ufid, struct offload_info *info, - struct dpif_flow_stats *stats) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); - - return (flow_api && flow_api->flow_put) - ? flow_api->flow_put(netdev, match, actions, act_len, ufid, - info, stats) - : EOPNOTSUPP; -} - -int -netdev_flow_get(struct netdev *netdev, struct match *match, - struct nlattr **actions, const ovs_u128 *ufid, - struct dpif_flow_stats *stats, - struct dpif_flow_attrs *attrs, struct ofpbuf *buf) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); - - return (flow_api && flow_api->flow_get) - ? flow_api->flow_get(netdev, match, actions, ufid, - stats, attrs, buf) - : EOPNOTSUPP; -} - -int -netdev_flow_del(struct netdev *netdev, const ovs_u128 *ufid, - struct dpif_flow_stats *stats) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); - - return (flow_api && flow_api->flow_del) - ? flow_api->flow_del(netdev, ufid, stats) - : EOPNOTSUPP; -} - -int -netdev_init_flow_api(struct netdev *netdev) -{ - if (!dpif_offload_is_offload_enabled()) { - return EOPNOTSUPP; - } - - if (ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api)) { - return 0; - } - - if (netdev_assign_flow_api(netdev)) { - return EOPNOTSUPP; - } - - return 0; -} - -void -netdev_uninit_flow_api(struct netdev *netdev) -{ - struct netdev_registered_flow_api *rfa; - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); - - if (!flow_api) { - return; - } - - if (flow_api->uninit_flow_api) { - flow_api->uninit_flow_api(netdev); - } - - ovsrcu_set(&netdev->flow_api, NULL); - rfa = netdev_lookup_flow_api(flow_api->type); - ovs_refcount_unref(&rfa->refcnt); -} - /* * Get the value of the hw info parameter specified by type. * Returns the value on success (>= 0). Returns -1 on failure. @@ -307,223 +72,3 @@ netdev_set_hw_info(struct netdev *netdev, int type, int val) break; } } - -/* Protects below port hashmaps. */ -static struct ovs_rwlock ifindex_to_port_rwlock = OVS_RWLOCK_INITIALIZER; -static struct ovs_rwlock port_to_netdev_rwlock - OVS_ACQ_BEFORE(ifindex_to_port_rwlock) = OVS_RWLOCK_INITIALIZER; - -static struct hmap port_to_netdev OVS_GUARDED_BY(port_to_netdev_rwlock) - = HMAP_INITIALIZER(&port_to_netdev); -static struct hmap ifindex_to_port OVS_GUARDED_BY(ifindex_to_port_rwlock) - = HMAP_INITIALIZER(&ifindex_to_port); - -struct port_to_netdev_data { - struct hmap_node portno_node; /* By (dpif_type, dpif_port.port_no). */ - struct hmap_node ifindex_node; /* By (dpif_type, ifindex). */ - struct netdev *netdev; - struct dpif_port dpif_port; - int ifindex; -}; - -void -netdev_ports_traverse(const char *dpif_type, - bool (*cb)(struct netdev *, odp_port_t, void *), - void *aux) -{ - 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) { - if (cb(data->netdev, data->dpif_port.port_no, aux)) { - break; - } - } - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); -} - -int -netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid, - struct dpif_flow_stats *stats) -{ - 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_del(data->netdev, ufid, stats)) { - ovs_rwlock_unlock(&port_to_netdev_rwlock); - return 0; - } - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); - - return ENOENT; -} - -int -netdev_ports_flow_get(const char *dpif_type, struct match *match, - struct nlattr **actions, const ovs_u128 *ufid, - struct dpif_flow_stats *stats, - struct dpif_flow_attrs *attrs, struct ofpbuf *buf) -{ - 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_get(data->netdev, match, actions, - ufid, stats, attrs, buf)) { - ovs_rwlock_unlock(&port_to_netdev_rwlock); - return 0; - } - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); - return ENOENT; -} - -static uint32_t -netdev_ports_hash(odp_port_t port, const char *dpif_type) -{ - return hash_int(odp_to_u32(port), hash_pointer(dpif_type, 0)); -} - -static struct port_to_netdev_data * -netdev_ports_lookup(odp_port_t port_no, const char *dpif_type) - OVS_REQ_RDLOCK(port_to_netdev_rwlock) -{ - struct port_to_netdev_data *data; - - HMAP_FOR_EACH_WITH_HASH (data, portno_node, - netdev_ports_hash(port_no, dpif_type), - &port_to_netdev) { - if (netdev_get_dpif_type(data->netdev) == dpif_type - && data->dpif_port.port_no == port_no) { - return data; - } - } - return NULL; -} - -int -netdev_ports_insert(struct netdev *netdev, struct dpif_port *dpif_port) -{ - const char *dpif_type = netdev_get_dpif_type(netdev); - struct port_to_netdev_data *data; - int ifindex = netdev_get_ifindex(netdev); - - ovs_assert(dpif_type); - - ovs_rwlock_wrlock(&port_to_netdev_rwlock); - if (netdev_ports_lookup(dpif_port->port_no, dpif_type)) { - ovs_rwlock_unlock(&port_to_netdev_rwlock); - return EEXIST; - } - - data = xzalloc(sizeof *data); - data->netdev = netdev_ref(netdev); - dpif_port_clone(&data->dpif_port, dpif_port); - - if (ifindex >= 0) { - data->ifindex = ifindex; - ovs_rwlock_wrlock(&ifindex_to_port_rwlock); - hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex); - ovs_rwlock_unlock(&ifindex_to_port_rwlock); - } else { - data->ifindex = -1; - } - - hmap_insert(&port_to_netdev, &data->portno_node, - netdev_ports_hash(dpif_port->port_no, dpif_type)); - ovs_rwlock_unlock(&port_to_netdev_rwlock); - - netdev_init_flow_api(netdev); - - return 0; -} - -struct netdev * -netdev_ports_get(odp_port_t port_no, const char *dpif_type) -{ - struct port_to_netdev_data *data; - struct netdev *ret = NULL; - - ovs_rwlock_rdlock(&port_to_netdev_rwlock); - data = netdev_ports_lookup(port_no, dpif_type); - if (data) { - ret = netdev_ref(data->netdev); - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); - - return ret; -} - -int -netdev_ports_remove(odp_port_t port_no, const char *dpif_type) -{ - struct port_to_netdev_data *data; - int ret = ENOENT; - - ovs_rwlock_wrlock(&port_to_netdev_rwlock); - data = netdev_ports_lookup(port_no, dpif_type); - if (data) { - dpif_port_destroy(&data->dpif_port); - netdev_close(data->netdev); /* unref and possibly close */ - hmap_remove(&port_to_netdev, &data->portno_node); - if (data->ifindex >= 0) { - ovs_rwlock_wrlock(&ifindex_to_port_rwlock); - hmap_remove(&ifindex_to_port, &data->ifindex_node); - ovs_rwlock_unlock(&ifindex_to_port_rwlock); - } - free(data); - ret = 0; - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); - - return ret; -} - -odp_port_t -netdev_ifindex_to_odp_port(int ifindex) -{ - struct port_to_netdev_data *data; - odp_port_t ret = 0; - - ovs_rwlock_rdlock(&ifindex_to_port_rwlock); - HMAP_FOR_EACH_WITH_HASH (data, ifindex_node, ifindex, &ifindex_to_port) { - if (data->ifindex == ifindex) { - ret = data->dpif_port.port_no; - break; - } - } - ovs_rwlock_unlock(&ifindex_to_port_rwlock); - - return ret; -} - -static void -netdev_ports_flow_init(void) -{ - struct port_to_netdev_data *data; - - ovs_rwlock_rdlock(&port_to_netdev_rwlock); - HMAP_FOR_EACH (data, portno_node, &port_to_netdev) { - netdev_init_flow_api(data->netdev); - } - ovs_rwlock_unlock(&port_to_netdev_rwlock); -} - -void -netdev_set_flow_api_enabled(const struct smap *ovs_other_config OVS_UNUSED) -{ - if (dpif_offload_is_offload_enabled()) { - static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; - - if (ovsthread_once_start(&once)) { - netdev_ports_flow_init(); - ovsthread_once_done(&once); - } - } -} diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index b8701bad6..fe42c9b4d 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -19,31 +19,13 @@ #define NETDEV_OFFLOAD_H 1 #include "openvswitch/netdev.h" -#include "openvswitch/types.h" #include "ovs-atomic.h" #include "ovs-rcu.h" -#include "ovs-thread.h" -#include "openvswitch/ofp-meter.h" -#include "packets.h" -#include "flow.h" #ifdef __cplusplus extern "C" { #endif -struct dp_packet_batch; -struct dp_packet; -struct netdev_class; -struct netdev_rxq; -struct netdev_saved_flags; -struct ofpbuf; -struct in_addr; -struct in6_addr; -struct smap; -struct sset; -struct ovs_action_push_tnl; - - /* Offload-capable (HW) netdev information */ struct netdev_hw_info { bool oor; /* Out of Offload Resources ? */ @@ -60,53 +42,8 @@ enum hw_info_type { HW_INFO_TYPE_OFFL_COUNT = 3 /* Offloaded flow count */ }; -/* Flow offloading. */ -struct offload_info { - /* - * The flow mark id assigned to the flow. If any pkts hit the flow, - * it will be in the pkt meta data. - */ - uint32_t flow_mark; - - odp_port_t orig_in_port; /* Originating in_port for tnl flows. */ -}; - -int netdev_flow_put(struct netdev *, struct match *, struct nlattr *actions, - size_t actions_len, const ovs_u128 *, - struct offload_info *, struct dpif_flow_stats *); -int netdev_flow_get(struct netdev *, struct match *, struct nlattr **actions, - const ovs_u128 *, struct dpif_flow_stats *, - struct dpif_flow_attrs *, struct ofpbuf *wbuffer); -int netdev_flow_del(struct netdev *, const ovs_u128 *, - struct dpif_flow_stats *); -int netdev_init_flow_api(struct netdev *); -void netdev_uninit_flow_api(struct netdev *); int netdev_get_hw_info(struct netdev *, int); void netdev_set_hw_info(struct netdev *, int, int); -void netdev_set_flow_api_enabled(const struct smap *ovs_other_config); - -struct dpif_port; -int netdev_ports_insert(struct netdev *, struct dpif_port *); -struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type); -int netdev_ports_remove(odp_port_t port, const char *dpif_type); -odp_port_t netdev_ifindex_to_odp_port(int ifindex); - -/* For each of the ports with dpif_type, call cb with the netdev and port - * number of the port, and an opaque user argument. - * The returned value is used to continue traversing upon false or stop if - * true. - */ -void netdev_ports_traverse(const char *dpif_type, - bool (*cb)(struct netdev *, odp_port_t, void *), - void *aux); -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, - struct nlattr **actions, - const ovs_u128 *ufid, - struct dpif_flow_stats *stats, - struct dpif_flow_attrs *attrs, - struct ofpbuf *buf); #ifdef __cplusplus } diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index 87bc95180..753151330 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -99,10 +99,12 @@ struct netdev { struct shash_node *node; /* Pointer to element in global map. */ struct ovs_list saved_flags_list; /* Contains "struct netdev_saved_flags". */ - /* Functions to control flow offloading. */ + /* The type of dpif this netdev is associated with. This is set once + * when the netdev is added to a specific dpif. */ + const char *dpif_type; + + /* Data used for controlling flow offloading via dpif-offload. */ OVSRCU_TYPE(const struct dpif_offload *) dpif_offload; - OVSRCU_TYPE(const struct netdev_flow_api *) flow_api; - const char *dpif_type; /* Type of dpif this netdev belongs to. */ struct netdev_hw_info hw_info; /* Offload-capable netdev info. */ }; diff --git a/lib/netdev.c b/lib/netdev.c index 6a4218553..6b0ea8e11 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -40,7 +40,6 @@ #include "fatal-signal.h" #include "hash.h" #include "openvswitch/list.h" -#include "netdev-offload-provider.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "odp-netlink.h" @@ -431,7 +430,6 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp) netdev->reconfigure_seq = seq_create(); netdev->last_reconfigure_seq = seq_read(netdev->reconfigure_seq); - ovsrcu_set(&netdev->flow_api, NULL); netdev->hw_info.oor = false; atomic_init(&netdev->hw_info.postprocess_api_supported, false); netdev->node = shash_add(&netdev_shash, name, netdev); @@ -583,8 +581,6 @@ netdev_unref(struct netdev *dev) const struct netdev_class *class = dev->netdev_class; struct netdev_registered_class *rc; - netdev_uninit_flow_api(dev); - dev->netdev_class->destruct(dev); if (dev->node) { diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index f751cdd4f..a7395ce09 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1765,7 +1765,7 @@ check_support(struct dpif_backer *backer) /* TC does not support offloading the explicit drop action. As such we need to * re-probe the datapath if hw-offload has been modified. * Note: We don't support true --> false transition as that requires a restart. - * See netdev_set_flow_api_enabled(). */ + * See dpif_offload_set_global_cfg(). */ static bool recheck_support_explicit_drop_action(struct dpif_backer *backer) { diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 20eec1e4d..b82338b2d 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -3400,7 +3400,6 @@ bridge_run(void) } if (cfg) { - netdev_set_flow_api_enabled(&cfg->other_config); dpdk_init(&cfg->other_config); userspace_tso_init(&cfg->other_config); }
This patch removes the global netdev_flow_api in favor of the new dpif-offload infrastructure. All offload-related handling is now performed via the dpif-offload layer, simplifying the code and removing redundant global interfaces from netdev-offload. Signed-off-by: Eelco Chaudron <echaudro@redhat.com> --- lib/automake.mk | 1 - lib/dpif-netdev.c | 3 +- lib/dpif-netdev.h | 12 + lib/dpif.c | 27 -- lib/netdev-dummy.c | 1 - lib/netdev-offload-dpdk.c | 5 +- lib/netdev-offload-dpdk.h | 7 +- lib/netdev-offload-provider.h | 79 ------ lib/netdev-offload.c | 457 +--------------------------------- lib/netdev-offload.h | 63 ----- lib/netdev-provider.h | 8 +- lib/netdev.c | 4 - ofproto/ofproto-dpif.c | 2 +- vswitchd/bridge.c | 1 - 14 files changed, 27 insertions(+), 643 deletions(-) delete mode 100644 lib/netdev-offload-provider.h