On Wed, Apr 30, 2025 at 7:54 AM Ales Musil <amu...@redhat.com> wrote:

> The vector has the same functionality as the x2nrealloc
> for insert. Use vector instead which slightly simplifies
> the final code.
>
> Signed-off-by: Ales Musil <amu...@redhat.com>
> Acked-by: Mark Michelson <mmich...@redhat.com>
> ---
> v4: Rebase on top of current main.
>     Add ack from Mark.
> v3: Rebase on top of current main.
> v2: Rebase on top of current main.
> ---
>  controller/binding.c          |  4 +--
>  controller/local_data.c       | 62 +++++++++++++++++------------------
>  controller/local_data.h       | 15 +++++----
>  controller/ovn-controller.c   | 19 ++++-------
>  controller/physical.c         | 18 +++++-----
>  controller/pinctrl.c          | 12 ++++---
>  controller/route.c            |  8 ++---
>  controller/test-lflow-cache.c | 27 +++++++--------
>  8 files changed, 79 insertions(+), 86 deletions(-)
>
> diff --git a/controller/binding.c b/controller/binding.c
> index f7535051f..9aec6708f 100644
> --- a/controller/binding.c
> +++ b/controller/binding.c
> @@ -738,10 +738,10 @@ update_ld_peers(const struct sbrec_port_binding *pb,
>       * remove it from the ld peers list.
>       */
>      enum en_lport_type type = get_lport_type(pb);
> -    int num_peers = ld->n_peer_ports;
> +    size_t num_peers = vector_len(&ld->peer_ports);
>      if (type != LP_PATCH) {
>          remove_local_datapath_peer_port(pb, ld, local_datapaths);
> -        if (num_peers != ld->n_peer_ports) {
> +        if (num_peers != vector_len(&ld->peer_ports)) {
>              static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>              VLOG_DBG_RL(&rl,
>                          "removing lport %s from the ld peers list",
> diff --git a/controller/local_data.c b/controller/local_data.c
> index e256de5fa..adda3b859 100644
> --- a/controller/local_data.c
> +++ b/controller/local_data.c
> @@ -86,6 +86,7 @@ local_datapath_alloc(const struct sbrec_datapath_binding
> *dp)
>      ld->datapath = dp;
>      ld->is_switch = datapath_is_switch(dp);
>      ld->is_transit_switch = datapath_is_transit_switch(dp);
> +    ld->peer_ports = VECTOR_EMPTY_INITIALIZER(struct peer_ports);
>      shash_init(&ld->external_ports);
>      shash_init(&ld->multichassis_ports);
>      /* memory accounting - common part. */
> @@ -121,10 +122,9 @@ local_datapath_destroy(struct local_datapath *ld)
>      local_datapath_usage -= (shash_count(&ld->multichassis_ports)
>                               * sizeof *node);
>      local_datapath_usage -= sizeof *ld;
> -    local_datapath_usage -=
> -        ld->n_allocated_peer_ports * sizeof *ld->peer_ports;
> +    local_datapath_usage -= vector_memory_usage(&ld->peer_ports);
>
> -    free(ld->peer_ports);
> +    vector_destroy(&ld->peer_ports);
>      shash_destroy(&ld->external_ports);
>      shash_destroy(&ld->multichassis_ports);
>      free(ld);
> @@ -258,10 +258,11 @@ local_data_dump_peer_ports(struct hmap
> *local_datapaths, struct ds *peer_ports)
>      HMAP_FOR_EACH (ld, hmap_node, local_datapaths) {
>          const char *name = smap_get_def(&ld->datapath->external_ids,
> "name",
>                                          "unknown");
> -        for (size_t i = 0; i < ld->n_peer_ports; i++) {
> +        struct peer_ports peers;
> +        VECTOR_FOR_EACH (&ld->peer_ports, peers) {
>              ds_put_format(peer_ports, "dp %s : local = %s, remote = %s\n",
> -                          name, ld->peer_ports[i].local->logical_port,
> -                          ld->peer_ports[i].remote->logical_port);
> +                          name, peers.local->logical_port,
> +                          peers.remote->logical_port);
>          }
>      }
>  }
> @@ -272,25 +273,26 @@ remove_local_datapath_peer_port(const struct
> sbrec_port_binding *pb,
>                                  struct hmap *local_datapaths)
>  {
>      size_t i = 0;
> -    for (i = 0; i < ld->n_peer_ports; i++) {
> -        if (ld->peer_ports[i].local == pb) {
> +    const struct peer_ports *peers;
> +    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
> +        if (peers->local == pb) {
>              break;
>          }
> +        i++;
>      }
>
> -    if (i == ld->n_peer_ports) {
> +    struct peer_ports removed;
> +    if (!vector_remove_fast(&ld->peer_ports, i, &removed)) {
>          return;
>      }
>
> -    const struct sbrec_port_binding *peer = ld->peer_ports[i].remote;
> -
> -    /* Possible improvement: We can shrink the allocated peer ports
> -     * if (ld->n_peer_ports < ld->n_allocated_peer_ports / 2).
> -     */
> -    ld->peer_ports[i].local = ld->peer_ports[ld->n_peer_ports - 1].local;
> -    ld->peer_ports[i].remote = ld->peer_ports[ld->n_peer_ports -
> 1].remote;
> -    ld->n_peer_ports--;
> +    if (vector_len(&ld->peer_ports) < vector_capacity(&ld->peer_ports) /
> 2) {
> +        local_datapath_usage -= vector_memory_usage(&ld->peer_ports);
> +        vector_shrink_to_fit(&ld->peer_ports);
> +        local_datapath_usage += vector_memory_usage(&ld->peer_ports);
> +    }
>
> +    const struct sbrec_port_binding *peer = removed.remote;
>      struct local_datapath *peer_ld =
>          get_local_datapath(local_datapaths, peer->datapath->tunnel_key);
>      if (peer_ld) {
> @@ -679,24 +681,20 @@ local_datapath_peer_port_add(struct local_datapath
> *ld,
>                               const struct sbrec_port_binding *local,
>                               const struct sbrec_port_binding *remote)
>  {
> -    for (size_t i = 0; i < ld->n_peer_ports; i++) {
> -        if (ld->peer_ports[i].local == local) {
> +    const struct peer_ports *ptr;
> +    VECTOR_FOR_EACH_PTR (&ld->peer_ports, ptr) {
> +        if (ptr->local == local) {
>              return;
>          }
>      }
> -    ld->n_peer_ports++;
> -    if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
> -        size_t old_n_ports = ld->n_allocated_peer_ports;
> -        ld->peer_ports =
> -            x2nrealloc(ld->peer_ports,
> -                       &ld->n_allocated_peer_ports,
> -                       sizeof *ld->peer_ports);
> -        local_datapath_usage +=
> -            (ld->n_allocated_peer_ports - old_n_ports) *
> -            sizeof *ld->peer_ports;
> -    }
> -    ld->peer_ports[ld->n_peer_ports - 1].local = local;
> -    ld->peer_ports[ld->n_peer_ports - 1].remote = remote;
> +
> +   local_datapath_usage -= vector_memory_usage(&ld->peer_ports);
> +    struct peer_ports peers = (struct peer_ports) {
> +        .local = local,
> +        .remote = remote,
> +    };
> +    vector_push(&ld->peer_ports, &peers);
> +    local_datapath_usage += vector_memory_usage(&ld->peer_ports);
>  }
>
>  static bool
> diff --git a/controller/local_data.h b/controller/local_data.h
> index 19d558232..841829f2e 100644
> --- a/controller/local_data.h
> +++ b/controller/local_data.h
> @@ -23,6 +23,7 @@
>
>  /* OVN includes. */
>  #include "lib/ovn-util.h"
> +#include "vec.h"
>
>  struct sbrec_datapath_binding;
>  struct sbrec_port_binding;
> @@ -32,6 +33,11 @@ struct ovsrec_bridge;
>  struct ovsrec_interface_table;
>  struct sbrec_load_balancer;
>
> +struct peer_ports {
> +    const struct sbrec_port_binding *local;
> +    const struct sbrec_port_binding *remote;
> +};
> +
>  /* A logical datapath that has some relevance to this hypervisor.  A
> logical
>   * datapath D is relevant to hypervisor H if:
>   *
> @@ -53,13 +59,8 @@ struct local_datapath {
>      /* The vtep port in this datapath, if any (at most one is allowed). */
>      const struct sbrec_port_binding *vtep_port;
>
> -    struct {
> -        const struct sbrec_port_binding *local;
> -        const struct sbrec_port_binding *remote;
> -    } *peer_ports;
> -
> -    size_t n_peer_ports;
> -    size_t n_allocated_peer_ports;
> +    /* Vector of struct peer_ports. */
> +    struct vector peer_ports;
>
>      struct shash external_ports;
>      struct shash multichassis_ports;
> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> index 37406f923..75b1ac750 100644
> --- a/controller/ovn-controller.c
> +++ b/controller/ovn-controller.c
> @@ -2522,9 +2522,7 @@ en_mff_ovn_geneve_run(struct engine_node *node, void
> *data)
>  struct load_balancers_by_dp {
>      struct hmap_node node;
>      const struct sbrec_datapath_binding *dp;
> -    const struct sbrec_load_balancer **dp_lbs;
> -    size_t n_allocated_dp_lbs;
> -    size_t n_dp_lbs;
> +    struct vector dp_lbs; /* Vector of const struct sbrec_load_balancer
> *. */
>  };
>
>  static struct load_balancers_by_dp *
> @@ -2534,6 +2532,8 @@ load_balancers_by_dp_create(struct hmap *lbs,
>      struct load_balancers_by_dp *lbs_by_dp = xzalloc(sizeof *lbs_by_dp);
>
>      lbs_by_dp->dp = dp;
> +    lbs_by_dp->dp_lbs =
> +        VECTOR_EMPTY_INITIALIZER(const struct sbrec_load_balancer *);
>      hmap_insert(lbs, &lbs_by_dp->node, hash_uint64(dp->tunnel_key));
>      return lbs_by_dp;
>  }
> @@ -2545,7 +2545,7 @@ load_balancers_by_dp_destroy(struct
> load_balancers_by_dp *lbs_by_dp)
>          return;
>      }
>
> -    free(lbs_by_dp->dp_lbs);
> +    vector_destroy(&lbs_by_dp->dp_lbs);
>      free(lbs_by_dp);
>  }
>
> @@ -2583,12 +2583,7 @@ load_balancers_by_dp_add_one(const struct hmap
> *local_datapaths,
>          lbs_by_dp = load_balancers_by_dp_create(lbs, ldp->datapath);
>      }
>
> -    if (lbs_by_dp->n_dp_lbs == lbs_by_dp->n_allocated_dp_lbs) {
> -        lbs_by_dp->dp_lbs = x2nrealloc(lbs_by_dp->dp_lbs,
> -                                       &lbs_by_dp->n_allocated_dp_lbs,
> -                                       sizeof *lbs_by_dp->dp_lbs);
> -    }
> -    lbs_by_dp->dp_lbs[lbs_by_dp->n_dp_lbs++] = lb;
> +    vector_push(&lbs_by_dp->dp_lbs, &lb);
>  }
>
>  /* Builds and returns a hmap of 'load_balancers_by_dp', one record for
> each
> @@ -3005,8 +3000,8 @@ lb_data_runtime_data_handler(struct engine_node
> *node, void *data OVS_UNUSED)
>              continue;
>          }
>
> -        for (size_t i = 0; i < lbs_by_dp->n_dp_lbs; i++) {
> -            const struct sbrec_load_balancer *sbrec_lb =
> lbs_by_dp->dp_lbs[i];
> +        const struct sbrec_load_balancer *sbrec_lb;
> +        VECTOR_FOR_EACH (&lbs_by_dp->dp_lbs, sbrec_lb) {
>              struct ovn_controller_lb *lb =
>                  ovn_controller_lb_find(&lb_data->local_lbs,
>                                         &sbrec_lb->header_.uuid);
> diff --git a/controller/physical.c b/controller/physical.c
> index b26d12d3c..a17d792c3 100644
> --- a/controller/physical.c
> +++ b/controller/physical.c
> @@ -347,9 +347,9 @@ put_remote_port_redirect_bridged(const struct
>          }
>
>          uint32_t ls_dp_key = 0;
> -        for (int i = 0; i < ld->n_peer_ports; i++) {
> -            const struct sbrec_port_binding *sport_binding =
> -                ld->peer_ports[i].remote;
> +        const struct peer_ports *peers;
> +        VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
> +            const struct sbrec_port_binding *sport_binding =
> peers->remote;
>              const char *sport_peer_name =
>                  smap_get(&sport_binding->options, "peer");
>              const char *distributed_port =
> @@ -734,9 +734,9 @@ put_replace_chassis_mac_flows(const struct shash
> *ct_zones,
>      int tag = localnet_port->tag ? *localnet_port->tag : 0;
>      struct zone_ids zone_ids = get_zone_ids(localnet_port, ct_zones);
>
> -    for (int i = 0; i < ld->n_peer_ports; i++) {
> -        const struct sbrec_port_binding *rport_binding =
> -            ld->peer_ports[i].remote;
> +    const struct peer_ports *peers;
> +    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
> +        const struct sbrec_port_binding *rport_binding = peers->remote;
>          struct eth_addr router_port_mac;
>          char *err_str = NULL;
>          struct match match;
> @@ -881,9 +881,9 @@ put_replace_router_port_mac_flows(const struct
> physical_ctx *ctx,
>          return;
>      }
>
> -    for (int i = 0; i < ld->n_peer_ports; i++) {
> -        const struct sbrec_port_binding *rport_binding =
> -            ld->peer_ports[i].remote;
> +    const struct peer_ports *peers;
> +    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
> +        const struct sbrec_port_binding *rport_binding = peers->remote;
>          struct eth_addr router_port_mac;
>          struct match match;
>          struct ofpact_mac *replace_mac;
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index a269e5375..34fb2e6bf 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -1356,8 +1356,9 @@ fill_ipv6_prefix_state(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
>  {
>      bool changed = false;
>
> -    for (size_t i = 0; i < ld->n_peer_ports; i++) {
> -        const struct sbrec_port_binding *pb = ld->peer_ports[i].local;
> +    const struct peer_ports *peers;
> +    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
> +        const struct sbrec_port_binding *pb = peers->local;
>          struct ipv6_prefixd_state *pfd;
>
>          if (!smap_get_bool(&pb->options, "ipv6_prefix", false)) {
> @@ -4814,9 +4815,10 @@ send_garp_locally(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
>          get_local_datapath(local_datapaths, in_pb->datapath->tunnel_key);
>
>      ovs_assert(ldp);
> -    for (size_t i = 0; i < ldp->n_peer_ports; i++) {
> -        const struct sbrec_port_binding *local = ldp->peer_ports[i].local;
> -        const struct sbrec_port_binding *remote =
> ldp->peer_ports[i].remote;
> +    const struct peer_ports *peers;
> +    VECTOR_FOR_EACH_PTR (&ldp->peer_ports, peers) {
> +        const struct sbrec_port_binding *local = peers->local;
> +        const struct sbrec_port_binding *remote = peers->remote;
>
>          /* Skip "ingress" port. */
>          if (local == in_pb) {
> diff --git a/controller/route.c b/controller/route.c
> index 55d3e0ae3..4e5862529 100644
> --- a/controller/route.c
> +++ b/controller/route.c
> @@ -158,7 +158,7 @@ route_run(struct route_ctx_in *r_ctx_in,
>      build_port_mapping(&port_mapping,
> r_ctx_in->dynamic_routing_port_mapping);
>
>      HMAP_FOR_EACH (ld, hmap_node, r_ctx_in->local_datapaths) {
> -        if (!ld->n_peer_ports || ld->is_switch) {
> +        if (vector_is_empty(&ld->peer_ports) || ld->is_switch) {
>              continue;
>          }
>
> @@ -169,9 +169,9 @@ route_run(struct route_ctx_in *r_ctx_in,
>
>          /* This is a LR datapath, find LRPs with route exchange options
>           * that are bound locally. */
> -        for (size_t i = 0; i < ld->n_peer_ports; i++) {
> -            const struct sbrec_port_binding *local_peer
> -                = ld->peer_ports[i].local;
> +        const struct peer_ports *peers;
> +        VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
> +            const struct sbrec_port_binding *local_peer = peers->local;
>              const struct sbrec_port_binding *repb =
>
>  route_exchange_find_port(r_ctx_in->sbrec_port_binding_by_name,
>                                           r_ctx_in->chassis,
> diff --git a/controller/test-lflow-cache.c b/controller/test-lflow-cache.c
> index 7ce999360..6f29abce9 100644
> --- a/controller/test-lflow-cache.c
> +++ b/controller/test-lflow-cache.c
> @@ -20,6 +20,7 @@
>  #include "tests/ovstest.h"
>  #include "tests/test-utils.h"
>  #include "util.h"
> +#include "vec.h"
>
>  #include "lflow-cache.h"
>
> @@ -111,9 +112,7 @@ test_lflow_cache_operations(struct ovs_cmdl_context
> *ctx)
>      struct lflow_cache *lc = lflow_cache_create();
>      struct expr *e = expr_create_boolean(true);
>      bool enabled = !strcmp(ctx->argv[1], "true");
> -    struct uuid *lflow_uuids = NULL;
> -    size_t n_allocated_lflow_uuids = 0;
> -    size_t n_lflow_uuids = 0;
> +    struct vector lflow_uuids = VECTOR_EMPTY_INITIALIZER(struct uuid);
>      unsigned int shift = 2;
>      unsigned int n_ops;
>
> @@ -152,16 +151,13 @@ test_lflow_cache_operations(struct ovs_cmdl_context
> *ctx)
>                  goto done;
>              }
>
> -            if (n_lflow_uuids == n_allocated_lflow_uuids) {
> -                lflow_uuids = x2nrealloc(lflow_uuids,
> &n_allocated_lflow_uuids,
> -                                         sizeof *lflow_uuids);
> -            }
> -            struct uuid *lflow_uuid = &lflow_uuids[n_lflow_uuids++];
> +            struct uuid lflow_uuid;
> +            uuid_generate(&lflow_uuid);
> +            vector_push(&lflow_uuids, &lflow_uuid);
>
> -            uuid_generate(lflow_uuid);
> -            test_lflow_cache_add__(lc, op_type, lflow_uuid, conj_id_ofs,
> +            test_lflow_cache_add__(lc, op_type, &lflow_uuid, conj_id_ofs,
>                                     n_conjs, e);
> -            test_lflow_cache_lookup__(lc, lflow_uuid);
> +            test_lflow_cache_lookup__(lc, &lflow_uuid);
>          } else if (!strcmp(op, "add-del")) {
>              const char *op_type = test_read_value(ctx, shift++,
> "op_type");
>              if (!op_type) {
> @@ -188,9 +184,10 @@ test_lflow_cache_operations(struct ovs_cmdl_context
> *ctx)
>              test_lflow_cache_delete__(lc, &lflow_uuid);
>              test_lflow_cache_lookup__(lc, &lflow_uuid);
>          } else if (!strcmp(op, "del")) {
> -            ovs_assert(n_lflow_uuids);
> -            test_lflow_cache_delete__(lc, &lflow_uuids[n_lflow_uuids -
> 1]);
> -            n_lflow_uuids--;
> +            ovs_assert(!vector_is_empty(&lflow_uuids));
> +            struct uuid lflow_uuid;
> +            vector_pop(&lflow_uuids, &lflow_uuid);
> +            test_lflow_cache_delete__(lc, &lflow_uuid);
>          } else if (!strcmp(op, "enable")) {
>              unsigned int limit;
>              unsigned int mem_limit_kb;
> @@ -236,7 +233,7 @@ test_lflow_cache_operations(struct ovs_cmdl_context
> *ctx)
>      }
>  done:
>      lflow_cache_destroy(lc);
> -    free(lflow_uuids);
> +    vector_destroy(&lflow_uuids);
>      expr_destroy(e);
>  }
>
> --
> 2.49.0
>
>
Recheck-request: github-robot
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to