From: Alex Wang Date: Tue, 10 Jun 2014 01:35:35 +0000 (-0700) Subject: cfm: Extracts the cfm status in one function. X-Git-Tag: v2.4.0~1963 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=685acfd9ff6679a0c6b4f3a53db6b633cf40472d;p=cascardo%2Fovs.git cfm: Extracts the cfm status in one function. This commit adds a new function, cfm_get_status(), for extracting all cfm status at once. This helps avoid the sequence of lock acquire/release in current implementation of status query. Signed-off-by: Alex Wang Acked-by: Ben Pfaff --- diff --git a/lib/cfm.c b/lib/cfm.c index c271e1e0b..447a0954d 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -925,26 +925,42 @@ cfm_get_health(const struct cfm *cfm) OVS_EXCLUDED(mutex) return health; } +static int +cfm_get_opup__(const struct cfm *cfm_) OVS_REQUIRES(mutex) +{ + struct cfm *cfm = CONST_CAST(struct cfm *, cfm_); + bool extended; + + atomic_read(&cfm->extended, &extended); + + return extended ? cfm->remote_opup : -1; +} + /* Gets the operational state of 'cfm'. 'cfm' is considered operationally down * if it has received a CCM with the operationally down bit set from any of its * remote maintenance points. Returns 1 if 'cfm' is operationally up, 0 if * 'cfm' is operationally down, or -1 if 'cfm' has no operational state * (because it isn't in extended mode). */ int -cfm_get_opup(const struct cfm *cfm_) OVS_EXCLUDED(mutex) +cfm_get_opup(const struct cfm *cfm) OVS_EXCLUDED(mutex) { - struct cfm *cfm = CONST_CAST(struct cfm *, cfm_); - bool extended; int opup; ovs_mutex_lock(&mutex); - atomic_read(&cfm->extended, &extended); - opup = extended ? cfm->remote_opup : -1; + opup = cfm_get_opup__(cfm); ovs_mutex_unlock(&mutex); return opup; } +static void +cfm_get_remote_mpids__(const struct cfm *cfm, uint64_t **rmps, size_t *n_rmps) + OVS_REQUIRES(mutex) +{ + *rmps = xmemdup(cfm->rmps_array, cfm->rmps_array_len * sizeof **rmps); + *n_rmps = cfm->rmps_array_len; +} + /* Populates 'rmps' with an array of remote maintenance points reachable by * 'cfm'. The number of remote maintenance points is written to 'n_rmps'. * 'cfm' retains ownership of the array written to 'rmps' */ @@ -953,8 +969,20 @@ cfm_get_remote_mpids(const struct cfm *cfm, uint64_t **rmps, size_t *n_rmps) OVS_EXCLUDED(mutex) { ovs_mutex_lock(&mutex); - *rmps = xmemdup(cfm->rmps_array, cfm->rmps_array_len * sizeof **rmps); - *n_rmps = cfm->rmps_array_len; + cfm_get_remote_mpids__(cfm, rmps, n_rmps); + ovs_mutex_unlock(&mutex); +} + +/* Extracts the status of 'cfm' and fills in the 's'. */ +void +cfm_get_status(const struct cfm *cfm, struct cfm_status *s) OVS_EXCLUDED(mutex) +{ + ovs_mutex_lock(&mutex); + s->faults = cfm_get_fault__(cfm); + s->remote_opstate = cfm_get_opup__(cfm); + s->flap_count = cfm->flap_count; + s->health = cfm->health; + cfm_get_remote_mpids__(cfm, &s->rmps, &s->n_rmps); ovs_mutex_unlock(&mutex); } diff --git a/lib/cfm.h b/lib/cfm.h index 13fdc60a6..a5d4cdf62 100644 --- a/lib/cfm.h +++ b/lib/cfm.h @@ -63,6 +63,29 @@ struct cfm_settings { bool check_tnl_key; /* Verify inbound packet key? */ }; +/* CFM status query. */ +struct cfm_status { + /* 0 if not faulted, otherwise a combination of one or more reasons. */ + enum cfm_fault_reason faults; + + /* 0 if the remote CFM endpoint is operationally down, + * 1 if the remote CFM endpoint is operationally up, + * -1 if we don't know because the remote CFM endpoint is not in extended + * mode. */ + int remote_opstate; + + uint64_t flap_count; + + /* Ordinarily a "health status" in the range 0...100 inclusive, with 0 + * being worst and 100 being best, or -1 if the health status is not + * well-defined. */ + int health; + + /* MPIDs of remote maintenance points whose CCMs have been received. */ + uint64_t *rmps; + size_t n_rmps; +}; + void cfm_init(void); struct cfm *cfm_create(const struct netdev *); struct cfm *cfm_ref(const struct cfm *); @@ -82,6 +105,7 @@ uint64_t cfm_get_flap_count(const struct cfm *); int cfm_get_health(const struct cfm *); int cfm_get_opup(const struct cfm *); void cfm_get_remote_mpids(const struct cfm *, uint64_t **rmps, size_t *n_rmps); +void cfm_get_status(const struct cfm *, struct cfm_status *); const char *cfm_fault_reason_to_str(int fault); long long int cfm_wake_time(struct cfm*); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index e6d88bc8b..9aa125545 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1811,18 +1811,14 @@ out: static int get_cfm_status(const struct ofport *ofport_, - struct ofproto_cfm_status *status) + struct cfm_status *status) { struct ofport_dpif *ofport = ofport_dpif_cast(ofport_); int ret = 0; if (ofport->cfm) { if (cfm_check_status_change(ofport->cfm)) { - status->faults = cfm_get_fault(ofport->cfm); - status->flap_count = cfm_get_flap_count(ofport->cfm); - status->remote_opstate = cfm_get_opup(ofport->cfm); - status->health = cfm_get_health(ofport->cfm); - cfm_get_remote_mpids(ofport->cfm, &status->rmps, &status->n_rmps); + cfm_get_status(ofport->cfm, status); } else { ret = NO_STATUS_CHANGE; } diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index c8d70e615..6e8cd9b8f 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -1360,7 +1360,7 @@ struct ofproto_class { * returned in 'status->rmps'. '*status' is indeterminate if the return * value is non-zero. */ int (*get_cfm_status)(const struct ofport *ofport, - struct ofproto_cfm_status *status); + struct cfm_status *status); /* Configures BFD on 'ofport'. * diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index a05a44402..fb9313b90 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3692,7 +3692,7 @@ ofproto_get_netflow_ids(const struct ofproto *ofproto, * '*status' is indeterminate if the return value is non-zero. */ int ofproto_port_get_cfm_status(const struct ofproto *ofproto, ofp_port_t ofp_port, - struct ofproto_cfm_status *status) + struct cfm_status *status) { struct ofport *ofport = ofproto_get_port(ofproto, ofp_port); return (ofport && ofproto->ofproto_class->get_cfm_status diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index de078b7ba..5f5e6c8ed 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -399,32 +399,9 @@ void ofproto_get_netflow_ids(const struct ofproto *, void ofproto_get_ofproto_controller_info(const struct ofproto *, struct shash *); void ofproto_free_ofproto_controller_info(struct shash *); -/* CFM status query. */ -struct ofproto_cfm_status { - /* 0 if not faulted, otherwise a combination of one or more reasons. */ - enum cfm_fault_reason faults; - - /* 0 if the remote CFM endpoint is operationally down, - * 1 if the remote CFM endpoint is operationally up, - * -1 if we don't know because the remote CFM endpoint is not in extended - * mode. */ - int remote_opstate; - - uint64_t flap_count; - - /* Ordinarily a "health status" in the range 0...100 inclusive, with 0 - * being worst and 100 being best, or -1 if the health status is not - * well-defined. */ - int health; - - /* MPIDs of remote maintenance points whose CCMs have been received. */ - uint64_t *rmps; - size_t n_rmps; -}; - int ofproto_port_get_cfm_status(const struct ofproto *, ofp_port_t ofp_port, - struct ofproto_cfm_status *); + struct cfm_status *); /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) * diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 9764c1f18..014ef6f8b 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1926,7 +1926,7 @@ static void iface_refresh_cfm_stats(struct iface *iface) { const struct ovsrec_interface *cfg = iface->cfg; - struct ofproto_cfm_status status; + struct cfm_status status; int error; error = ofproto_port_get_cfm_status(iface->port->bridge->ofproto,