The statistics were stored as allocated object for each individual statistic and linked together via list. Store them in vector instead which allows us to avoid a lot of small allocations and free right after using the statistic.
The same applies to the buffered packets, use vector instead of moving around single allocated objects. This should reduce the fragmentation. Signed-off-by: Ales Musil <amu...@redhat.com> --- v3: Rebase on top of current main. v2: Rebase on top of current main. --- controller/mac-cache.c | 190 +++++++++++++++++------------------------ controller/mac-cache.h | 41 +++++---- controller/pinctrl.c | 13 ++- controller/statctrl.c | 53 ++++++------ 4 files changed, 139 insertions(+), 158 deletions(-) diff --git a/controller/mac-cache.c b/controller/mac-cache.c index 18236c440..304304bee 100644 --- a/controller/mac-cache.c +++ b/controller/mac-cache.c @@ -18,6 +18,7 @@ #include "lflow.h" #include "lib/mac-binding-index.h" +#include "lib/vec.h" #include "local_data.h" #include "lport.h" #include "mac-cache.h" @@ -339,43 +340,30 @@ fdbs_clear(struct hmap *map) } } -struct mac_cache_stats { - struct ovs_list list_node; - - int64_t idle_age_ms; - - union { - /* Common data to identify MAC binding. */ - struct mac_binding_data mb; - /* Common data to identify FDB. */ - struct fdb_data fdb; - } data; -}; - /* MAC binding stat processing. */ void -mac_binding_stats_process_flow_stats(struct ovs_list *stats_list, +mac_binding_stats_process_flow_stats(struct vector *stats_vec, struct ofputil_flow_stats *ofp_stats) { - struct mac_cache_stats *stats = xmalloc(sizeof *stats); - - stats->idle_age_ms = ofp_stats->idle_age * 1000; - stats->data.mb = (struct mac_binding_data) { - .cookie = ntohll(ofp_stats->cookie), - /* The port_key must be zero to match mac_binding_data_from_sbrec. */ - .port_key = 0, - .dp_key = ntohll(ofp_stats->match.flow.metadata), - .mac = ofp_stats->match.flow.dl_src + struct mac_cache_stats stats = (struct mac_cache_stats) { + .idle_age_ms = ofp_stats->idle_age * 1000, + .data.mb = (struct mac_binding_data) { + .cookie = ntohll(ofp_stats->cookie), + /* The port_key must be zero to match + * mac_binding_data_from_sbrec. */ + .port_key = 0, + .dp_key = ntohll(ofp_stats->match.flow.metadata), + .mac = ofp_stats->match.flow.dl_src + }, }; if (ofp_stats->match.flow.dl_type == htons(ETH_TYPE_IP) || ofp_stats->match.flow.dl_type == htons(ETH_TYPE_ARP)) { - stats->data.mb.ip = in6_addr_mapped_ipv4(ofp_stats->match.flow.nw_src); + stats.data.mb.ip = in6_addr_mapped_ipv4(ofp_stats->match.flow.nw_src); } else { - stats->data.mb.ip = ofp_stats->match.flow.ipv6_src; + stats.data.mb.ip = ofp_stats->match.flow.ipv6_src; } - - ovs_list_push_back(stats_list, &stats->list_node); + vector_push(stats_vec, &stats); } static void @@ -409,19 +397,18 @@ void mac_binding_stats_run( struct rconn *swconn OVS_UNUSED, struct ovsdb_idl_index *sbrec_port_binding_by_name OVS_UNUSED, - struct ovs_list *stats_list, uint64_t *req_delay, void *data) + struct vector *stats_vec, uint64_t *req_delay, void *data) { struct mac_cache_data *cache_data = data; long long timewall_now = time_wall_msec(); struct mac_cache_stats *stats; - LIST_FOR_EACH_POP (stats, list_node, stats_list) { + VECTOR_FOR_EACH_PTR (stats_vec, stats) { struct mac_binding *mb = mac_binding_find(&cache_data->mac_bindings, &stats->data.mb); if (!mb) { mac_binding_update_log("Not found in the cache:", &stats->data.mb, false, NULL, 0, 0); - free(stats); continue; } @@ -449,7 +436,6 @@ mac_binding_stats_run( threshold, stats->idle_age_ms, since_updated_ms); } - free(stats); } mac_cache_update_req_delay(&cache_data->thresholds, req_delay); @@ -460,19 +446,18 @@ mac_binding_stats_run( /* FDB stat processing. */ void -fdb_stats_process_flow_stats(struct ovs_list *stats_list, +fdb_stats_process_flow_stats(struct vector *stats_vec, struct ofputil_flow_stats *ofp_stats) { - struct mac_cache_stats *stats = xmalloc(sizeof *stats); - - stats->idle_age_ms = ofp_stats->idle_age * 1000; - stats->data.fdb = (struct fdb_data) { + struct mac_cache_stats stats = (struct mac_cache_stats) { + .idle_age_ms = ofp_stats->idle_age * 1000, + .data.fdb = (struct fdb_data) { .port_key = ofp_stats->match.flow.regs[MFF_LOG_INPORT - MFF_REG0], .dp_key = ntohll(ofp_stats->match.flow.metadata), .mac = ofp_stats->match.flow.dl_src + }, }; - - ovs_list_push_back(stats_list, &stats->list_node); + vector_push(stats_vec, &stats); } static void @@ -506,20 +491,19 @@ fdb_update_log(const char *action, void fdb_stats_run(struct rconn *swconn OVS_UNUSED, struct ovsdb_idl_index *sbrec_port_binding_by_name OVS_UNUSED, - struct ovs_list *stats_list, + struct vector *stats_vec, uint64_t *req_delay, void *data) { struct mac_cache_data *cache_data = data; long long timewall_now = time_wall_msec(); struct mac_cache_stats *stats; - LIST_FOR_EACH_POP (stats, list_node, stats_list) { + VECTOR_FOR_EACH_PTR (stats_vec, stats) { struct fdb *fdb = fdb_find(&cache_data->fdbs, &stats->data.fdb); if (!fdb) { fdb_update_log("Not found in the cache:", &stats->data.fdb, false, NULL, 0, 0); - free(stats); continue; } @@ -546,8 +530,6 @@ fdb_stats_run(struct rconn *swconn OVS_UNUSED, fdb_update_log("Not updating non-active", &fdb->data, true, threshold, stats->idle_age_ms, since_updated_ms); } - - free(stats); } mac_cache_update_req_delay(&cache_data->thresholds, req_delay); @@ -557,34 +539,10 @@ fdb_stats_run(struct rconn *swconn OVS_UNUSED, } /* Packet buffering. */ -struct bp_packet_data * -bp_packet_data_create(const struct ofputil_packet_in *pin, - const struct ofpbuf *continuation) { - struct bp_packet_data *pd = xmalloc(sizeof *pd); - - pd->pin = (struct ofputil_packet_in) { - .packet = xmemdup(pin->packet, pin->packet_len), - .packet_len = pin->packet_len, - .flow_metadata = pin->flow_metadata, - .reason = pin->reason, - .table_id = pin->table_id, - .cookie = pin->cookie, - /* Userdata are empty on purpose, - * it is not needed for the continuation. */ - .userdata = NULL, - .userdata_len = 0, - }; - pd->continuation = ofpbuf_clone(continuation); - - return pd; -} - - void bp_packet_data_destroy(struct bp_packet_data *pd) { free(pd->pin.packet); ofpbuf_delete(pd->continuation); - free(pd); } struct buffered_packets * @@ -604,7 +562,8 @@ buffered_packets_add(struct buffered_packets_ctx *ctx, /* Schedule the freshly added buffered packet to do lookup * immediately. */ bp->lookup_at_ms = 0; - ovs_list_init(&bp->queue); + bp->queue = VECTOR_CAPACITY_INITIALIZER(struct bp_packet_data, + BUFFER_QUEUE_DEPTH); } bp->expire_at_ms = time_msec() + BUFFERED_PACKETS_TIMEOUT_MS; @@ -614,14 +573,32 @@ buffered_packets_add(struct buffered_packets_ctx *ctx, void buffered_packets_packet_data_enqueue(struct buffered_packets *bp, - struct bp_packet_data *pd) { - if (ovs_list_size(&bp->queue) == BUFFER_QUEUE_DEPTH) { - struct bp_packet_data *p = CONTAINER_OF(ovs_list_pop_front(&bp->queue), - struct bp_packet_data, node); - - bp_packet_data_destroy(p); + const struct ofputil_packet_in *pin, + const struct ofpbuf *continuation) +{ + if (vector_len(&bp->queue) == BUFFER_QUEUE_DEPTH) { + struct bp_packet_data pd; + vector_remove(&bp->queue, 0, &pd); + bp_packet_data_destroy(&pd); } - ovs_list_push_back(&bp->queue, &pd->node); + + struct bp_packet_data pd = (struct bp_packet_data) { + .pin = (struct ofputil_packet_in) { + .packet = xmemdup(pin->packet, pin->packet_len), + .packet_len = pin->packet_len, + .flow_metadata = pin->flow_metadata, + .reason = pin->reason, + .table_id = pin->table_id, + .cookie = pin->cookie, + /* Userdata are empty on purpose, + * it is not needed for the continuation. */ + .userdata = NULL, + .userdata_len = 0, + }, + .continuation = ofpbuf_clone(continuation), + }; + + vector_push(&bp->queue, &pd); } void @@ -661,16 +638,18 @@ buffered_packets_ctx_run(struct buffered_packets_ctx *ctx, } struct bp_packet_data *pd; - LIST_FOR_EACH_POP (pd, node, &bp->queue) { + VECTOR_FOR_EACH_PTR (&bp->queue, pd) { struct dp_packet packet; dp_packet_use_const(&packet, pd->pin.packet, pd->pin.packet_len); struct eth_header *eth = dp_packet_data(&packet); eth->eth_dst = mac; - - ovs_list_push_back(&ctx->ready_packets_data, &pd->node); } + vector_push_array(&ctx->ready_packets_data, + vector_get_array(&bp->queue), + vector_len(&bp->queue)); + vector_clear(&bp->queue); buffered_packets_remove(ctx, bp); } @@ -679,7 +658,7 @@ buffered_packets_ctx_run(struct buffered_packets_ctx *ctx, bool buffered_packets_ctx_is_ready_to_send(struct buffered_packets_ctx *ctx) { - return !ovs_list_is_empty(&ctx->ready_packets_data); + return !vector_is_empty(&ctx->ready_packets_data); } bool @@ -689,14 +668,14 @@ buffered_packets_ctx_has_packets(struct buffered_packets_ctx *ctx) { void buffered_packets_ctx_init(struct buffered_packets_ctx *ctx) { + ctx->ready_packets_data = VECTOR_EMPTY_INITIALIZER(struct bp_packet_data); hmap_init(&ctx->buffered_packets); - ovs_list_init(&ctx->ready_packets_data); } void buffered_packets_ctx_destroy(struct buffered_packets_ctx *ctx) { struct bp_packet_data *pd; - LIST_FOR_EACH_POP (pd, node, &ctx->ready_packets_data) { + VECTOR_FOR_EACH_PTR (&ctx->ready_packets_data, pd) { bp_packet_data_destroy(pd); } @@ -707,16 +686,6 @@ buffered_packets_ctx_destroy(struct buffered_packets_ctx *ctx) { hmap_destroy(&ctx->buffered_packets); } - -void -mac_cache_stats_destroy(struct ovs_list *stats_list) -{ - struct mac_cache_stats *stats; - LIST_FOR_EACH_POP (stats, list_node, stats_list) { - free(stats); - } -} - static uint32_t mac_binding_data_hash(const struct mac_binding_data *mb_data) { @@ -815,11 +784,12 @@ static void buffered_packets_remove(struct buffered_packets_ctx *ctx, struct buffered_packets *bp) { struct bp_packet_data *pd; - LIST_FOR_EACH_POP (pd, node, &bp->queue) { + VECTOR_FOR_EACH_PTR (&bp->queue, pd) { bp_packet_data_destroy(pd); } hmap_remove(&ctx->buffered_packets, &bp->hmap_node); + vector_destroy(&bp->queue); free(bp); } @@ -861,48 +831,49 @@ buffered_packets_db_lookup(struct buffered_packets *bp, struct ds *ip, void mac_binding_probe_stats_process_flow_stats( - struct ovs_list *stats_list, + struct vector *stats_vec, struct ofputil_flow_stats *ofp_stats) { - struct mac_cache_stats *stats = xmalloc(sizeof *stats); - - stats->idle_age_ms = ofp_stats->idle_age * 1000; - stats->data.mb = (struct mac_binding_data) { - .cookie = ntohll(ofp_stats->cookie), - /* The port_key must be zero to match mac_binding_data_from_sbrec. */ - .port_key = 0, - .dp_key = ntohll(ofp_stats->match.flow.metadata), + struct mac_cache_stats stats = (struct mac_cache_stats) { + .idle_age_ms = ofp_stats->idle_age * 1000, + .data.mb = (struct mac_binding_data) { + .cookie = ntohll(ofp_stats->cookie), + /* The port_key must be zero to match + * mac_binding_data_from_sbrec. */ + .port_key = 0, + .dp_key = ntohll(ofp_stats->match.flow.metadata), + .mac = ofp_stats->match.flow.dl_src + }, }; if (ofp_stats->match.flow.regs[0]) { - stats->data.mb.ip = + stats.data.mb.ip = in6_addr_mapped_ipv4(htonl(ofp_stats->match.flow.regs[0])); } else { ovs_be128 ip6 = hton128(flow_get_xxreg(&ofp_stats->match.flow, 1)); - memcpy(&stats->data.mb.ip, &ip6, sizeof stats->data.mb.ip); + memcpy(&stats.data.mb.ip, &ip6, sizeof stats.data.mb.ip); } - ovs_list_push_back(stats_list, &stats->list_node); + vector_push(stats_vec, &stats); } void mac_binding_probe_stats_run( struct rconn *swconn, struct ovsdb_idl_index *sbrec_port_binding_by_name, - struct ovs_list *stats_list, + struct vector *stats_vec, uint64_t *req_delay, void *data) { long long timewall_now = time_wall_msec(); struct mac_cache_data *cache_data = data; struct mac_cache_stats *stats; - LIST_FOR_EACH_POP (stats, list_node, stats_list) { + VECTOR_FOR_EACH_PTR (stats_vec, stats) { struct mac_binding *mb = mac_binding_find(&cache_data->mac_bindings, &stats->data.mb); if (!mb) { mac_binding_update_log("Probe: not found in the cache:", &stats->data.mb, false, NULL, 0, 0); - free(stats); continue; } @@ -915,7 +886,6 @@ mac_binding_probe_stats_run( mac_binding_update_log("Not sending ARP/ND request for non-active", &mb->data, true, threshold, stats->idle_age_ms, since_updated_ms); - free(stats); continue; } @@ -924,7 +894,6 @@ mac_binding_probe_stats_run( "Not sending ARP/ND request for recently updated", &mb->data, true, threshold, stats->idle_age_ms, since_updated_ms); - free(stats); continue; } @@ -932,13 +901,11 @@ mac_binding_probe_stats_run( lport_lookup_by_name(sbrec_port_binding_by_name, sbrec->logical_port); if (!pb) { - free(stats); continue; } struct lport_addresses laddr; if (!extract_lsp_addresses(pb->mac[0], &laddr)) { - free(stats); continue; } @@ -960,7 +927,6 @@ mac_binding_probe_stats_run( OFTABLE_LOCAL_OUTPUT); } - free(stats); destroy_lport_addresses(&laddr); } diff --git a/controller/mac-cache.h b/controller/mac-cache.h index f5dbaf813..295dc9e23 100644 --- a/controller/mac-cache.h +++ b/controller/mac-cache.h @@ -28,6 +28,9 @@ #include "ovn-sb-idl.h" struct ovsdb_idl_index; +struct vector; + +#define MAC_CACHE_VEC_CAPACITY_THRESHOLD 1024 struct mac_cache_data { /* 'struct mac_cache_threshold' by datapath's tunnel_key. */ @@ -89,9 +92,18 @@ struct fdb { long long timestamp; }; -struct bp_packet_data { - struct ovs_list node; +struct mac_cache_stats { + int64_t idle_age_ms; + + union { + /* Common data to identify MAC binding. */ + struct mac_binding_data mb; + /* Common data to identify FDB. */ + struct fdb_data fdb; + } data; +}; +struct bp_packet_data { struct ofpbuf *continuation; struct ofputil_packet_in pin; }; @@ -102,7 +114,7 @@ struct buffered_packets { struct mac_binding_data mb_data; /* Queue of packet_data associated with this struct. */ - struct ovs_list queue; + struct vector queue; /* Timestamp in ms when the buffered packet should expire. */ long long int expire_at_ms; @@ -115,7 +127,7 @@ struct buffered_packets_ctx { /* Map of all buffered packets waiting for the MAC address. */ struct hmap buffered_packets; /* List of packet data that are ready to be sent. */ - struct ovs_list ready_packets_data; + struct vector ready_packets_data; }; /* Thresholds. */ @@ -177,30 +189,24 @@ void fdbs_clear(struct hmap *map); /* MAC binding stat processing. */ void -mac_binding_stats_process_flow_stats(struct ovs_list *stats_list, +mac_binding_stats_process_flow_stats(struct vector *stats_vec, struct ofputil_flow_stats *ofp_stats); void mac_binding_stats_run( struct rconn *swconn OVS_UNUSED, struct ovsdb_idl_index *sbrec_port_binding_by_name OVS_UNUSED, - struct ovs_list *stats_list, uint64_t *req_delay, void *data); + struct vector *stats_vec, uint64_t *req_delay, void *data); /* FDB stat processing. */ -void fdb_stats_process_flow_stats(struct ovs_list *stats_list, +void fdb_stats_process_flow_stats(struct vector *stats_vec, struct ofputil_flow_stats *ofp_stats); void fdb_stats_run( struct rconn *swconn OVS_UNUSED, struct ovsdb_idl_index *sbrec_port_binding_by_name OVS_UNUSED, - struct ovs_list *stats_list, uint64_t *req_delay, void *data); - -void mac_cache_stats_destroy(struct ovs_list *stats_list); + struct vector *stats_vec, uint64_t *req_delay, void *data); /* Packet buffering. */ -struct bp_packet_data * -bp_packet_data_create(const struct ofputil_packet_in *pin, - const struct ofpbuf *continuation); - void bp_packet_data_destroy(struct bp_packet_data *pd); struct buffered_packets * @@ -208,7 +214,8 @@ buffered_packets_add(struct buffered_packets_ctx *ctx, struct mac_binding_data mb_data); void buffered_packets_packet_data_enqueue(struct buffered_packets *bp, - struct bp_packet_data *pd); + const struct ofputil_packet_in *pin, + const struct ofpbuf *continuation); void buffered_packets_ctx_run(struct buffered_packets_ctx *ctx, const struct hmap *recent_mbs, @@ -226,12 +233,12 @@ bool buffered_packets_ctx_is_ready_to_send(struct buffered_packets_ctx *ctx); bool buffered_packets_ctx_has_packets(struct buffered_packets_ctx *ctx); void mac_binding_probe_stats_process_flow_stats( - struct ovs_list *stats_list, + struct vector *stats_vec, struct ofputil_flow_stats *ofp_stats); void mac_binding_probe_stats_run( struct rconn *swconn, struct ovsdb_idl_index *sbrec_port_binding_by_name, - struct ovs_list *stats_list, uint64_t *req_delay, void *data); + struct vector *stats_vec, uint64_t *req_delay, void *data); #endif /* controller/mac-cache.h */ diff --git a/controller/pinctrl.c b/controller/pinctrl.c index f67a61758..a51957761 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -1569,8 +1569,7 @@ OVS_REQUIRES(pinctrl_mutex) return; } - struct bp_packet_data *pd = bp_packet_data_create(pin, continuation); - buffered_packets_packet_data_enqueue(bp, pd); + buffered_packets_packet_data_enqueue(bp, pin, continuation); /* There is a chance that the MAC binding was already created. */ notify_pinctrl_main(); @@ -4734,15 +4733,21 @@ send_mac_binding_buffered_pkts(struct rconn *swconn) { enum ofp_version version = rconn_get_version(swconn); enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version); + struct vector *rpd = &buffered_packets_ctx.ready_packets_data; struct bp_packet_data *pd; - LIST_FOR_EACH_POP (pd, node, &buffered_packets_ctx.ready_packets_data) { + VECTOR_FOR_EACH_PTR (rpd, pd) { queue_msg(swconn, ofputil_encode_resume(&pd->pin, pd->continuation, proto)); bp_packet_data_destroy(pd); } - ovs_list_init(&buffered_packets_ctx.ready_packets_data); + vector_clear(rpd); + if (vector_capacity(rpd) >= MAC_CACHE_VEC_CAPACITY_THRESHOLD) { + VLOG_DBG("The ready_packets_data vector capacity (%"PRIuSIZE") " + "is over threshold.", vector_capacity(rpd)); + vector_shrink_to_fit(rpd); + } } /* Update or add an IP-MAC binding for 'logical_port'. diff --git a/controller/statctrl.c b/controller/statctrl.c index f0c5bd904..28c794df8 100644 --- a/controller/statctrl.c +++ b/controller/statctrl.c @@ -19,6 +19,7 @@ #include "dirs.h" #include "latch.h" #include "lflow.h" +#include "lib/vec.h" #include "mac-cache.h" #include "openvswitch/ofp-errors.h" #include "openvswitch/ofp-flow.h" @@ -53,39 +54,33 @@ struct stats_node { int64_t next_request_timestamp; /* Request delay in ms. */ uint64_t request_delay; - /* List of processed statistics. */ - struct ovs_list stats_list; - /* Function to clean up the node. - * This function runs in main thread. */ - void (*destroy)(struct ovs_list *stats_list); + /* Vector of processed statistics. */ + struct vector stats; /* Function to process the response and store it in the list. * This function runs in statctrl thread locked behind mutex. */ - void (*process_flow_stats)(struct ovs_list *stats_list, + void (*process_flow_stats)(struct vector *stats, struct ofputil_flow_stats *ofp_stats); /* Function to process the parsed stats. * This function runs in main thread locked behind mutex. */ void (*run)(struct rconn *swconn, struct ovsdb_idl_index *sbrec_port_binding_by_name, - struct ovs_list *stats_list, + struct vector *stats, uint64_t *req_delay, void *data); - /* Name of the stats node corresponding stopwatch. */ - const char *stopwatch_name; + /* Name of the stats node. */ + const char *name; }; -#define STATS_NODE(NAME, REQUEST, DESTROY, PROCESS, RUN) \ +#define STATS_NODE(NAME, REQUEST, STAT_TYPE, PROCESS, RUN) \ do { \ statctrl_ctx.nodes[STATS_##NAME] = (struct stats_node) { \ .request = REQUEST, \ .xid = 0, \ .next_request_timestamp = INT64_MAX, \ .request_delay = 0, \ - .stats_list = \ - OVS_LIST_INITIALIZER( \ - &statctrl_ctx.nodes[STATS_##NAME].stats_list), \ - .destroy = DESTROY, \ + .stats = VECTOR_EMPTY_INITIALIZER(STAT_TYPE), \ .process_flow_stats = PROCESS, \ .run = RUN, \ - .stopwatch_name = OVS_STRINGIZE(stats_##NAME), \ + .name = OVS_STRINGIZE(stats_##NAME), \ }; \ stopwatch_create(OVS_STRINGIZE(stats_##NAME), SW_MS); \ } while (0) @@ -143,7 +138,7 @@ statctrl_init(void) .out_group = OFPG_ANY, .table_id = OFTABLE_MAC_CACHE_USE, }; - STATS_NODE(MAC_BINDING, mac_binding_request, mac_cache_stats_destroy, + STATS_NODE(MAC_BINDING, mac_binding_request, struct mac_cache_stats, mac_binding_stats_process_flow_stats, mac_binding_stats_run); struct ofputil_flow_stats_request fdb_request = { @@ -153,7 +148,7 @@ statctrl_init(void) .out_group = OFPG_ANY, .table_id = OFTABLE_LOOKUP_FDB, }; - STATS_NODE(FDB, fdb_request, mac_cache_stats_destroy, + STATS_NODE(FDB, fdb_request, struct mac_cache_stats, fdb_stats_process_flow_stats, fdb_stats_run); struct ofputil_flow_stats_request mac_binding_probe_request = { @@ -164,7 +159,7 @@ statctrl_init(void) .table_id = OFTABLE_MAC_BINDING, }; STATS_NODE(MAC_BINDING_PROBE, mac_binding_probe_request, - mac_cache_stats_destroy, + struct mac_cache_stats, mac_binding_probe_stats_process_flow_stats, mac_binding_probe_stats_run); @@ -196,11 +191,19 @@ statctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, struct stats_node *node = &statctrl_ctx.nodes[i]; uint64_t prev_delay = node->request_delay; - stopwatch_start(node->stopwatch_name, time_msec()); + stopwatch_start(node->name, time_msec()); node->run(statctrl_ctx.swconn, - sbrec_port_binding_by_name, &node->stats_list, + sbrec_port_binding_by_name, &node->stats, &node->request_delay, node_data[i]); - stopwatch_stop(node->stopwatch_name, time_msec()); + vector_clear(&node->stats); + if (vector_capacity(&node->stats) >= + MAC_CACHE_VEC_CAPACITY_THRESHOLD) { + VLOG_DBG("The statistics vector for node '%s' capacity " + "(%"PRIuSIZE") is over threshold.", node->name, + vector_capacity(&node->stats)); + vector_shrink_to_fit(&node->stats); + } + stopwatch_stop(node->name, time_msec()); schedule_updated |= statctrl_update_next_request_timestamp(node, now, prev_delay); @@ -233,7 +236,7 @@ statctrl_wait(struct ovsdb_idl_txn *ovnsb_idl_txn) ovs_mutex_lock(&mutex); for (size_t i = 0; i < STATS_MAX; i++) { struct stats_node *node = &statctrl_ctx.nodes[i]; - if (!ovs_list_is_empty(&node->stats_list)) { + if (!vector_is_empty(&node->stats)) { poll_immediate_wake(); } } @@ -254,7 +257,7 @@ statctrl_destroy(void) for (size_t i = 0; i < STATS_MAX; i++) { struct stats_node *node = &statctrl_ctx.nodes[i]; - node->destroy(&node->stats_list); + vector_destroy(&node->stats); } } @@ -364,7 +367,7 @@ statctrl_decode_statistics_reply(struct stats_node *node, struct ofpbuf *msg) break; } - node->process_flow_stats(&node->stats_list, &fs); + node->process_flow_stats(&node->stats, &fs); } ofpbuf_uninit(&ofpacts); @@ -399,7 +402,7 @@ static void statctrl_notify_main_thread(struct statctrl_ctx *ctx) { for (size_t i = 0; i < STATS_MAX; i++) { - if (!ovs_list_is_empty(&ctx->nodes[i].stats_list)) { + if (!vector_is_empty(&ctx->nodes[i].stats)) { seq_change(ctx->main_seq); return; } -- 2.49.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev