Finding a given port is faster.
Signed-off-by: Jarno Rajahalme <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev