* 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 <[email protected]> --- lib/rstp.c | 54 ++++++------------------- lib/rstp.h | 131 +++++++++++++++++++++---------------------------------------- 2 files changed, 56 insertions(+), 129 deletions(-) diff --git a/lib/rstp.c b/lib/rstp.c index 907a907..9ad1b0d 100644 --- a/lib/rstp.c +++ b/lib/rstp.c @@ -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) { diff --git a/lib/rstp.h b/lib/rstp.h index 4942d59..7a08228 100644 --- a/lib/rstp.h +++ b/lib/rstp.h @@ -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. */ -- 1.8.3.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
