[ovs-dev] [PATCH v6 18/18] lib/rstp: Use hmap instead of a list for ports.

Jarno Rajahalme jrajahalme at nicira.com
Tue Sep 9 18:49:40 UTC 2014


Series pushed to master, thank you for your contribution!

  Jarno

On Sep 9, 2014, at 3:39 AM, Daniele Venturino <venturino.daniele at gmail.com> wrote:

> Acked-by: Daniele Venturino <daniele.venturino at m3s.it>
> 
> 2014-08-21 1:57 GMT+02:00 Jarno Rajahalme <jrajahalme at nicira.com>:
> Finding a given port is faster.
> 
> Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
> ---
>  lib/rstp-common.h         |    5 +++--
>  lib/rstp-state-machines.c |   30 +++++++++++++++---------------
>  lib/rstp.c                |   35 ++++++++++++++++++-----------------
>  3 files changed, 36 insertions(+), 34 deletions(-)
> 
> diff --git a/lib/rstp-common.h b/lib/rstp-common.h
> index 2be5861..dd756ef 100644
> --- a/lib/rstp-common.h
> +++ b/lib/rstp-common.h
> @@ -32,6 +32,7 @@
>  #include "rstp.h"
>  #include <stdbool.h>
>  #include <stdint.h>
> +#include "hmap.h"
>  #include "list.h"
>  #include "ovs-atomic.h"
>  #include "packets.h"
> @@ -264,7 +265,7 @@ struct rstp_port {
>      struct ovs_refcount ref_cnt;
> 
>      struct rstp *rstp OVS_GUARDED_BY(rstp_mutex);
> -    struct list node OVS_GUARDED_BY(rstp_mutex); /* Node in rstp->ports list. */
> +    struct hmap_node node OVS_GUARDED_BY(rstp_mutex); /* In rstp->ports. */
>      void *aux OVS_GUARDED_BY(rstp_mutex);
>      struct rstp_bpdu received_bpdu_buffer OVS_GUARDED_BY(rstp_mutex);
>      /*************************************************************************
> @@ -866,7 +867,7 @@ struct rstp {
>      bool stp_version OVS_GUARDED_BY(rstp_mutex);
> 
>      /* Ports */
> -    struct list ports OVS_GUARDED_BY(rstp_mutex);
> +    struct hmap ports OVS_GUARDED_BY(rstp_mutex);
> 
>      struct ovs_refcount ref_cnt;
> 
> diff --git a/lib/rstp-state-machines.c b/lib/rstp-state-machines.c
> index c40449d..2a98f62 100644
> --- a/lib/rstp-state-machines.c
> +++ b/lib/rstp-state-machines.c
> @@ -190,7 +190,7 @@ move_rstp__(struct rstp *rstp)
> 
>          rstp->changes = false;
>          port_role_selection_sm(rstp);
> -        LIST_FOR_EACH (p, node, &rstp->ports) {
> +        HMAP_FOR_EACH (p, node, &rstp->ports) {
>              if (p->rstp_state != RSTP_DISABLED) {
>                  port_receive_sm(p);
>                  bridge_detection_sm(p);
> @@ -217,7 +217,7 @@ void decrease_rstp_port_timers__(struct rstp *r)
>  {
>      struct rstp_port *p;
> 
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          decrement_timer(&p->hello_when);
>          decrement_timer(&p->tc_while);
>          decrement_timer(&p->fd_while);
> @@ -250,7 +250,7 @@ updt_role_disabled_tree(struct rstp *r)
>  {
>      struct rstp_port *p;
> 
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          p->selected_role = ROLE_DISABLED;
>      }
>  }
> @@ -261,7 +261,7 @@ clear_reselect_tree(struct rstp *r)
>  {
>      struct rstp_port *p;
> 
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          p->reselect = false;
>      }
>  }
> @@ -279,7 +279,7 @@ updt_roles_tree__(struct rstp *r)
>      /* Letter c1) */
>      r->root_times = r->bridge_times;
>      /* Letters a) b) c) */
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          uint32_t old_root_path_cost;
>          uint32_t root_path_cost;
> 
> @@ -310,7 +310,7 @@ updt_roles_tree__(struct rstp *r)
>      VLOG_DBG("%s: new Root is "RSTP_ID_FMT"", r->name,
>               RSTP_ID_ARGS(r->root_priority.root_bridge_id));
>      /* Letters d) e) */
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          p->designated_priority_vector.root_bridge_id =
>              r->root_priority.root_bridge_id;
>          p->designated_priority_vector.root_path_cost =
> @@ -322,7 +322,7 @@ updt_roles_tree__(struct rstp *r)
>          p->designated_times = r->root_times;
>          p->designated_times.hello_time = r->bridge_times.hello_time;
>      }
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          switch (p->info_is) {
>          case INFO_IS_DISABLED:
>              p->selected_role = ROLE_DISABLED;
> @@ -374,12 +374,12 @@ set_selected_tree(struct rstp *r)
>  {
>      struct rstp_port *p;
> 
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          if (p->reselect) {
>              return;
>          }
>      }
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          p->selected = true;
>      }
>  }
> @@ -416,7 +416,7 @@ port_role_selection_sm(struct rstp *r)
>              PORT_ROLE_SELECTION_SM_ROLE_SELECTION;
>          /* no break */
>      case PORT_ROLE_SELECTION_SM_ROLE_SELECTION:
> -        LIST_FOR_EACH (p, node, &r->ports) {
> +        HMAP_FOR_EACH (p, node, &r->ports) {
>              if (p->reselect) {
>                  r->port_role_selection_sm_state =
>                      PORT_ROLE_SELECTION_SM_ROLE_SELECTION_EXEC;
> @@ -1260,7 +1260,7 @@ set_re_root_tree(struct rstp_port *p)
>      struct rstp_port *p1;
> 
>      r = p->rstp;
> -    LIST_FOR_EACH (p1, node, &r->ports) {
> +    HMAP_FOR_EACH (p1, node, &r->ports) {
>          p1->re_root = true;
>      }
>  }
> @@ -1273,7 +1273,7 @@ set_sync_tree(struct rstp_port *p)
>      struct rstp_port *p1;
> 
>      r = p->rstp;
> -    LIST_FOR_EACH (p1, node, &r->ports) {
> +    HMAP_FOR_EACH (p1, node, &r->ports) {
>          p1->sync = true;
>      }
>  }
> @@ -1361,7 +1361,7 @@ re_rooted(struct rstp_port *p)
>      struct rstp_port *p1;
> 
>      r = p->rstp;
> -    LIST_FOR_EACH (p1, node, &r->ports) {
> +    HMAP_FOR_EACH (p1, node, &r->ports) {
>          if ((p1 != p) && (p1->rr_while != 0)) {
>              return false;
>          }
> @@ -1375,7 +1375,7 @@ all_synced(struct rstp *r)
>  {
>      struct rstp_port *p;
> 
> -    LIST_FOR_EACH (p, node, &r->ports) {
> +    HMAP_FOR_EACH (p, node, &r->ports) {
>          if (!(p->selected && p->role == p->selected_role &&
>                (p->role == ROLE_ROOT || p->synced == true))) {
>              return false;
> @@ -1833,7 +1833,7 @@ set_tc_prop_tree(struct rstp_port *p)
>      struct rstp_port *p1;
> 
>      r = p->rstp;
> -    LIST_FOR_EACH (p1, node, &r->ports) {
> +    HMAP_FOR_EACH (p1, node, &r->ports) {
>          /* Set tc_prop on every port, except the one calling this
>           * function. */
>          if (p1->port_number != p->port_number) {
> diff --git a/lib/rstp.c b/lib/rstp.c
> index d5abd20..96ea8ef 100644
> --- a/lib/rstp.c
> +++ b/lib/rstp.c
> @@ -176,7 +176,7 @@ rstp_unref(struct rstp *rstp)
>           * ports from one bridge to another, and holders always
>           * release their ports before releasing the bridge.  This
>           * means that there should be not ports at this time. */
> -        ovs_assert(list_is_empty(&rstp->ports));
> +        ovs_assert(hmap_is_empty(&rstp->ports));
> 
>          list_remove(&rstp->node);
>          ovs_mutex_unlock(&rstp_mutex);
> @@ -251,9 +251,9 @@ rstp_create(const char *name, rstp_identifier bridge_address,
>      rstp = xzalloc(sizeof *rstp);
>      rstp->name = xstrdup(name);
> 
> -    /* Initialize the ports list before calling any setters,
> -     * so that the state machines will see an empty ports list. */
> -    list_init(&rstp->ports);
> +    /* Initialize the ports map before calling any setters,
> +     * so that the state machines will see an empty ports map. */
> +    hmap_init(&rstp->ports);
> 
>      ovs_mutex_lock(&rstp_mutex);
>      /* Set bridge address. */
> @@ -303,7 +303,7 @@ set_bridge_priority__(struct rstp *rstp)
>      /* [17.13] When the bridge address changes, recalculates all priority
>       * vectors.
>       */
> -    LIST_FOR_EACH (p, node, &rstp->ports) {
> +    HMAP_FOR_EACH (p, node, &rstp->ports) {
>          p->selected = false;
>          p->reselect = true;
>      }
> @@ -416,7 +416,7 @@ reinitialize_rstp__(struct rstp *rstp)
>      OVS_REQUIRES(rstp_mutex)
>  {
>      struct rstp temp;
> -    static struct list ports;
> +    static struct hmap ports;
>      struct rstp_port *p;
> 
>      /* Copy rstp in temp */
> @@ -429,9 +429,9 @@ reinitialize_rstp__(struct rstp *rstp)
>      /* Initialize rstp. */
>      rstp->name = temp.name;
> 
> -    /* Initialize the ports list before calling any setters,
> +    /* Initialize the ports hmap before calling any setters,
>       * so that the state machines will see an empty ports list. */
> -    list_init(&rstp->ports);
> +    hmap_init(&rstp->ports);
> 
>      /* Set bridge address. */
>      rstp_set_bridge_address__(rstp, temp.address);
> @@ -457,7 +457,7 @@ reinitialize_rstp__(struct rstp *rstp)
>      /* Restore ports. */
>      rstp->ports = ports;
> 
> -    LIST_FOR_EACH (p, node, &rstp->ports) {
> +    HMAP_FOR_EACH (p, node, &rstp->ports) {
>          reinitialize_port__(p);
>      }
> 
> @@ -583,7 +583,7 @@ rstp_set_bridge_transmit_hold_count__(struct rstp *rstp,
>          /* Resetting txCount on all ports [17.13]. */
> 
>          rstp->transmit_hold_count = new_transmit_hold_count;
> -        LIST_FOR_EACH (p, node, &rstp->ports) {
> +        HMAP_FOR_EACH (p, node, &rstp->ports) {
>              p->tx_count = 0;
>          }
>      }
> @@ -779,7 +779,7 @@ rstp_check_and_reset_fdb_flush(struct rstp *rstp)
>      needs_flush = false;
> 
>      ovs_mutex_lock(&rstp_mutex);
> -    LIST_FOR_EACH (p, node, &rstp->ports) {
> +    HMAP_FOR_EACH (p, node, &rstp->ports) {
>          if (p->fdb_flush) {
>              needs_flush = true;
>              /* fdb_flush should be reset by the filtering database
> @@ -812,7 +812,7 @@ rstp_get_next_changed_port_aux(struct rstp *rstp, struct rstp_port **portp)
>      if (*portp == NULL) {
>          struct rstp_port *p;
> 
> -        LIST_FOR_EACH (p, node, &rstp->ports) {
> +        HMAP_FOR_EACH (p, node, &rstp->ports) {
>              if (p->state_changed) {
>                  p->state_changed = false;
>                  aux = p->aux;
> @@ -823,7 +823,7 @@ rstp_get_next_changed_port_aux(struct rstp *rstp, struct rstp_port **portp)
>      } else { /* continue */
>          struct rstp_port *p = *portp;
> 
> -        LIST_FOR_EACH_CONTINUE (p, node, &rstp->ports) {
> +        HMAP_FOR_EACH_CONTINUE (p, node, &rstp->ports) {
>              if (p->state_changed) {
>                  p->state_changed = false;
>                  aux = p->aux;
> @@ -850,7 +850,8 @@ rstp_get_port__(struct rstp *rstp, uint16_t port_number)
> 
>      ovs_assert(rstp && port_number > 0 && port_number <= RSTP_MAX_PORTS);
> 
> -    LIST_FOR_EACH (port, node, &rstp->ports) {
> +    HMAP_FOR_EACH_WITH_HASH (port, node, hash_int(port_number, 0),
> +                             &rstp->ports) {
>          if (port->port_number == port_number) {
>              return port;
>          }
> @@ -1051,7 +1052,7 @@ rstp_add_port(struct rstp *rstp)
>               p->port_id);
> 
>      rstp_port_set_state__(p, RSTP_DISCARDING);
> -    list_push_back(&rstp->ports, &p->node);
> +    hmap_insert(&rstp->ports, &p->node, hash_int(p->port_number, 0));
>      rstp->changes = true;
>      move_rstp__(rstp);
>      VLOG_DBG("%s: added port "RSTP_PORT_ID_FMT"", rstp->name, p->port_id);
> @@ -1084,7 +1085,7 @@ rstp_port_unref(struct rstp_port *rp)
>          ovs_mutex_lock(&rstp_mutex);
>          rstp = rp->rstp;
>          rstp_port_set_state__(rp, RSTP_DISABLED);
> -        list_remove(&rp->node);
> +        hmap_remove(&rstp->ports, &rp->node);
>          VLOG_DBG("%s: removed port "RSTP_PORT_ID_FMT"", rstp->name,
>                   rp->port_id);
>          ovs_mutex_unlock(&rstp_mutex);
> @@ -1237,7 +1238,7 @@ rstp_get_root_port(struct rstp *rstp)
>      struct rstp_port *p;
> 
>      ovs_mutex_lock(&rstp_mutex);
> -    LIST_FOR_EACH (p, node, &rstp->ports) {
> +    HMAP_FOR_EACH (p, node, &rstp->ports) {
>          if (p->port_id == rstp->root_port_id) {
>              ovs_mutex_unlock(&rstp_mutex);
>              return p;
> --
> 1.7.10.4
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
> 




More information about the dev mailing list