dpif-netlink: Remove netlink-offload integration This patch removes the legacy integration between dpif-netlink and netlink-offload. All netdev flow dump structures, flow dump APIs, and supporting code related to offloaded flows in dpif-netlink and netdev-offload have been removed, as (tc) flow offload is now handled entirely through dpif-offload.
This simplifies dpif-netlink by decoupling it from all it's offload logic. Signed-off-by: Eelco Chaudron <echau...@redhat.com> --- lib/dpif-netlink.c | 169 +++------------------------------- lib/dpif-offload-tc.c | 8 +- lib/netdev-offload-provider.h | 23 ----- lib/netdev-offload-tc.c | 12 +-- lib/netdev-offload-tc.h | 15 ++- lib/netdev-offload.c | 77 ---------------- lib/netdev-offload.h | 18 ---- 7 files changed, 33 insertions(+), 289 deletions(-) diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index ff29f9427..2df91a98e 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -79,7 +79,6 @@ enum { MAX_PORTS = USHRT_MAX }; * missing if we have old headers. */ #define ETH_FLAG_LRO (1 << 15) /* LRO is enabled */ -#define FLOW_DUMP_MAX_BATCH 50 #define OPERATE_MAX_OPS 50 #ifndef EPOLLEXCLUSIVE @@ -1599,11 +1598,6 @@ struct dpif_netlink_flow_dump { struct dpif_flow_dump up; struct nl_dump nl_dump; atomic_int status; - struct netdev_flow_dump **netdev_dumps; - int netdev_dumps_num; /* Number of netdev_flow_dumps */ - struct ovs_mutex netdev_lock; /* Guards the following. */ - int netdev_current_dump OVS_GUARDED; /* Shared current dump */ - struct dpif_flow_dump_types types; /* Type of dump */ }; static struct dpif_netlink_flow_dump * @@ -1612,39 +1606,6 @@ dpif_netlink_flow_dump_cast(struct dpif_flow_dump *dump) return CONTAINER_OF(dump, struct dpif_netlink_flow_dump, up); } -static void -start_netdev_dump(const struct dpif *dpif_, - struct dpif_netlink_flow_dump *dump) -{ - ovs_mutex_init(&dump->netdev_lock); - - if (!(dump->types.offloaded_flows)) { - dump->netdev_dumps_num = 0; - dump->netdev_dumps = NULL; - return; - } - - ovs_mutex_lock(&dump->netdev_lock); - dump->netdev_current_dump = 0; - dump->netdev_dumps - = netdev_ports_flow_dump_create(dpif_normalize_type(dpif_type(dpif_)), - &dump->netdev_dumps_num, - dump->up.terse); - ovs_mutex_unlock(&dump->netdev_lock); -} - -static void -dpif_netlink_populate_flow_dump_types(struct dpif_netlink_flow_dump *dump, - struct dpif_flow_dump_types *types) -{ - if (!types) { - dump->types.ovs_flows = true; - dump->types.offloaded_flows = true; - } else { - memcpy(&dump->types, types, sizeof *types); - } -} - static struct dpif_flow_dump * dpif_netlink_flow_dump_create(const struct dpif *dpif_, bool terse, struct dpif_flow_dump_types *types) @@ -1657,24 +1618,18 @@ dpif_netlink_flow_dump_create(const struct dpif *dpif_, bool terse, dump = xmalloc(sizeof *dump); dpif_flow_dump_init(&dump->up, dpif_, terse, types); - dpif_netlink_populate_flow_dump_types(dump, types); - - if (dump->types.ovs_flows) { - dpif_netlink_flow_init(&request); - request.cmd = OVS_FLOW_CMD_GET; - request.dp_ifindex = dpif->dp_ifindex; - request.ufid_present = false; - request.ufid_terse = terse; + dpif_netlink_flow_init(&request); + request.cmd = OVS_FLOW_CMD_GET; + request.dp_ifindex = dpif->dp_ifindex; + request.ufid_present = false; + request.ufid_terse = terse; - buf = ofpbuf_new(1024); - dpif_netlink_flow_to_ofpbuf(&request, buf); - nl_dump_start(&dump->nl_dump, NETLINK_GENERIC, buf); - ofpbuf_delete(buf); - } + buf = ofpbuf_new(1024); + dpif_netlink_flow_to_ofpbuf(&request, buf); + nl_dump_start(&dump->nl_dump, NETLINK_GENERIC, buf); + ofpbuf_delete(buf); atomic_init(&dump->status, 0); - start_netdev_dump(dpif_, dump); - return &dump->up; } @@ -1682,24 +1637,9 @@ static int dpif_netlink_flow_dump_destroy(struct dpif_flow_dump *dump_) { struct dpif_netlink_flow_dump *dump = dpif_netlink_flow_dump_cast(dump_); - unsigned int nl_status = 0; + unsigned int nl_status = nl_dump_done(&dump->nl_dump); int dump_status; - if (dump->types.ovs_flows) { - nl_status = nl_dump_done(&dump->nl_dump); - } - - for (int i = 0; i < dump->netdev_dumps_num; i++) { - int err = netdev_flow_dump_destroy(dump->netdev_dumps[i]); - - if (err != 0 && err != EOPNOTSUPP) { - VLOG_ERR("failed dumping netdev: %s", ovs_strerror(err)); - } - } - - free(dump->netdev_dumps); - ovs_mutex_destroy(&dump->netdev_lock); - /* No other thread has access to 'dump' at this point. */ atomic_read_relaxed(&dump->status, &dump_status); free(dump); @@ -1713,13 +1653,6 @@ struct dpif_netlink_flow_dump_thread { struct dpif_flow_stats stats; struct ofpbuf nl_flows; /* Always used to store flows. */ struct ofpbuf *nl_actions; /* Used if kernel does not supply actions. */ - int netdev_dump_idx; /* This thread current netdev dump index */ - bool netdev_done; /* If we are finished dumping netdevs */ - - /* (Key/Mask/Actions) Buffers for netdev dumping */ - struct odputil_keybuf keybuf[FLOW_DUMP_MAX_BATCH]; - struct odputil_keybuf maskbuf[FLOW_DUMP_MAX_BATCH]; - struct odputil_keybuf actbuf[FLOW_DUMP_MAX_BATCH]; }; static struct dpif_netlink_flow_dump_thread * @@ -1739,8 +1672,6 @@ dpif_netlink_flow_dump_thread_create(struct dpif_flow_dump *dump_) thread->dump = dump; ofpbuf_init(&thread->nl_flows, NL_DUMP_BUFSIZE); thread->nl_actions = NULL; - thread->netdev_dump_idx = 0; - thread->netdev_done = !(thread->netdev_dump_idx < dump->netdev_dumps_num); return &thread->up; } @@ -1781,39 +1712,6 @@ dpif_netlink_flow_to_dpif_flow(struct dpif_flow *dpif_flow, dpif_flow->attrs.dp_extra_info = NULL; } -/* The design is such that all threads are working together on the first dump - * to the last, in order (at first they all on dump 0). - * When the first thread finds that the given dump is finished, - * they all move to the next. If two or more threads find the same dump - * is finished at the same time, the first one will advance the shared - * netdev_current_dump and the others will catch up. */ -static void -dpif_netlink_advance_netdev_dump(struct dpif_netlink_flow_dump_thread *thread) -{ - struct dpif_netlink_flow_dump *dump = thread->dump; - - ovs_mutex_lock(&dump->netdev_lock); - /* if we haven't finished (dumped everything) */ - if (dump->netdev_current_dump < dump->netdev_dumps_num) { - /* if we are the first to find that current dump is finished - * advance it. */ - if (thread->netdev_dump_idx == dump->netdev_current_dump) { - thread->netdev_dump_idx = ++dump->netdev_current_dump; - /* did we just finish the last dump? done. */ - if (dump->netdev_current_dump == dump->netdev_dumps_num) { - thread->netdev_done = true; - } - } else { - /* otherwise, we are behind, catch up */ - thread->netdev_dump_idx = dump->netdev_current_dump; - } - } else { - /* some other thread finished */ - thread->netdev_done = true; - } - ovs_mutex_unlock(&dump->netdev_lock); -} - static int dpif_netlink_netdev_match_to_dpif_flow(struct match *match, struct ofpbuf *key_buf, @@ -1882,56 +1780,11 @@ dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_, = dpif_netlink_flow_dump_thread_cast(thread_); struct dpif_netlink_flow_dump *dump = thread->dump; struct dpif_netlink *dpif = dpif_netlink_cast(thread->up.dump->dpif); - int n_flows; + int n_flows = 0; ofpbuf_delete(thread->nl_actions); thread->nl_actions = NULL; - n_flows = 0; - max_flows = MIN(max_flows, FLOW_DUMP_MAX_BATCH); - - while (!thread->netdev_done && n_flows < max_flows) { - struct odputil_keybuf *maskbuf = &thread->maskbuf[n_flows]; - struct odputil_keybuf *keybuf = &thread->keybuf[n_flows]; - struct odputil_keybuf *actbuf = &thread->actbuf[n_flows]; - struct ofpbuf key, mask, act; - struct dpif_flow *f = &flows[n_flows]; - int cur = thread->netdev_dump_idx; - struct netdev_flow_dump *netdev_dump = dump->netdev_dumps[cur]; - struct match match; - struct nlattr *actions; - struct dpif_flow_stats stats; - struct dpif_flow_attrs attrs; - ovs_u128 ufid; - bool has_next; - - ofpbuf_use_stack(&key, keybuf, sizeof *keybuf); - ofpbuf_use_stack(&act, actbuf, sizeof *actbuf); - ofpbuf_use_stack(&mask, maskbuf, sizeof *maskbuf); - has_next = netdev_flow_dump_next(netdev_dump, &match, - &actions, &stats, &attrs, - &ufid, - &thread->nl_flows, - &act); - if (has_next) { - dpif_netlink_netdev_match_to_dpif_flow(&match, - &key, &mask, - actions, - &stats, - &attrs, - &ufid, - f, - dump->up.terse); - n_flows++; - } else { - dpif_netlink_advance_netdev_dump(thread); - } - } - - if (!(dump->types.ovs_flows)) { - return n_flows; - } - while (!n_flows || (n_flows < max_flows && thread->nl_flows.size)) { struct dpif_netlink_flow datapath_flow; diff --git a/lib/dpif-offload-tc.c b/lib/dpif-offload-tc.c index c74bfb52e..e2e18b5b1 100644 --- a/lib/dpif-offload-tc.c +++ b/lib/dpif-offload-tc.c @@ -48,7 +48,7 @@ struct dpif_offload_tc_flow_dump { struct ovs_mutex netdev_dump_mutex; size_t netdev_dump_index; size_t netdev_dump_count; - struct netdev_flow_dump *netdev_dumps[]; + struct netdev_tc_flow_dump *netdev_dumps[]; }; #define FLOW_DUMP_MAX_BATCH 50 @@ -333,7 +333,7 @@ dpif_offload_tc_flow_dump_create(const struct dpif_offload *offload_, port_count = dpif_offload_port_mgr_port_count(offload->port_mgr); dump = xmalloc(sizeof *dump + - (port_count * sizeof(struct netdev_flow_dump))); + (port_count * sizeof(struct netdev_tc_flow_dump))); dpif_offload_flow_dump_init(&dump->dump, offload_, terse); @@ -458,8 +458,8 @@ dpif_offload_tc_flow_dump_next(struct dpif_offload_flow_dump_thread *thread_, struct odputil_keybuf *maskbuf = &thread->maskbuf[n_flows]; struct odputil_keybuf *keybuf = &thread->keybuf[n_flows]; struct odputil_keybuf *actbuf = &thread->actbuf[n_flows]; + struct netdev_tc_flow_dump *netdev_dump; struct dpif_flow *f = &flows[n_flows]; - struct netdev_flow_dump *netdev_dump; int cur = thread->netdev_dump_index; struct ofpbuf key, mask, act; struct dpif_flow_stats stats; @@ -505,7 +505,7 @@ dpif_offload_tc_flow_dump_destroy(struct dpif_offload_flow_dump *dump_) dump = dpif_offload_tc_flow_dump_cast(dump_); for (int i = 0; i < dump->netdev_dump_count; i++) { - struct netdev_flow_dump *dump_netdev = dump->netdev_dumps[i]; + struct netdev_tc_flow_dump *dump_netdev = dump->netdev_dumps[i]; int rc = netdev_offload_tc_flow_dump_destroy(dump_netdev); if (rc && !error) { diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index f762af19a..6af97a723 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -31,29 +31,6 @@ extern "C" { struct netdev_flow_api { char *type; - /* Flow dumping interface. - * - * This is the back-end for the flow dumping interface described in - * dpif.h. Please read the comments there first, because this code - * closely follows it. - * - * On success returns 0 and allocates data, on failure returns - * positive errno. */ - int (*flow_dump_create)(struct netdev *, struct netdev_flow_dump **dump, - bool terse); - int (*flow_dump_destroy)(struct netdev_flow_dump *); - - /* Returns true if there are more flows to dump. - * 'rbuffer' is used as a temporary buffer and needs to be pre allocated - * by the caller. While there are more flows the same 'rbuffer' - * should be provided. 'wbuffer' is used to store dumped actions and needs - * to be pre allocated by the caller. */ - bool (*flow_dump_next)(struct netdev_flow_dump *, struct match *, - struct nlattr **actions, - struct dpif_flow_stats *stats, - struct dpif_flow_attrs *attrs, ovs_u128 *ufid, - struct ofpbuf *rbuffer, struct ofpbuf *wbuffer); - /* 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. diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 44518b3c1..ced017e98 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -501,7 +501,7 @@ static int get_chains_from_netdev(struct netdev *netdev, struct tcf_id *id, struct hmap *map) { - struct netdev_flow_dump *dump; + struct netdev_tc_flow_dump *dump; struct chain_node *chain_node; struct ofpbuf rbuffer, reply; uint32_t chain; @@ -588,11 +588,11 @@ netdev_offload_tc_flow_flush(struct netdev *netdev) int netdev_offload_tc_flow_dump_create(struct netdev *netdev, - struct netdev_flow_dump **dump_out, + struct netdev_tc_flow_dump **dump_out, bool terse) { enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); - struct netdev_flow_dump *dump; + struct netdev_tc_flow_dump *dump; uint32_t block_id = 0; struct tcf_id id; int prio = 0; @@ -619,7 +619,7 @@ netdev_offload_tc_flow_dump_create(struct netdev *netdev, return 0; } int -netdev_offload_tc_flow_dump_destroy(struct netdev_flow_dump *dump) +netdev_offload_tc_flow_dump_destroy(struct netdev_tc_flow_dump *dump) { nl_dump_done(dump->nl_dump); netdev_close(dump->netdev); @@ -1351,7 +1351,7 @@ parse_tc_flower_to_match(const struct netdev *netdev, } bool -netdev_offload_tc_flow_dump_next(struct netdev_flow_dump *dump, +netdev_offload_tc_flow_dump_next(struct netdev_tc_flow_dump *dump, struct match *match, struct nlattr **actions, struct dpif_flow_stats *stats, @@ -3070,7 +3070,7 @@ tc_get_policer_action_ids(struct hmap *map) { uint32_t police_idx[TCA_ACT_MAX_PRIO]; struct policer_node *policer_node; - struct netdev_flow_dump *dump; + struct netdev_tc_flow_dump *dump; struct ofpbuf rbuffer, reply; size_t hash; int i, err; diff --git a/lib/netdev-offload-tc.h b/lib/netdev-offload-tc.h index d628e42ba..e4740c799 100644 --- a/lib/netdev-offload-tc.h +++ b/lib/netdev-offload-tc.h @@ -21,13 +21,22 @@ struct dpif_offload; struct netdev; +/* Per Netdev flow dump structure. */ +struct netdev_tc_flow_dump { + struct nl_dump *nl_dump; + struct netdev *netdev; + odp_port_t port; + bool terse; +}; + /* Netdev-specific offload functions. These should only be used by the * associated dpif offload provider. */ int netdev_offload_tc_flow_flush(struct netdev *); int netdev_offload_tc_flow_dump_create(struct netdev *, - struct netdev_flow_dump **, bool terse); -int netdev_offload_tc_flow_dump_destroy(struct netdev_flow_dump *); -bool netdev_offload_tc_flow_dump_next(struct netdev_flow_dump *, + struct netdev_tc_flow_dump **, + bool terse); +int netdev_offload_tc_flow_dump_destroy(struct netdev_tc_flow_dump *); +bool netdev_offload_tc_flow_dump_next(struct netdev_tc_flow_dump *, struct match *, struct nlattr **actions, struct dpif_flow_stats *, struct dpif_flow_attrs *, ovs_u128 *ufid, diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index bdc50da5d..3fec58b4f 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -200,44 +200,6 @@ netdev_assign_flow_api(struct netdev *netdev) return -1; } -int -netdev_flow_dump_create(struct netdev *netdev, struct netdev_flow_dump **dump, - bool terse) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api); - - return (flow_api && flow_api->flow_dump_create) - ? flow_api->flow_dump_create(netdev, dump, terse) - : EOPNOTSUPP; -} - -int -netdev_flow_dump_destroy(struct netdev_flow_dump *dump) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &dump->netdev->flow_api); - - return (flow_api && flow_api->flow_dump_destroy) - ? flow_api->flow_dump_destroy(dump) - : EOPNOTSUPP; -} - -bool -netdev_flow_dump_next(struct netdev_flow_dump *dump, struct match *match, - struct nlattr **actions, struct dpif_flow_stats *stats, - struct dpif_flow_attrs *attrs, ovs_u128 *ufid, - struct ofpbuf *rbuffer, struct ofpbuf *wbuffer) -{ - const struct netdev_flow_api *flow_api = - ovsrcu_get(const struct netdev_flow_api *, &dump->netdev->flow_api); - - return (flow_api && flow_api->flow_dump_next) - ? flow_api->flow_dump_next(dump, match, actions, stats, attrs, - ufid, rbuffer, wbuffer) - : false; -} - int netdev_flow_put(struct netdev *netdev, struct match *match, struct nlattr *actions, size_t act_len, @@ -497,45 +459,6 @@ netdev_ports_traverse(const char *dpif_type, ovs_rwlock_unlock(&port_to_netdev_rwlock); } -struct netdev_flow_dump ** -netdev_ports_flow_dump_create(const char *dpif_type, int *ports, bool terse) -{ - struct netdev_flow_dump **dumps = NULL; - struct port_to_netdev_data *data; - int count = 0; - int i = 0; - - 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) { - count++; - } - } - - if (!count) { - goto unlock; - } - - dumps = xzalloc(sizeof *dumps * count); - - HMAP_FOR_EACH (data, portno_node, &port_to_netdev) { - if (netdev_get_dpif_type(data->netdev) == dpif_type) { - if (netdev_flow_dump_create(data->netdev, &dumps[i], terse)) { - continue; - } - - dumps[i]->port = data->dpif_port.port_no; - i++; - } - } - -unlock: - ovs_rwlock_unlock(&port_to_netdev_rwlock); - - *ports = i; - return dumps; -} - int netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid, struct dpif_flow_stats *stats) diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index 111de378b..39d11904e 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -59,13 +59,6 @@ enum hw_info_type { HW_INFO_TYPE_OFFL_COUNT = 3 /* Offloaded flow count */ }; -struct netdev_flow_dump { - struct netdev *netdev; - odp_port_t port; - bool terse; - struct nl_dump *nl_dump; -}; - /* Flow offloading. */ struct offload_info { bool recirc_id_shared_with_tc; /* Indicates whever tc chains will be in @@ -100,13 +93,6 @@ netdev_offload_thread_id(void) return id; } -int netdev_flow_dump_create(struct netdev *, struct netdev_flow_dump **dump, - bool terse); -int netdev_flow_dump_destroy(struct netdev_flow_dump *); -bool netdev_flow_dump_next(struct netdev_flow_dump *, struct match *, - struct nlattr **actions, struct dpif_flow_stats *, - struct dpif_flow_attrs *, ovs_u128 *ufid, - struct ofpbuf *rbuffer, struct ofpbuf *wbuffer); 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 *); @@ -137,10 +123,6 @@ odp_port_t netdev_ifindex_to_odp_port(int ifindex); void netdev_ports_traverse(const char *dpif_type, bool (*cb)(struct netdev *, odp_port_t, void *), void *aux); -struct netdev_flow_dump **netdev_ports_flow_dump_create( - const char *dpif_type, - int *ports, - bool terse); 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 d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev