@@ -50,7 +50,7 @@
VLOG_DEFINE_THIS_MODULE(rstp);
-struct ovs_mutex rstp_mutex = OVS_MUTEX_INITIALIZER;
+struct ovs_mutex rstp_mutex;
static struct ovs_list all_rstps__ = OVS_LIST_INITIALIZER(&all_rstps__);
static struct ovs_list *const all_rstps OVS_GUARDED_BY(rstp_mutex) = &all_rstps__;
@@ -161,7 +161,6 @@ rstp_port_role_name(enum rstp_port_role role)
* while taking a new reference. */
struct rstp *
rstp_ref(struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
if (rstp) {
ovs_refcount_ref(&rstp->ref_cnt);
@@ -172,7 +171,6 @@ rstp_ref(struct rstp *rstp)
/* Frees RSTP struct when reference count reaches zero. */
void
rstp_unref(struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
if (rstp && ovs_refcount_unref_relaxed(&rstp->ref_cnt) == 1) {
ovs_mutex_lock(&rstp_mutex);
@@ -197,7 +195,6 @@ rstp_unref(struct rstp *rstp)
* port_number). */
int
rstp_port_get_number(const struct rstp_port *p)
- OVS_EXCLUDED(rstp_mutex)
{
int number;
@@ -214,7 +211,6 @@ static void rstp_unixctl_tcn(struct unixctl_conn *, int argc,
/* Decrements the State Machines' timers. */
void
rstp_tick_timers(struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
decrease_rstp_port_timers__(rstp);
@@ -225,7 +221,6 @@ rstp_tick_timers(struct rstp *rstp)
void
rstp_port_received_bpdu(struct rstp_port *rp, const void *bpdu,
size_t bpdu_size)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
/* Only process packets on ports that have RSTP enabled. */
@@ -237,10 +232,16 @@ rstp_port_received_bpdu(struct rstp_port *rp, const void *bpdu,
void
rstp_init(void)
- OVS_EXCLUDED(rstp_mutex)
{
- unixctl_command_register("rstp/tcn", "[bridge]", 0, 1, rstp_unixctl_tcn,
- NULL);
+ static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+
+ if (ovsthread_once_start(&once)) {
+ ovs_mutex_init_recursive(&rstp_mutex);
+
+ unixctl_command_register("rstp/tcn", "[bridge]", 0, 1, rstp_unixctl_tcn,
+ NULL);
+ ovsthread_once_done(&once);
+ }
}
/* Creates and returns a new RSTP instance that initially has no ports. */
@@ -249,12 +250,13 @@ rstp_create(const char *name, rstp_identifier bridge_address,
void (*send_bpdu)(struct dp_packet *bpdu, void *port_aux,
void *rstp_aux),
void *aux)
- OVS_EXCLUDED(rstp_mutex)
{
struct rstp *rstp;
VLOG_DBG("Creating RSTP instance");
+ rstp_init();
+
rstp = xzalloc(sizeof *rstp);
rstp->name = xstrdup(name);
@@ -338,7 +340,6 @@ rstp_set_bridge_address__(struct rstp *rstp, rstp_identifier bridge_address)
/* Sets the bridge address. */
void
rstp_set_bridge_address(struct rstp *rstp, rstp_identifier bridge_address)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_address__(rstp, bridge_address);
@@ -347,7 +348,6 @@ rstp_set_bridge_address(struct rstp *rstp, rstp_identifier bridge_address)
const char *
rstp_get_name(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
char *name;
@@ -359,7 +359,6 @@ rstp_get_name(const struct rstp *rstp)
rstp_identifier
rstp_get_bridge_id(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
rstp_identifier bridge_id;
@@ -391,7 +390,6 @@ rstp_set_bridge_priority__(struct rstp *rstp, int new_priority)
void
rstp_set_bridge_priority(struct rstp *rstp, int new_priority)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_priority__(rstp, new_priority);
@@ -413,7 +411,6 @@ rstp_set_bridge_ageing_time__(struct rstp *rstp, int new_ageing_time)
void
rstp_set_bridge_ageing_time(struct rstp *rstp, int new_ageing_time)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_ageing_time__(rstp, new_ageing_time);
@@ -509,7 +506,6 @@ rstp_set_bridge_force_protocol_version__(struct rstp *rstp,
void
rstp_set_bridge_force_protocol_version(struct rstp *rstp,
enum rstp_force_protocol_version new_force_protocol_version)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_force_protocol_version__(rstp, new_force_protocol_version);
@@ -551,7 +547,6 @@ rstp_set_bridge_max_age__(struct rstp *rstp, int new_max_age)
void
rstp_set_bridge_max_age(struct rstp *rstp, int new_max_age)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_max_age__(rstp, new_max_age);
@@ -579,7 +574,6 @@ rstp_set_bridge_forward_delay__(struct rstp *rstp, int new_forward_delay)
void
rstp_set_bridge_forward_delay(struct rstp *rstp, int new_forward_delay)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_forward_delay__(rstp, new_forward_delay);
@@ -611,7 +605,6 @@ rstp_set_bridge_transmit_hold_count__(struct rstp *rstp,
void
rstp_set_bridge_transmit_hold_count(struct rstp *rstp,
int new_transmit_hold_count)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_set_bridge_transmit_hold_count__(rstp, new_transmit_hold_count);
@@ -790,7 +783,6 @@ rstp_port_set_path_cost__(struct rstp_port *port, uint32_t path_cost)
/* Gets the root path cost. */
uint32_t
rstp_get_root_path_cost(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
uint32_t cost;
@@ -811,7 +803,6 @@ rstp_get_root_path_cost(const struct rstp *rstp)
* '*port' could become stale before it is used in the next invocation. */
void *
rstp_check_and_reset_fdb_flush(struct rstp *rstp, struct rstp_port **port)
- OVS_EXCLUDED(rstp_mutex)
{
void *aux = NULL;
@@ -965,7 +956,6 @@ rstp_get_port__(struct rstp *rstp, uint16_t port_number)
struct rstp_port *
rstp_get_port(struct rstp *rstp, uint16_t port_number)
- OVS_EXCLUDED(rstp_mutex)
{
struct rstp_port *p;
@@ -1003,7 +993,6 @@ update_port_enabled__(struct rstp_port *p)
/* Sets the port MAC_Operational parameter [6.4.2]. */
void
rstp_port_set_mac_operational(struct rstp_port *p, bool new_mac_operational)
- OVS_EXCLUDED(rstp_mutex)
{
struct rstp *rstp;
@@ -1114,7 +1103,6 @@ reinitialize_port__(struct rstp_port *p)
void
reinitialize_port(struct rstp_port *p)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
reinitialize_port__(p);
@@ -1142,7 +1130,6 @@ rstp_port_set_state__(struct rstp_port *p, enum rstp_state state)
void
rstp_port_set_state(struct rstp_port *p, enum rstp_state state)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_port_set_state__(p, state);
@@ -1152,7 +1139,6 @@ rstp_port_set_state(struct rstp_port *p, enum rstp_state state)
/* Adds a RSTP port. */
struct rstp_port *
rstp_add_port(struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
struct rstp_port *p = xzalloc(sizeof *p);
@@ -1180,7 +1166,6 @@ rstp_add_port(struct rstp *rstp)
* while taking a new reference. */
struct rstp_port *
rstp_port_ref(const struct rstp_port *rp_)
- OVS_EXCLUDED(rstp_mutex)
{
struct rstp_port *rp = CONST_CAST(struct rstp_port *, rp_);
@@ -1193,7 +1178,6 @@ rstp_port_ref(const struct rstp_port *rp_)
/* Frees RSTP struct. This can be caller by any thread. */
void
rstp_port_unref(struct rstp_port *rp)
- OVS_EXCLUDED(rstp_mutex)
{
if (rp && ovs_refcount_unref_relaxed(&rp->ref_cnt) == 1) {
struct rstp *rstp;
@@ -1291,7 +1275,6 @@ rstp_port_set_mcheck__(struct rstp_port *port, bool mcheck)
/* Returns the designated bridge id. */
rstp_identifier
rstp_get_designated_id(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
rstp_identifier designated_id;
@@ -1305,7 +1288,6 @@ rstp_get_designated_id(const struct rstp *rstp)
/* Returns the root bridge id. */
rstp_identifier
rstp_get_root_id(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
rstp_identifier root_id;
@@ -1319,7 +1301,6 @@ rstp_get_root_id(const struct rstp *rstp)
/* Returns the designated port id. */
uint16_t
rstp_get_designated_port_id(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
uint16_t designated_port_id;
@@ -1333,7 +1314,6 @@ rstp_get_designated_port_id(const struct rstp *rstp)
/* Return the bridge port id. */
uint16_t
rstp_get_bridge_port_id(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
uint16_t bridge_port_id;
@@ -1349,7 +1329,6 @@ rstp_get_bridge_port_id(const struct rstp *rstp)
*/
bool
rstp_is_root_bridge(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
bool is_root;
@@ -1364,7 +1343,6 @@ rstp_is_root_bridge(const struct rstp *rstp)
/* Returns the bridge ID of the bridge currently believed to be the root. */
rstp_identifier
rstp_get_designated_root(const struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
rstp_identifier designated_root;
@@ -1380,7 +1358,6 @@ rstp_get_designated_root(const struct rstp *rstp)
*/
struct rstp_port *
rstp_get_root_port(struct rstp *rstp)
- OVS_EXCLUDED(rstp_mutex)
{
struct rstp_port *p;
@@ -1398,7 +1375,6 @@ rstp_get_root_port(struct rstp *rstp)
/* Returns the state of port 'p'. */
enum rstp_state
rstp_port_get_state(const struct rstp_port *p)
- OVS_EXCLUDED(rstp_mutex)
{
enum rstp_state state;
@@ -1417,7 +1393,6 @@ rstp_port_get_status(const struct rstp_port *p, uint16_t *id,
uint16_t *designated_port_id,
uint32_t *designated_path_cost, int *tx_count,
int *rx_count, int *error_count, int *uptime)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
*id = p->port_id;
@@ -1440,7 +1415,6 @@ rstp_port_set(struct rstp_port *port, uint16_t port_num, int priority,
uint32_t path_cost, bool is_admin_edge, bool is_auto_edge,
enum rstp_admin_point_to_point_mac_state admin_p2p_mac_state,
bool admin_port_state, bool do_mcheck, void *aux)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
port->aux = aux;
@@ -1458,7 +1432,6 @@ rstp_port_set(struct rstp_port *port, uint16_t port_num, int priority,
/* Individual setters only used by test-rstp.c. */
void
rstp_port_set_priority(struct rstp_port *port, int priority)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_port_set_priority__(port, priority);
@@ -1467,7 +1440,6 @@ rstp_port_set_priority(struct rstp_port *port, int priority)
void
rstp_port_set_path_cost(struct rstp_port *port, uint32_t path_cost)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
rstp_port_set_path_cost__(port, path_cost);
@@ -1476,7 +1448,6 @@ rstp_port_set_path_cost(struct rstp_port *port, uint32_t path_cost)
void
rstp_port_set_aux(struct rstp_port *port, void *aux)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
port->aux = aux;
@@ -1501,7 +1472,6 @@ rstp_find(const char *name)
static void
rstp_unixctl_tcn(struct unixctl_conn *conn, int argc,
const char *argv[], void *aux OVS_UNUSED)
- OVS_EXCLUDED(rstp_mutex)
{
ovs_mutex_lock(&rstp_mutex);
if (argc > 1) {
@@ -137,109 +137,73 @@ static inline bool rstp_forward_in_state(enum rstp_state);
static inline bool rstp_learn_in_state(enum rstp_state);
static inline bool rstp_should_manage_bpdu(enum rstp_state state);
-void rstp_init(void)
- OVS_EXCLUDED(rstp_mutex);
+void rstp_init(void);
struct rstp * rstp_create(const char *, rstp_identifier bridge_id,
void (*send_bpdu)(struct dp_packet *, void *port_aux,
void *rstp_aux),
- void *aux)
- OVS_EXCLUDED(rstp_mutex);
+ void *aux);
-struct rstp *rstp_ref(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_unref(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
+struct rstp *rstp_ref(struct rstp *);
+void rstp_unref(struct rstp *);
/* Functions used outside RSTP, to call functions defined in
rstp-state-machines.h */
-void rstp_tick_timers(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
+void rstp_tick_timers(struct rstp *);
void rstp_port_received_bpdu(struct rstp_port *, const void *bpdu,
- size_t bpdu_size)
- OVS_EXCLUDED(rstp_mutex);
-void *rstp_check_and_reset_fdb_flush(struct rstp *, struct rstp_port **)
- OVS_EXCLUDED(rstp_mutex);
-void *rstp_get_next_changed_port_aux(struct rstp *, struct rstp_port **)
- OVS_EXCLUDED(rstp_mutex);
+ size_t bpdu_size);
+void *rstp_check_and_reset_fdb_flush(struct rstp *, struct rstp_port **);
+void *rstp_get_next_changed_port_aux(struct rstp *, struct rstp_port **);
void rstp_port_set_mac_operational(struct rstp_port *,
- bool new_mac_operational)
- OVS_EXCLUDED(rstp_mutex);
-bool rstp_shift_root_learned_address(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-void *rstp_get_old_root_aux(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-void *rstp_get_new_root_aux(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_reset_root_changed(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
+ bool new_mac_operational);
+bool rstp_shift_root_learned_address(struct rstp *);
+void *rstp_get_old_root_aux(struct rstp *);
+void *rstp_get_new_root_aux(struct rstp *);
+void rstp_reset_root_changed(struct rstp *);
/* Bridge setters */
-void rstp_set_bridge_address(struct rstp *, rstp_identifier bridge_address)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_set_bridge_priority(struct rstp *, int new_priority)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_set_bridge_ageing_time(struct rstp *, int new_ageing_time)
- OVS_EXCLUDED(rstp_mutex);
+void rstp_set_bridge_address(struct rstp *, rstp_identifier bridge_address);
+void rstp_set_bridge_priority(struct rstp *, int new_priority);
+void rstp_set_bridge_ageing_time(struct rstp *, int new_ageing_time);
void rstp_set_bridge_force_protocol_version(struct rstp *,
- enum rstp_force_protocol_version)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_set_bridge_max_age(struct rstp *, int new_max_age)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_set_bridge_forward_delay(struct rstp *, int new_forward_delay)
- OVS_EXCLUDED(rstp_mutex);
+ enum rstp_force_protocol_version);
+void rstp_set_bridge_max_age(struct rstp *, int new_max_age);
+void rstp_set_bridge_forward_delay(struct rstp *, int new_forward_delay);
void rstp_set_bridge_transmit_hold_count(struct rstp *,
- int new_transmit_hold_count)
- OVS_EXCLUDED(rstp_mutex);
+ int new_transmit_hold_count);
/* Bridge getters */
-const char * rstp_get_name(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-rstp_identifier rstp_get_root_id(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-rstp_identifier rstp_get_bridge_id(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-rstp_identifier rstp_get_designated_id(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-uint32_t rstp_get_root_path_cost(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-uint16_t rstp_get_designated_port_id(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-uint16_t rstp_get_bridge_port_id(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-struct rstp_port * rstp_get_root_port(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-rstp_identifier rstp_get_designated_root(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-bool rstp_is_root_bridge(const struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
+const char * rstp_get_name(const struct rstp *);
+rstp_identifier rstp_get_root_id(const struct rstp *);
+rstp_identifier rstp_get_bridge_id(const struct rstp *);
+rstp_identifier rstp_get_designated_id(const struct rstp *);
+uint32_t rstp_get_root_path_cost(const struct rstp *);
+uint16_t rstp_get_designated_port_id(const struct rstp *);
+uint16_t rstp_get_bridge_port_id(const struct rstp *);
+struct rstp_port * rstp_get_root_port(struct rstp *);
+rstp_identifier rstp_get_designated_root(const struct rstp *);
+bool rstp_is_root_bridge(const struct rstp *);
/* RSTP ports */
-struct rstp_port * rstp_add_port(struct rstp *)
- OVS_EXCLUDED(rstp_mutex);
-struct rstp_port *rstp_port_ref(const struct rstp_port *)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_port_unref(struct rstp_port *)
- OVS_EXCLUDED(rstp_mutex);
+struct rstp_port * rstp_add_port(struct rstp *);
+struct rstp_port *rstp_port_ref(const struct rstp_port *);
+void rstp_port_unref(struct rstp_port *);
uint32_t rstp_convert_speed_to_cost(unsigned int speed);
void rstp_port_set(struct rstp_port *, uint16_t port_num, int priority,
uint32_t path_cost, bool is_admin_edge, bool is_auto_edge,
enum rstp_admin_point_to_point_mac_state admin_p2p_mac_state,
- bool admin_port_state, bool do_mcheck, void *aux)
- OVS_EXCLUDED(rstp_mutex);
+ bool admin_port_state, bool do_mcheck, void *aux);
-enum rstp_state rstp_port_get_state(const struct rstp_port *)
- OVS_EXCLUDED(rstp_mutex);
+enum rstp_state rstp_port_get_state(const struct rstp_port *);
void rstp_port_get_status(const struct rstp_port *, uint16_t *id,
enum rstp_state *state, enum rstp_port_role *role,
rstp_identifier *designated_bridge_id,
uint16_t *designated_port_id,
uint32_t *designated_path_cost, int *tx_count,
- int *rx_count, int *error_count, int *uptime)
- OVS_EXCLUDED(rstp_mutex);
+ int *rx_count, int *error_count, int *uptime);
void * rstp_get_port_aux__(struct rstp *rstp, uint16_t port_number)
OVS_REQUIRES(rstp_mutex);
@@ -253,21 +217,14 @@ void rstp_port_set_state__(struct rstp_port *, enum rstp_state state)
/* Internal API for test-rstp.c */
-struct rstp_port *rstp_get_port(struct rstp *rstp, uint16_t port_number)
- OVS_EXCLUDED(rstp_mutex);
-void reinitialize_port(struct rstp_port *p)
- OVS_EXCLUDED(rstp_mutex);
-
-int rstp_port_get_number(const struct rstp_port *)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_port_set_priority(struct rstp_port *port, int priority)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_port_set_aux(struct rstp_port *p, void *aux)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_port_set_path_cost(struct rstp_port *port, uint32_t path_cost)
- OVS_EXCLUDED(rstp_mutex);
-void rstp_port_set_state(struct rstp_port *p, enum rstp_state state)
- OVS_EXCLUDED(rstp_mutex);
+struct rstp_port *rstp_get_port(struct rstp *rstp, uint16_t port_number);
+void reinitialize_port(struct rstp_port *p);
+
+int rstp_port_get_number(const struct rstp_port *);
+void rstp_port_set_priority(struct rstp_port *port, int priority);
+void rstp_port_set_aux(struct rstp_port *p, void *aux);
+void rstp_port_set_path_cost(struct rstp_port *port, uint32_t path_cost);
+void rstp_port_set_state(struct rstp_port *p, enum rstp_state state);
/* Inline functions. */
* This patch will be used for next patch. The 'rstp/show' command, which uses the mutex, calls functions which also use the mutex. We should init it as a recursive mutex. * Because of recursive mutex, this patch remove the OVS_EXCLUDED in list/rstp.[ch] files. * Some rstp tests of OvS, which run with ovstest, does not run rstp_init in the bridge_init. We should call rstp_init when creating the rstp and stp also do that, otherwise tests fail. Signed-off-by: nickcooper-zhangtonghao <nic@opencloud.tech> --- lib/rstp.c | 54 ++++++------------------- lib/rstp.h | 131 +++++++++++++++++++++---------------------------------------- 2 files changed, 56 insertions(+), 129 deletions(-)