Move port manager instances from provider-specific data structures into the common struct dpif_offload. This removes duplication across providers and clarifies ownership of port-related state.
With the port manager owned by dpif_offload, offload providers are required to use the common port management APIs. This simplifies external port management and eliminates the need for provider-specific port enumeration logic. The port dump functions were also simplified using the CMAP_CURSOR_FOR_EACH_CONTINUE() API. Signed-off-by: Eelco Chaudron <[email protected]> --- lib/dpif-offload-dpdk-netdev.c | 5 +- lib/dpif-offload-dpdk.c | 107 ++++++----------- lib/dpif-offload-dummy.c | 94 +++++---------- lib/dpif-offload-provider.h | 73 ++++-------- lib/dpif-offload-tc-netdev.c | 5 +- lib/dpif-offload-tc.c | 114 ++++++------------ lib/dpif-offload.c | 208 ++++++++++++++++----------------- lib/dpif-offload.h | 5 +- 8 files changed, 234 insertions(+), 377 deletions(-) diff --git a/lib/dpif-offload-dpdk-netdev.c b/lib/dpif-offload-dpdk-netdev.c index d61365ed76..efe99065e4 100644 --- a/lib/dpif-offload-dpdk-netdev.c +++ b/lib/dpif-offload-dpdk-netdev.c @@ -2788,8 +2788,9 @@ dpdk_netdev_flow_del(struct dpdk_offload *offload, struct netdev *netdev, return dpdk_flow_destroy(offload, rte_flow_data, false, false); } -int dpdk_netdev_offload_init(struct netdev *netdev, - unsigned int offload_thread_count) +int +dpdk_netdev_offload_init(struct netdev *netdev, + unsigned int offload_thread_count) { int ret = EOPNOTSUPP; diff --git a/lib/dpif-offload-dpdk.c b/lib/dpif-offload-dpdk.c index 5b58f3be00..8b09244d05 100644 --- a/lib/dpif-offload-dpdk.c +++ b/lib/dpif-offload-dpdk.c @@ -93,7 +93,6 @@ struct dpdk_offload_thread_item { /* dpif offload interface for the dpdk rte_flow implementation. */ struct dpdk_offload { struct dpif_offload offload; - struct dpif_offload_port_mgr *port_mgr; atomic_count next_offload_thread_id; atomic_bool offload_thread_shutdown; @@ -565,9 +564,9 @@ dpdk_offload_traverse_ports(const struct dpdk_offload *offload, bool (*cb)(struct netdev *, odp_port_t, void *), void *aux) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, &offload->offload) { if (cb(port->netdev, port->port_no, aux)) { break; } @@ -576,7 +575,7 @@ dpdk_offload_traverse_ports(const struct dpdk_offload *offload, static int dpdk_offload_enable(struct dpif_offload *offload_, - struct dpif_offload_port_mgr_port *port) + struct dpif_offload_port *port) { struct dpdk_offload *offload = dpdk_offload_cast(offload_); struct netdev *netdev = port->netdev; @@ -588,7 +587,7 @@ dpdk_offload_enable(struct dpif_offload *offload_, static int dpdk_offload_cleanup(struct dpif_offload *offload_ OVS_UNUSED, - struct dpif_offload_port_mgr_port *port) + struct dpif_offload_port *port) { struct netdev *netdev = port->netdev; @@ -598,16 +597,14 @@ dpdk_offload_cleanup(struct dpif_offload *offload_ OVS_UNUSED, } static int -dpdk_offload_port_add(struct dpif_offload *offload_, struct netdev *netdev, +dpdk_offload_port_add(struct dpif_offload *offload, struct netdev *netdev, odp_port_t port_no) { - struct dpif_offload_port_mgr_port *port = xmalloc(sizeof *port); - struct dpdk_offload *offload = dpdk_offload_cast(offload_); + struct dpif_offload_port *port = xmalloc(sizeof *port); - if (dpif_offload_port_mgr_add(offload->port_mgr, port, netdev, - port_no, false)) { + if (dpif_offload_port_mgr_add(offload, port, netdev, port_no, false)) { if (dpif_offload_enabled()) { - return dpdk_offload_enable(offload_, port); + return dpdk_offload_enable(offload, port); } return 0; } @@ -617,7 +614,7 @@ dpdk_offload_port_add(struct dpif_offload *offload_, struct netdev *netdev, } static void -dpdk_offload_free_port(struct dpif_offload_port_mgr_port *port) +dpdk_offload_free_port(struct dpif_offload_port *port) { netdev_close(port->netdev); free(port); @@ -627,10 +624,10 @@ static int dpdk_offload_port_del(struct dpif_offload *offload_, odp_port_t port_no) { struct dpdk_offload *offload = dpdk_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; int ret = 0; - port = dpif_offload_port_mgr_find_by_odp_port(offload->port_mgr, port_no); + port = dpif_offload_port_mgr_find_by_odp_port(offload_, port_no); if (dpif_offload_enabled() && port) { /* If hardware offload is enabled, we first need to flush (complete) @@ -640,7 +637,7 @@ dpdk_offload_port_del(struct dpif_offload *offload_, odp_port_t port_no) dpdk_offload_flush(offload, port->netdev); } - port = dpif_offload_port_mgr_remove(offload->port_mgr, port_no); + port = dpif_offload_port_mgr_remove(offload_, port_no); if (port) { if (dpif_offload_enabled()) { ret = dpdk_offload_cleanup(offload_, port); @@ -650,40 +647,13 @@ dpdk_offload_port_del(struct dpif_offload *offload_, odp_port_t port_no) return ret; } -static int -dpdk_offload_port_dump_start(const struct dpif_offload *offload_, - void **statep) -{ - struct dpdk_offload *offload = dpdk_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_start(offload->port_mgr, statep); -} - -static int -dpdk_offload_port_dump_next(const struct dpif_offload *offload_, void *state, - struct dpif_offload_port *port) -{ - struct dpdk_offload *offload = dpdk_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_next(offload->port_mgr, state, - port); -} - -static int -dpdk_offload_port_dump_done(const struct dpif_offload *offload_, void *state) -{ - struct dpdk_offload *offload = dpdk_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_done(offload->port_mgr, state); -} - -struct netdev * -dpdk_offload_get_netdev(const struct dpdk_offload *offload, odp_port_t port_no) +static struct netdev * +dpdk_offload_get_netdev__(const struct dpif_offload *offload, + odp_port_t port_no) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - port = dpif_offload_port_mgr_find_by_odp_port(offload->port_mgr, - port_no); + port = dpif_offload_port_mgr_find_by_odp_port(offload, port_no); if (!port) { return NULL; } @@ -691,12 +661,10 @@ dpdk_offload_get_netdev(const struct dpdk_offload *offload, odp_port_t port_no) return port->netdev; } -static struct netdev * -dpdk_offload_get_netdev__(struct dpif_offload *offload_, odp_port_t port_no) +struct netdev * +dpdk_offload_get_netdev(const struct dpdk_offload *offload, odp_port_t port_no) { - struct dpdk_offload *offload = dpdk_offload_cast(offload_); - - return dpdk_offload_get_netdev(offload, port_no); + return dpdk_offload_get_netdev__(&offload->offload, port_no); } static int @@ -706,7 +674,6 @@ dpdk_offload_open(const struct dpif_offload_class *offload_class, struct dpdk_offload *offload = xmalloc(sizeof *offload); dpif_offload_init(&offload->offload, offload_class, dpif); - offload->port_mgr = dpif_offload_port_mgr_init(); offload->once_enable = (struct ovsthread_once) OVSTHREAD_ONCE_INITIALIZER; offload->offload_thread_count = DEFAULT_OFFLOAD_THREAD_COUNT; offload->offload_threads = NULL; @@ -723,9 +690,9 @@ static void dpdk_offload_close(struct dpif_offload *offload_) { struct dpdk_offload *offload = dpdk_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload_) { dpdk_offload_port_del(offload_, port->port_no); } @@ -738,13 +705,12 @@ dpdk_offload_close(struct dpif_offload *offload_) free(offload->offload_threads); } - dpif_offload_port_mgr_uninit(offload->port_mgr); - if (offload->flow_mark_pool) { id_fpool_destroy(offload->flow_mark_pool); } ovsthread_once_destroy(&offload->once_enable); + dpif_offload_destroy(offload_); free(offload); } @@ -756,7 +722,7 @@ dpdk_offload_set_config(struct dpif_offload *offload_, if (smap_get_bool(other_cfg, "hw-offload", false)) { if (ovsthread_once_start(&offload->once_enable)) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; unsigned int offload_thread_count = smap_get_uint( other_cfg, "n-offload-threads", DEFAULT_OFFLOAD_THREAD_COUNT); @@ -774,7 +740,7 @@ dpdk_offload_set_config(struct dpif_offload *offload_, offload->offload_thread_count = offload_thread_count; dpdk_offload_threads_init(offload); - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload_) { dpdk_offload_enable(offload_, port); } @@ -784,16 +750,14 @@ dpdk_offload_set_config(struct dpif_offload *offload_, } static void -dpdk_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, +dpdk_offload_get_debug(const struct dpif_offload *offload, struct ds *ds, struct json *json) { - struct dpdk_offload *offload = dpdk_offload_cast(offload_); - if (json) { struct json *json_ports = json_object_create(); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { struct json *json_port = json_object_create(); json_object_put(json_port, "port_no", @@ -809,9 +773,9 @@ dpdk_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, json_destroy(json_ports); } } else if (ds) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { ds_put_format(ds, " - %s: port_no: %u\n", netdev_get_name(port->netdev), port->port_no); } @@ -836,14 +800,14 @@ static uint64_t dpdk_flow_count(const struct dpif_offload *offload_) { struct dpdk_offload *offload = dpdk_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; uint64_t total = 0; if (!dpif_offload_enabled()) { return 0; } - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload_) { total += dpdk_netdev_flow_count(port->netdev, offload->offload_thread_count); } @@ -854,14 +818,14 @@ dpdk_flow_count(const struct dpif_offload *offload_) static uint64_t dpdk_flow_count_by_thread(struct dpdk_offload *offload, unsigned int tid) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; uint64_t total = 0; if (!dpif_offload_enabled()) { return 0; } - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, &offload->offload) { total += dpdk_netdev_flow_count_by_thread(port->netdev, tid); } @@ -1077,9 +1041,6 @@ struct dpif_offload_class dpif_offload_dpdk_class = { .can_offload = dpdk_can_offload, .port_add = dpdk_offload_port_add, .port_del = dpdk_offload_port_del, - .port_dump_start = dpdk_offload_port_dump_start, - .port_dump_next = dpdk_offload_port_dump_next, - .port_dump_done = dpdk_offload_port_dump_done, .flow_count = dpdk_flow_count, .get_netdev = dpdk_offload_get_netdev__, .netdev_hw_post_process = dpdk_offload_hw_post_process, diff --git a/lib/dpif-offload-dummy.c b/lib/dpif-offload-dummy.c index c2d5b9675b..dec5b7b1ae 100644 --- a/lib/dpif-offload-dummy.c +++ b/lib/dpif-offload-dummy.c @@ -51,7 +51,6 @@ struct dummy_offloaded_flow { struct dummy_offload { struct dpif_offload offload; - struct dpif_offload_port_mgr *port_mgr; struct id_fpool *flow_mark_pool; dpif_offload_flow_unreference_cb *unreference_cb; @@ -60,7 +59,7 @@ struct dummy_offload { }; struct dummy_offload_port { - struct dpif_offload_port_mgr_port pm_port; + struct dpif_offload_port pm_port; struct ovs_mutex port_mutex; /* Protect all below members. */ struct hmap offloaded_flows OVS_GUARDED; @@ -97,7 +96,7 @@ dummy_free_flow_mark(struct dummy_offload *offload, uint32_t flow_mark) } static struct dummy_offload_port * -dummy_offload_port_cast(struct dpif_offload_port_mgr_port *port) +dummy_offload_port_cast(struct dpif_offload_port *port) { return CONTAINER_OF(port, struct dummy_offload_port, pm_port); } @@ -271,7 +270,7 @@ dummy_find_offloaded_flow_and_update(struct dummy_offload_port *port, static void dummy_offload_enable(struct dpif_offload *dpif_offload, - struct dpif_offload_port_mgr_port *port) + struct dpif_offload_port *port) { atomic_store_relaxed(&port->netdev->hw_info.post_process_api_supported, true); @@ -279,7 +278,7 @@ dummy_offload_enable(struct dpif_offload *dpif_offload, } static void -dummy_offload_cleanup(struct dpif_offload_port_mgr_port *port) +dummy_offload_cleanup(struct dpif_offload_port *port) { dpif_offload_set_netdev_offload(port->netdev, NULL); } @@ -338,8 +337,8 @@ dummy_offload_port_add(struct dpif_offload *dpif_offload, hmap_init(&port->offloaded_flows); ovs_mutex_unlock(&port->port_mutex); - if (dpif_offload_port_mgr_add(offload->port_mgr, &port->pm_port, - netdev, port_no, false)) { + if (dpif_offload_port_mgr_add(dpif_offload, &port->pm_port, netdev, + port_no, false)) { if (dpif_offload_enabled()) { dummy_offload_enable(dpif_offload, &port->pm_port); @@ -355,9 +354,9 @@ static int dummy_offload_port_del(struct dpif_offload *dpif_offload, odp_port_t port_no) { struct dummy_offload *offload = dummy_offload_cast(dpif_offload); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - port = dpif_offload_port_mgr_remove(offload->port_mgr, port_no); + port = dpif_offload_port_mgr_remove(dpif_offload, port_no); if (port) { struct dummy_offload_port *dummy_port; @@ -370,40 +369,13 @@ dummy_offload_port_del(struct dpif_offload *dpif_offload, odp_port_t port_no) return 0; } -static int -dummy_offload_port_dump_start(const struct dpif_offload *offload_, - void **statep) -{ - struct dummy_offload *offload = dummy_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_start(offload->port_mgr, statep); -} - -static int -dummy_offload_port_dump_next(const struct dpif_offload *offload_, void *state, - struct dpif_offload_port *port) -{ - struct dummy_offload *offload = dummy_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_next(offload->port_mgr, state, - port); -} - -static int -dummy_offload_port_dump_done(const struct dpif_offload *offload_, void *state) -{ - struct dummy_offload *offload = dummy_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_done(offload->port_mgr, state); -} - static struct netdev * -dummy_offload_get_netdev(struct dpif_offload *dpif_offload, odp_port_t port_no) +dummy_offload_get_netdev(const struct dpif_offload *dpif_offload, + odp_port_t port_no) { - struct dummy_offload *offload = dummy_offload_cast(dpif_offload); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - port = dpif_offload_port_mgr_find_by_odp_port(offload->port_mgr, port_no); + port = dpif_offload_port_mgr_find_by_odp_port(dpif_offload, port_no); if (!port) { return NULL; } @@ -420,7 +392,6 @@ dummy_offload_open(const struct dpif_offload_class *offload_class, offload = xmalloc(sizeof *offload); dpif_offload_init(&offload->offload, offload_class, dpif); - offload->port_mgr = dpif_offload_port_mgr_init(); offload->once_enable = (struct ovsthread_once) OVSTHREAD_ONCE_INITIALIZER; offload->flow_mark_pool = NULL; offload->unreference_cb = NULL; @@ -433,19 +404,19 @@ static void dummy_offload_close(struct dpif_offload *dpif_offload) { struct dummy_offload *offload = dummy_offload_cast(dpif_offload); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; /* The ofproto layer may not call dpif_port_del() for all ports, * especially internal ones, so we need to clean up any remaining ports. */ - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, dpif_offload) { dummy_offload_port_del(dpif_offload, port->port_no); } - dpif_offload_port_mgr_uninit(offload->port_mgr); if (offload->flow_mark_pool) { id_fpool_destroy(offload->flow_mark_pool); } ovsthread_once_destroy(&offload->once_enable); + dpif_offload_destroy(dpif_offload); free(offload); } @@ -457,9 +428,9 @@ dummy_offload_set_config(struct dpif_offload *dpif_offload, if (smap_get_bool(other_cfg, "hw-offload", false)) { if (ovsthread_once_start(&offload->once_enable)) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, dpif_offload) { dummy_offload_enable(dpif_offload, port); } @@ -469,16 +440,14 @@ dummy_offload_set_config(struct dpif_offload *dpif_offload, } static void -dummy_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, +dummy_offload_get_debug(const struct dpif_offload *offload, struct ds *ds, struct json *json) { - struct dummy_offload *offload = dummy_offload_cast(offload_); - if (json) { struct json *json_ports = json_object_create(); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { struct json *json_port = json_object_create(); json_object_put(json_port, "port_no", @@ -494,9 +463,9 @@ dummy_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, json_destroy(json_ports); } } else if (ds) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { ds_put_format(ds, " - %s: port_no: %u\n", netdev_get_name(port->netdev), port->port_no); } @@ -504,17 +473,14 @@ dummy_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, } static int -dummy_offload_get_global_stats(const struct dpif_offload *offload_, +dummy_offload_get_global_stats(const struct dpif_offload *offload, struct netdev_custom_stats *stats) { - struct dummy_offload *offload = dummy_offload_cast(offload_); - /* Add a single counter telling how many ports we are servicing. */ - stats->label = xstrdup(dpif_offload_name(offload_)); + stats->label = xstrdup(dpif_offload_name(offload)); stats->size = 1; stats->counters = xmalloc(sizeof(struct netdev_custom_counter) * 1); - stats->counters[0].value = dpif_offload_port_mgr_port_count( - offload->port_mgr); + stats->counters[0].value = dpif_offload_port_mgr_port_count(offload); ovs_strzcpy(stats->counters[0].name, "Offloaded port count", sizeof stats->counters[0].name); @@ -537,13 +503,12 @@ dummy_offload_log_operation(const char *op, int error, const ovs_u128 *ufid) } static struct dummy_offload_port * -dummy_offload_get_port_by_netdev(const struct dpif_offload *offload_, +dummy_offload_get_port_by_netdev(const struct dpif_offload *offload, struct netdev *netdev) { - struct dummy_offload *offload = dummy_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - port = dpif_offload_port_mgr_find_by_netdev(offload->port_mgr, netdev); + port = dpif_offload_port_mgr_find_by_netdev(offload, netdev); if (!port) { return NULL; } @@ -832,9 +797,6 @@ dummy_netdev_simulate_offload(struct netdev *netdev, struct dp_packet *packet, .can_offload = dummy_can_offload, \ .port_add = dummy_offload_port_add, \ .port_del = dummy_offload_port_del, \ - .port_dump_start = dummy_offload_port_dump_start, \ - .port_dump_next = dummy_offload_port_dump_next, \ - .port_dump_done = dummy_offload_port_dump_done, \ .get_netdev = dummy_offload_get_netdev, \ .netdev_hw_post_process = dummy_offload_hw_post_process, \ .netdev_flow_put = dummy_flow_put, \ diff --git a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h index 44e55f27c7..57d42b5d4d 100644 --- a/lib/dpif-offload-provider.h +++ b/lib/dpif-offload-provider.h @@ -56,6 +56,7 @@ struct dpif_offload_provider_collection { struct dpif_offload { const struct dpif_offload_class *class; struct ovs_list dpif_list_node; + struct dpif_offload_port_mgr *ports; char *name; }; @@ -162,30 +163,6 @@ struct dpif_offload_class { void (*port_set_config)(struct dpif_offload *, odp_port_t port_no, const struct smap *cfg); - /* Attempts to begin dumping the ports in a dpif_offload. On success, - * returns 0 and initializes '*statep' with any data needed for iteration. - * On failure, returns a positive errno value. */ - int (*port_dump_start)(const struct dpif_offload *, void **statep); - - /* Attempts to retrieve another port from 'dpif_offload' for 'state', which - * was initialized by a successful call to the 'port_dump_start' function - * for 'dpif_offload'. On success, stores a new dpif_offload_port into - * 'port' and returns 0. Returns EOF if the end of the port table has been - * reached, or a positive errno value on error. This function will not be - * called again once it returns nonzero once for a given iteration (but - * the 'port_dump_done' function will be called afterward). - * - * The dpif provider retains ownership of the data stored in 'port'. It - * must remain valid until at least the next call to 'port_dump_next' or - * 'port_dump_done' for 'state'. */ - int (*port_dump_next)(const struct dpif_offload *, void *state, - struct dpif_offload_port *); - - /* Releases resources from 'dpif_offload' for 'state', which was - * initialized by a successful call to the 'port_dump_start' function for - * 'dpif_offload'. */ - int (*port_dump_done)(const struct dpif_offload *dpif, void *state); - /* 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 *); @@ -274,8 +251,8 @@ struct dpif_offload_class { * NOT incremented. Callers needing to hold a reference must call * netdev_ref() on the returned netdev. Returns NULL if port_no is * not found. */ - struct netdev *(*get_netdev)(struct dpif_offload *, odp_port_t port_no); - + struct netdev *(*get_netdev)(const struct dpif_offload *, + odp_port_t port_no); /* These APIs operate directly on the provided netdev for performance * reasons. They are intended for use in fast path processing and should @@ -336,7 +313,7 @@ extern struct dpif_offload_class dpif_offload_dpdk_class; extern struct dpif_offload_class dpif_offload_tc_class; -/* Structure used by the common dpif port management library functions. */ +/* Structures used by the common dpif port management library functions. */ struct dpif_offload_port_mgr { struct ovs_mutex cmap_mod_lock; @@ -345,7 +322,7 @@ struct dpif_offload_port_mgr { struct cmap ifindex_to_port; }; -struct dpif_offload_port_mgr_port { +struct dpif_offload_port { struct cmap_node odp_port_node; struct cmap_node netdev_node; struct cmap_node ifindex_node; @@ -357,30 +334,28 @@ struct dpif_offload_port_mgr_port { /* Global dpif port management library functions. */ struct dpif_offload_port_mgr *dpif_offload_port_mgr_init(void); -bool dpif_offload_port_mgr_add(struct dpif_offload_port_mgr *, - struct dpif_offload_port_mgr_port *, +void dpif_offload_port_mgr_destroy(struct dpif_offload *); +bool dpif_offload_port_mgr_add(struct dpif_offload *, + struct dpif_offload_port *, struct netdev *netdev, odp_port_t, bool need_ifindex); -struct dpif_offload_port_mgr_port *dpif_offload_port_mgr_remove( - struct dpif_offload_port_mgr *, odp_port_t); -void dpif_offload_port_mgr_uninit(struct dpif_offload_port_mgr *); -size_t dpif_offload_port_mgr_port_count(struct dpif_offload_port_mgr *); -struct dpif_offload_port_mgr_port *dpif_offload_port_mgr_find_by_ifindex( - struct dpif_offload_port_mgr *, int ifindex); -struct dpif_offload_port_mgr_port *dpif_offload_port_mgr_find_by_netdev( - struct dpif_offload_port_mgr *, struct netdev *); -struct dpif_offload_port_mgr_port *dpif_offload_port_mgr_find_by_odp_port( - struct dpif_offload_port_mgr *, odp_port_t); -int dpif_offload_port_mgr_port_dump_start(struct dpif_offload_port_mgr *, +struct dpif_offload_port *dpif_offload_port_mgr_remove(struct dpif_offload *, + odp_port_t); +size_t dpif_offload_port_mgr_port_count(const struct dpif_offload *); +struct dpif_offload_port *dpif_offload_port_mgr_find_by_ifindex( + const struct dpif_offload *, int ifindex); +struct dpif_offload_port *dpif_offload_port_mgr_find_by_netdev( + const struct dpif_offload *, struct netdev *); +struct dpif_offload_port *dpif_offload_port_mgr_find_by_odp_port( + const struct dpif_offload *, odp_port_t); +int dpif_offload_port_mgr_port_dump_start(const struct dpif_offload *, void **statep); -int dpif_offload_port_mgr_port_dump_next(struct dpif_offload_port_mgr *, - void *state, - struct dpif_offload_port *); -int dpif_offload_port_mgr_port_dump_done(struct dpif_offload_port_mgr *, - void *state); - -#define DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH(PORT, PORT_MGR) \ - CMAP_FOR_EACH (PORT, odp_port_node, &(PORT_MGR)->odp_port_to_port) +int dpif_offload_port_mgr_port_dump_next(void *state, + struct dpif_offload_port_dump_port *); +int dpif_offload_port_mgr_port_dump_done(void *state); + +#define DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH(PORT, OFFLOAD) \ + CMAP_FOR_EACH (PORT, odp_port_node, &(OFFLOAD)->ports->odp_port_to_port) /* Global functions, called by the dpif layer or offload providers. */ void dpif_offload_module_init(void); diff --git a/lib/dpif-offload-tc-netdev.c b/lib/dpif-offload-tc-netdev.c index 11a72118a3..a2f4ab8b5d 100644 --- a/lib/dpif-offload-tc-netdev.c +++ b/lib/dpif-offload-tc-netdev.c @@ -668,8 +668,9 @@ parse_flower_rewrite_to_netlink_action(struct ofpbuf *buf, } } -static void parse_tc_flower_geneve_opts(struct tc_action *action, - struct ofpbuf *buf) +static void +parse_tc_flower_geneve_opts(struct tc_action *action, + struct ofpbuf *buf) { int tun_opt_len = action->encap.data.present.len; size_t geneve_off; diff --git a/lib/dpif-offload-tc.c b/lib/dpif-offload-tc.c index fca106584a..58d7628a3b 100644 --- a/lib/dpif-offload-tc.c +++ b/lib/dpif-offload-tc.c @@ -35,7 +35,6 @@ VLOG_DEFINE_THIS_MODULE(dpif_offload_tc); /* dpif offload interface for the tc implementation. */ struct tc_offload { struct dpif_offload offload; - struct dpif_offload_port_mgr *port_mgr; /* Configuration specific variables. */ struct ovsthread_once once_enable; /* Track first-time enablement. */ @@ -75,7 +74,7 @@ tc_offload_cast(const struct dpif_offload *offload) static int tc_offload_enable(struct dpif_offload *dpif_offload, - struct dpif_offload_port_mgr_port *port) + struct dpif_offload_port *port) { int ret = tc_netdev_init(port->netdev); @@ -91,7 +90,7 @@ tc_offload_enable(struct dpif_offload *dpif_offload, static int tc_offload_cleanup(struct dpif_offload *dpif_offload OVS_UNUSED, - struct dpif_offload_port_mgr_port *port) + struct dpif_offload_port *port) { dpif_offload_set_netdev_offload(port->netdev, NULL); return 0; @@ -101,11 +100,9 @@ static int tc_port_add(struct dpif_offload *dpif_offload, struct netdev *netdev, odp_port_t port_no) { - struct dpif_offload_port_mgr_port *port = xmalloc(sizeof *port); - struct tc_offload *offload = tc_offload_cast(dpif_offload); + struct dpif_offload_port *port = xmalloc(sizeof *port); - if (dpif_offload_port_mgr_add(offload->port_mgr, port, netdev, port_no, - true)) { + if (dpif_offload_port_mgr_add(dpif_offload, port, netdev, port_no, true)) { if (dpif_offload_enabled()) { return tc_offload_enable(dpif_offload, port); } @@ -117,7 +114,7 @@ tc_port_add(struct dpif_offload *dpif_offload, struct netdev *netdev, } static void -tc_free_port(struct dpif_offload_port_mgr_port *port) +tc_free_port(struct dpif_offload_port *port) { netdev_close(port->netdev); free(port); @@ -126,11 +123,10 @@ tc_free_port(struct dpif_offload_port_mgr_port *port) static int tc_port_del(struct dpif_offload *dpif_offload, odp_port_t port_no) { - struct tc_offload *offload = tc_offload_cast(dpif_offload); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; int ret = 0; - port = dpif_offload_port_mgr_remove(offload->port_mgr, port_no); + port = dpif_offload_port_mgr_remove(dpif_offload, port_no); if (port) { if (dpif_offload_enabled()) { ret = tc_offload_cleanup(dpif_offload, port); @@ -140,39 +136,12 @@ tc_port_del(struct dpif_offload *dpif_offload, odp_port_t port_no) return ret; } -static int -tc_port_dump_start(const struct dpif_offload *offload_, void **statep) -{ - struct tc_offload *offload = tc_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_start(offload->port_mgr, statep); -} - -static int -tc_port_dump_next(const struct dpif_offload *offload_, void *state, - struct dpif_offload_port *port) -{ - struct tc_offload *offload = tc_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_next(offload->port_mgr, state, - port); -} - -static int -tc_port_dump_done(const struct dpif_offload *offload_, void *state) -{ - struct tc_offload *offload = tc_offload_cast(offload_); - - return dpif_offload_port_mgr_port_dump_done(offload->port_mgr, state); -} - static struct netdev * -tc_get_netdev(struct dpif_offload *dpif_offload, odp_port_t port_no) +tc_get_netdev(const struct dpif_offload *dpif_offload, odp_port_t port_no) { - struct tc_offload *offload = tc_offload_cast(dpif_offload); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - port = dpif_offload_port_mgr_find_by_odp_port(offload->port_mgr, port_no); + port = dpif_offload_port_mgr_find_by_odp_port(dpif_offload, port_no); if (!port) { return NULL; } @@ -187,7 +156,6 @@ tc_offload_open(const struct dpif_offload_class *offload_class, struct tc_offload *offload = xmalloc(sizeof *offload); dpif_offload_init(&offload->offload, offload_class, dpif); - offload->port_mgr = dpif_offload_port_mgr_init(); offload->once_enable = (struct ovsthread_once) OVSTHREAD_ONCE_INITIALIZER; offload->recirc_id_shared = !!(dpif_get_features(dpif) & OVS_DP_F_TC_RECIRC_SHARING); @@ -205,14 +173,14 @@ static void tc_offload_close(struct dpif_offload *dpif_offload) { struct tc_offload *offload = tc_offload_cast(dpif_offload); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, dpif_offload) { tc_port_del(dpif_offload, port->port_no); } - dpif_offload_port_mgr_uninit(offload->port_mgr); ovsthread_once_destroy(&offload->once_enable); + dpif_offload_destroy(dpif_offload); free(offload); } @@ -224,12 +192,12 @@ tc_offload_set_config(struct dpif_offload *offload_, if (smap_get_bool(other_cfg, "hw-offload", false)) { if (ovsthread_once_start(&offload->once_enable)) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; tc_set_policy(smap_get_def(other_cfg, "tc-policy", TC_POLICY_DEFAULT)); - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload_) { tc_offload_enable(offload_, port); } @@ -239,16 +207,14 @@ tc_offload_set_config(struct dpif_offload *offload_, } static void -tc_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, +tc_offload_get_debug(const struct dpif_offload *offload, struct ds *ds, struct json *json) { - struct tc_offload *offload = tc_offload_cast(offload_); - if (json) { struct json *json_ports = json_object_create(); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { struct json *json_port = json_object_create(); json_object_put(json_port, "port_no", @@ -266,9 +232,9 @@ tc_offload_get_debug(const struct dpif_offload *offload_, struct ds *ds, json_destroy(json_ports); } } else if (ds) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { ds_put_format(ds, " - %s: port_no: %u, ifindex: %d\n", netdev_get_name(port->netdev), port->port_no, port->ifindex); @@ -290,13 +256,12 @@ tc_can_offload(struct dpif_offload *dpif_offload OVS_UNUSED, } static int -tc_flow_flush(const struct dpif_offload *offload_) +tc_flow_flush(const struct dpif_offload *offload) { - struct tc_offload *offload = tc_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; int error = 0; - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { int rc = tc_netdev_flow_flush(port->netdev); if (rc && !error) { @@ -320,22 +285,21 @@ tc_flow_dump_thread_cast( } static struct dpif_offload_flow_dump * -tc_flow_dump_create(const struct dpif_offload *offload_, bool terse) +tc_flow_dump_create(const struct dpif_offload *offload, bool terse) { - struct tc_offload *offload = tc_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; size_t added_port_count = 0; struct tc_flow_dump *dump; size_t port_count; - port_count = dpif_offload_port_mgr_port_count(offload->port_mgr); + port_count = dpif_offload_port_mgr_port_count(offload); dump = xmalloc(sizeof *dump + (port_count * sizeof(struct netdev_tc_flow_dump))); - dpif_offload_flow_dump_init(&dump->dump, offload_, terse); + dpif_offload_flow_dump_init(&dump->dump, offload, terse); - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload) { if (added_port_count >= port_count) { break; } @@ -526,7 +490,7 @@ tc_parse_flow_put(struct tc_offload *offload_tc, struct dpif *dpif, struct dpif_flow_put *put) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; const struct nlattr *nla; struct tc_offload_info info; struct match match; @@ -548,7 +512,7 @@ tc_parse_flow_put(struct tc_offload *offload_tc, struct dpif *dpif, } in_port = match.flow.in_port.odp_port; - port = dpif_offload_port_mgr_find_by_odp_port(offload_tc->port_mgr, + port = dpif_offload_port_mgr_find_by_odp_port(&offload_tc->offload, in_port); if (!port) { return EOPNOTSUPP; @@ -557,12 +521,12 @@ tc_parse_flow_put(struct tc_offload *offload_tc, struct dpif *dpif, /* Check the output port for a tunnel. */ NL_ATTR_FOR_EACH (nla, left, put->actions, put->actions_len) { if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) { - struct dpif_offload_port_mgr_port *mgr_port; + struct dpif_offload_port *mgr_port; odp_port_t out_port; out_port = nl_attr_get_odp_port(nla); mgr_port = dpif_offload_port_mgr_find_by_odp_port( - offload_tc->port_mgr, out_port); + &offload_tc->offload, out_port); if (!mgr_port) { err = EOPNOTSUPP; @@ -650,8 +614,8 @@ out: static int tc_parse_flow_get(struct tc_offload *offload_tc, struct dpif_flow_get *get) { - struct dpif_offload_port_mgr_port *port; struct dpif_flow *dpif_flow = get->flow; + struct dpif_offload_port *port; struct odputil_keybuf maskbuf; struct odputil_keybuf keybuf; struct odputil_keybuf actbuf; @@ -666,7 +630,7 @@ tc_parse_flow_get(struct tc_offload *offload_tc, struct dpif_flow_get *get) ofpbuf_use_stack(&buf, &act_buf, sizeof act_buf); - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, offload_tc->port_mgr) { + DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, &offload_tc->offload) { if (!tc_netdev_flow_get(port->netdev, &match, &actions, get->ufid, &stats, &attrs, &buf)) { err = 0; @@ -751,12 +715,11 @@ tc_operate(struct dpif *dpif, const struct dpif_offload *offload_, } odp_port_t -tc_get_port_id_by_ifindex(const struct dpif_offload *offload_, int ifindex) +tc_get_port_id_by_ifindex(const struct dpif_offload *offload, int ifindex) { - struct tc_offload *offload = tc_offload_cast(offload_); - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port *port; - port = dpif_offload_port_mgr_find_by_ifindex(offload->port_mgr, ifindex); + port = dpif_offload_port_mgr_find_by_ifindex(offload, ifindex); if (port) { return port->port_no; } @@ -774,9 +737,6 @@ struct dpif_offload_class dpif_offload_tc_class = { .can_offload = tc_can_offload, .port_add = tc_port_add, .port_del = tc_port_del, - .port_dump_start = tc_port_dump_start, - .port_dump_next = tc_port_dump_next, - .port_dump_done = tc_port_dump_done, .flow_flush = tc_flow_flush, .flow_dump_create = tc_flow_dump_create, .flow_dump_next = tc_flow_dump_next, diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c index 6125675b39..b431ce3d0a 100644 --- a/lib/dpif-offload.c +++ b/lib/dpif-offload.c @@ -159,9 +159,6 @@ dpif_offload_module_init(void) && base_dpif_offload_classes[i]->can_offload && base_dpif_offload_classes[i]->port_add && base_dpif_offload_classes[i]->port_del - && base_dpif_offload_classes[i]->port_dump_start - && base_dpif_offload_classes[i]->port_dump_next - && base_dpif_offload_classes[i]->port_dump_done && base_dpif_offload_classes[i]->get_netdev); ovs_assert((base_dpif_offload_classes[i]->flow_dump_create && @@ -360,11 +357,8 @@ provider_collection_free_rcu( /* We need to use the safe variant here as we removed the entry, and the * close API will free() it. */ LIST_FOR_EACH_SAFE (offload_entry, dpif_list_node, &collection->list) { - char *name = offload_entry->name; - ovs_list_remove(&offload_entry->dpif_list_node); offload_entry->class->close(offload_entry); - free(name); } /* Free remaining resources. */ @@ -434,6 +428,16 @@ dpif_offload_init(struct dpif_offload *offload, offload->class = class; offload->name = xasprintf("%s[%s]", class->type, dpif_name(dpif)); + offload->ports = dpif_offload_port_mgr_init(); +} + +void +dpif_offload_destroy(struct dpif_offload *offload) +{ + ovs_assert(offload); + + dpif_offload_port_mgr_destroy(offload); + free(offload->name); } const char * @@ -460,9 +464,9 @@ dpif_offload_get_debug(const struct dpif_offload *offload, struct ds *ds, return true; } -int dpif_offload_stats_get(struct dpif *dpif, - struct netdev_custom_stats **stats_, - size_t *n_stats) +int +dpif_offload_stats_get(struct dpif *dpif, struct netdev_custom_stats **stats_, + size_t *n_stats) { struct dpif_offload_provider_collection *collection; struct netdev_custom_stats *stats; @@ -1206,27 +1210,23 @@ dpif_offload_port_dump_start(struct dpif_offload_port_dump *dump, if (!dpif_offload_get_next_offload_for_dump(dump)) { dump->error = EOF; } else { - dump->error = dump->offload->class->port_dump_start(dump->offload, + dump->error = dpif_offload_port_mgr_port_dump_start(dump->offload, &dump->state); } } bool dpif_offload_port_dump_next(struct dpif_offload_port_dump *dump, - struct dpif_offload_port *port) + struct dpif_offload_port_dump_port *port) { - const struct dpif_offload *offload = dump->offload; - while (true) { - if (dump->error) { break; } - dump->error = offload->class->port_dump_next(offload, dump->state, - port); + dump->error = dpif_offload_port_mgr_port_dump_next(dump->state, port); if (dump->error) { - offload->class->port_dump_done(offload, dump->state); + dpif_offload_port_mgr_port_dump_done(dump->state); if (dump->error != EOF) { /* If the error is not EOF, we stop dumping ports from all @@ -1235,9 +1235,8 @@ dpif_offload_port_dump_next(struct dpif_offload_port_dump *dump, } if (dpif_offload_get_next_offload_for_dump(dump)) { - offload = dump->offload; - dump->error = offload->class->port_dump_start(offload, - &dump->state); + dump->error = dpif_offload_port_mgr_port_dump_start( + dump->offload, &dump->state); continue; } } @@ -1251,8 +1250,7 @@ int dpif_offload_port_dump_done(struct dpif_offload_port_dump *dump) { if (!dump->error && dump->offload) { - dump->error = dump->offload->class->port_dump_done(dump->offload, - dump->state); + dump->error = dpif_offload_port_mgr_port_dump_done(dump->state); } return dump->error == EOF ? 0 : dump->error; } @@ -1296,8 +1294,8 @@ bool dpif_offload_netdevs_out_of_resources(struct dpif *dpif) { struct dpif_offload_provider_collection *collection; + struct dpif_offload_port_dump_port port; struct dpif_offload_port_dump dump; - struct dpif_offload_port port; bool oor = false; collection = dpif_get_offload_provider_collection(dpif); @@ -1575,34 +1573,42 @@ dpif_offload_port_mgr_init(void) } void -dpif_offload_port_mgr_uninit(struct dpif_offload_port_mgr *mgr) +dpif_offload_port_mgr_destroy(struct dpif_offload *offload) { - if (!mgr) { + struct dpif_offload_port_mgr *ports; + + if (!offload || !offload->ports) { return; } - ovs_assert(cmap_count(&mgr->odp_port_to_port) == 0); - ovs_assert(cmap_count(&mgr->netdev_to_port) == 0); - ovs_assert(cmap_count(&mgr->ifindex_to_port) == 0); + ports = offload->ports; + offload->ports = NULL; + + ovs_assert(cmap_count(&ports->odp_port_to_port) == 0); + ovs_assert(cmap_count(&ports->netdev_to_port) == 0); + ovs_assert(cmap_count(&ports->ifindex_to_port) == 0); - cmap_destroy(&mgr->odp_port_to_port); - cmap_destroy(&mgr->netdev_to_port); - cmap_destroy(&mgr->ifindex_to_port); - free(mgr); + cmap_destroy(&ports->odp_port_to_port); + cmap_destroy(&ports->netdev_to_port); + cmap_destroy(&ports->ifindex_to_port); + free(ports); } -struct dpif_offload_port_mgr_port * -dpif_offload_port_mgr_find_by_ifindex(struct dpif_offload_port_mgr *mgr, +struct dpif_offload_port * +dpif_offload_port_mgr_find_by_ifindex(const struct dpif_offload *offload, int ifindex) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port_mgr *ports = offload->ports; + struct dpif_offload_port *port; + + ovs_assert(ports); if (ifindex < 0) { return NULL; } CMAP_FOR_EACH_WITH_HASH (port, ifindex_node, hash_int(ifindex, 0), - &mgr->ifindex_to_port) { + &ports->ifindex_to_port) { if (port->ifindex == ifindex) { return port; } @@ -1610,18 +1616,21 @@ dpif_offload_port_mgr_find_by_ifindex(struct dpif_offload_port_mgr *mgr, return NULL; } -struct dpif_offload_port_mgr_port * -dpif_offload_port_mgr_find_by_netdev(struct dpif_offload_port_mgr *mgr, +struct dpif_offload_port * +dpif_offload_port_mgr_find_by_netdev(const struct dpif_offload *offload, struct netdev *netdev) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port_mgr *ports = offload->ports; + struct dpif_offload_port *port; + + ovs_assert(ports); if (!netdev) { return NULL; } CMAP_FOR_EACH_WITH_HASH (port, netdev_node, hash_pointer(netdev, 0), - &mgr->netdev_to_port) { + &ports->netdev_to_port) { if (port->netdev == netdev) { return port; } @@ -1629,15 +1638,18 @@ dpif_offload_port_mgr_find_by_netdev(struct dpif_offload_port_mgr *mgr, return NULL; } -struct dpif_offload_port_mgr_port * -dpif_offload_port_mgr_find_by_odp_port(struct dpif_offload_port_mgr *mgr, +struct dpif_offload_port * +dpif_offload_port_mgr_find_by_odp_port(const struct dpif_offload *offload, odp_port_t port_no) { - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port_mgr *ports = offload->ports; + struct dpif_offload_port *port; + + ovs_assert(ports); CMAP_FOR_EACH_WITH_HASH (port, odp_port_node, hash_int(odp_to_u32(port_no), 0), - &mgr->odp_port_to_port) { + &ports->odp_port_to_port) { if (port->port_no == port_no) { return port; } @@ -1645,145 +1657,129 @@ dpif_offload_port_mgr_find_by_odp_port(struct dpif_offload_port_mgr *mgr, return NULL; } -struct dpif_offload_port_mgr_port * -dpif_offload_port_mgr_remove(struct dpif_offload_port_mgr *mgr, - odp_port_t port_no) +struct dpif_offload_port * +dpif_offload_port_mgr_remove(struct dpif_offload *offload, odp_port_t port_no) { /* Note that it is the caller's responsibility to release the netdev * after port removal. This should probably be done through the * ovsrcu_postpone() API. */ - struct dpif_offload_port_mgr_port *port; + struct dpif_offload_port_mgr *ports = offload->ports; + struct dpif_offload_port *port; - ovs_mutex_lock(&mgr->cmap_mod_lock); + ovs_assert(ports); - port = dpif_offload_port_mgr_find_by_odp_port(mgr, port_no); + ovs_mutex_lock(&ports->cmap_mod_lock); + + port = dpif_offload_port_mgr_find_by_odp_port(offload, port_no); if (port) { - cmap_remove(&mgr->odp_port_to_port, &port->odp_port_node, + cmap_remove(&ports->odp_port_to_port, &port->odp_port_node, hash_int(odp_to_u32(port_no), 0)); - cmap_remove(&mgr->netdev_to_port, &port->netdev_node, + cmap_remove(&ports->netdev_to_port, &port->netdev_node, hash_pointer(port->netdev, 0)); if (port->ifindex >= 0) { - cmap_remove(&mgr->ifindex_to_port, &port->ifindex_node, + cmap_remove(&ports->ifindex_to_port, &port->ifindex_node, hash_int(port->ifindex, 0)); } } - ovs_mutex_unlock(&mgr->cmap_mod_lock); + ovs_mutex_unlock(&ports->cmap_mod_lock); return port; } bool -dpif_offload_port_mgr_add(struct dpif_offload_port_mgr *mgr, - struct dpif_offload_port_mgr_port *port, +dpif_offload_port_mgr_add(struct dpif_offload *offload, + struct dpif_offload_port *port, struct netdev *netdev, odp_port_t port_no, bool need_ifindex) { + struct dpif_offload_port_mgr *ports; + /* Note that this function takes a reference to the passed-in netdev. * However, on port removal it is the caller's responsibility to * release this reference. */ - ovs_assert(netdev); + ovs_assert(offload->ports && netdev); + ports = offload->ports; memset(port, 0, sizeof *port); port->port_no = port_no; port->ifindex = need_ifindex ? netdev_get_ifindex(netdev) : -1; - ovs_mutex_lock(&mgr->cmap_mod_lock); + ovs_mutex_lock(&ports->cmap_mod_lock); - if (dpif_offload_port_mgr_find_by_odp_port(mgr, port_no) - || dpif_offload_port_mgr_find_by_ifindex(mgr, port->ifindex) - || dpif_offload_port_mgr_find_by_netdev(mgr, netdev)) { + if (dpif_offload_port_mgr_find_by_odp_port(offload, port_no) + || dpif_offload_port_mgr_find_by_ifindex(offload, port->ifindex) + || dpif_offload_port_mgr_find_by_netdev(offload, netdev)) { - ovs_mutex_unlock(&mgr->cmap_mod_lock); + ovs_mutex_unlock(&ports->cmap_mod_lock); return false; } port->netdev = netdev_ref(netdev); - cmap_insert(&mgr->odp_port_to_port, &port->odp_port_node, + cmap_insert(&ports->odp_port_to_port, &port->odp_port_node, hash_int(odp_to_u32(port_no), 0)); - cmap_insert(&mgr->netdev_to_port, &port->netdev_node, + cmap_insert(&ports->netdev_to_port, &port->netdev_node, hash_pointer(netdev, 0)); if (port->ifindex >= 0) { - cmap_insert(&mgr->ifindex_to_port, &port->ifindex_node, + cmap_insert(&ports->ifindex_to_port, &port->ifindex_node, hash_int(port->ifindex, 0)); } - ovs_mutex_unlock(&mgr->cmap_mod_lock); + ovs_mutex_unlock(&ports->cmap_mod_lock); return true; } size_t -dpif_offload_port_mgr_port_count(struct dpif_offload_port_mgr *mgr) +dpif_offload_port_mgr_port_count(const struct dpif_offload *offload) { - return cmap_count(&mgr->odp_port_to_port); + ovs_assert(offload && offload->ports); + + return cmap_count(&offload->ports->odp_port_to_port); } struct dpif_offload_port_mgr_dump_state { struct netdev *last_netdev; - size_t port_index; - size_t port_count; - odp_port_t ports[]; + struct cmap_cursor cursor; }; int -dpif_offload_port_mgr_port_dump_start(struct dpif_offload_port_mgr *mgr, +dpif_offload_port_mgr_port_dump_start(const struct dpif_offload *offload, void **statep) { - size_t port_count = dpif_offload_port_mgr_port_count(mgr); struct dpif_offload_port_mgr_dump_state *state; - struct dpif_offload_port_mgr_port *port; - size_t added_port_count = 0; - - state = xmalloc(sizeof *state + (port_count * sizeof(odp_port_t))); - - DPIF_OFFLOAD_PORT_MGR_PORT_FOR_EACH (port, mgr) { - if (added_port_count >= port_count) { - break; - } - state->ports[added_port_count] = port->port_no; - added_port_count++; - } - state->port_count = added_port_count; - state->port_index = 0; + state = xmalloc(sizeof *state); + state->cursor = cmap_cursor_start(&offload->ports->odp_port_to_port); state->last_netdev = NULL; *statep = state; return 0; } -int dpif_offload_port_mgr_port_dump_next(struct dpif_offload_port_mgr *mgr, - void *state_, - struct dpif_offload_port *port) +int +dpif_offload_port_mgr_port_dump_next(void *state_, + struct dpif_offload_port_dump_port *port) { struct dpif_offload_port_mgr_dump_state *state = state_; - struct dpif_offload_port_mgr_port *mgr_port; - - while (state->port_index < state->port_count) { - - mgr_port = dpif_offload_port_mgr_find_by_odp_port( - mgr, state->ports[state->port_index++]); + struct dpif_offload_port *mgr_port; - if (mgr_port) { - port->netdev = netdev_ref(mgr_port->netdev); - port->port_no = mgr_port->port_no; - - netdev_close(state->last_netdev); - state->last_netdev = port->netdev; - return 0; - } + CMAP_CURSOR_FOR_EACH_CONTINUE (mgr_port, odp_port_node, &state->cursor) { + port->netdev = netdev_ref(mgr_port->netdev); + netdev_close(state->last_netdev); + state->last_netdev = port->netdev; + port->port_no = mgr_port->port_no; + return 0; } return EOF; } int -dpif_offload_port_mgr_port_dump_done( - struct dpif_offload_port_mgr *mgr OVS_UNUSED, void *state_) +dpif_offload_port_mgr_port_dump_done(void *state_) { struct dpif_offload_port_mgr_dump_state *state = state_; diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h index c4e6284a26..fedcc80bc5 100644 --- a/lib/dpif-offload.h +++ b/lib/dpif-offload.h @@ -58,6 +58,7 @@ bool dpif_offload_rebalance_policy_enabled(void); /* Per dpif specific functions. */ void dpif_offload_init(struct dpif_offload *, const struct dpif_offload_class *, struct dpif *); +void dpif_offload_destroy(struct dpif_offload *); int dpif_attach_offload_providers(struct dpif *); void dpif_detach_offload_providers(struct dpif *); const char *dpif_offload_name(const struct dpif_offload *); @@ -102,7 +103,7 @@ enum dpif_offload_impl_type dpif_offload_get_impl_type_by_class( : (dpif_offload_dump_done(DUMP), false)); \ ) -struct dpif_offload_port { +struct dpif_offload_port_dump_port { struct netdev *netdev; odp_port_t port_no; }; @@ -117,7 +118,7 @@ struct dpif_offload_port_dump { void dpif_offload_port_dump_start(struct dpif_offload_port_dump *, const struct dpif *); bool dpif_offload_port_dump_next(struct dpif_offload_port_dump *, - struct dpif_offload_port *); + struct dpif_offload_port_dump_port *); int dpif_offload_port_dump_done(struct dpif_offload_port_dump *); /* Iterates through each DPIF_OFFLOAD_PORT in DPIF, using DUMP as state. -- 2.52.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
