[ovs-dev] [thread 13/15] ofproto-dpif-xlate: Require a lock for reconfiguration.
Ethan Jackson
ethan at nicira.com
Thu Aug 8 19:58:32 UTC 2013
Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
ofproto/ofproto-dpif-xlate.c | 13 +++++++++++--
ofproto/ofproto-dpif-xlate.h | 22 +++++++++++++---------
ofproto/ofproto-dpif.c | 8 ++++++++
3 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index a258f24..0ac147a 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -55,6 +55,8 @@ VLOG_DEFINE_THIS_MODULE(ofproto_dpif_xlate);
* flow translation. */
#define MAX_RESUBMIT_RECURSION 64
+struct ovs_rwlock xlate_rwlock = OVS_RWLOCK_INITIALIZER;
+
struct xbridge {
struct hmap_node hmap_node; /* Node in global 'xbridges' map. */
struct ofproto_dpif *ofproto; /* Key in global 'xbridges' map. */
@@ -502,6 +504,7 @@ xlate_receive(const struct dpif_backer *backer, struct ofpbuf *packet,
const struct xport *xport;
int error = ENODEV;
+ ovs_rwlock_rdlock(&xlate_rwlock);
fitness = odp_flow_key_to_flow(key, key_len, flow);
if (fitness == ODP_FIT_ERROR) {
error = EINVAL;
@@ -553,6 +556,7 @@ exit:
if (fitnessp) {
*fitnessp = fitness;
}
+ ovs_rwlock_unlock(&xlate_rwlock);
return error;
}
@@ -2480,6 +2484,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
COVERAGE_INC(xlate_actions);
+ ovs_rwlock_rdlock(&xlate_rwlock);
+
/* Flow initialization rules:
* - 'base_flow' must match the kernel's view of the packet at the
* time that action processing starts. 'flow' represents any
@@ -2515,7 +2521,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
ctx.xbridge = xbridge_lookup(xin->ofproto);
if (!ctx.xbridge) {
- return;
+ goto out;
}
ctx.rule = xin->rule;
@@ -2572,7 +2578,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
break;
case OFPC_FRAG_DROP:
- return;
+ goto out;
case OFPC_FRAG_REASM:
NOT_REACHED();
@@ -2633,4 +2639,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
* use non-header fields as part of the cache. */
memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
+
+out:
+ ovs_rwlock_unlock(&xlate_rwlock);
}
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 881823b..1c37bc3 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -110,22 +110,24 @@ struct xlate_in {
const struct dpif_flow_stats *resubmit_stats;
};
+extern struct ovs_rwlock xlate_rwlock;
+
void xlate_ofproto_set(struct ofproto_dpif *, const char *name,
struct dpif *, struct rule_dpif *miss_rule,
struct rule_dpif *no_packet_in_rule,
const struct mac_learning *, struct stp *,
const struct mbridge *, const struct dpif_sflow *,
const struct dpif_ipfix *, enum ofp_config_flags,
- bool forward_bpdu, bool has_in_band, bool has_netflow);
-
-void xlate_remove_ofproto(struct ofproto_dpif *);
+ bool forward_bpdu, bool has_in_band, bool has_netflow)
+ OVS_REQ_WRLOCK(xlate_rwlock);
+void xlate_remove_ofproto(struct ofproto_dpif *) OVS_REQ_WRLOCK(xlate_rwlock);
void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *,
const char *name, enum port_vlan_mode, int vlan,
unsigned long *trunks, bool use_priority_tags,
const struct bond *, const struct lacp *,
- bool floodable);
-void xlate_bundle_remove(struct ofbundle *);
+ bool floodable) OVS_REQ_WRLOCK(xlate_rwlock);
+void xlate_bundle_remove(struct ofbundle *) OVS_REQ_WRLOCK(xlate_rwlock);
void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *,
struct ofport_dpif *, ofp_port_t, odp_port_t,
@@ -133,15 +135,17 @@ void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *,
const struct bfd *, struct ofport_dpif *peer,
int stp_port_no, const struct ofproto_port_queue *qdscp,
size_t n_qdscp, enum ofputil_port_config, bool is_tunnel,
- bool may_enable);
-void xlate_ofport_remove(struct ofport_dpif *);
+ bool may_enable) OVS_REQ_WRLOCK(xlate_rwlock);
+void xlate_ofport_remove(struct ofport_dpif *) OVS_REQ_WRLOCK(xlate_rwlock);
int xlate_receive(const struct dpif_backer *, struct ofpbuf *packet,
const struct nlattr *key, size_t key_len,
struct flow *, enum odp_key_fitness *,
- struct ofproto_dpif **, odp_port_t *odp_in_port);
+ struct ofproto_dpif **, odp_port_t *odp_in_port)
+ OVS_EXCLUDED(xlate_rwlock);
-void xlate_actions(struct xlate_in *, struct xlate_out *);
+void xlate_actions(struct xlate_in *, struct xlate_out *)
+ OVS_EXCLUDED(xlate_rwlock);
void xlate_in_init(struct xlate_in *, struct ofproto_dpif *,
const struct flow *, struct rule_dpif *,
uint8_t tcp_flags, const struct ofpbuf *packet);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index f4f46e5..47786b0 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -794,6 +794,7 @@ type_run(const char *type)
continue;
}
+ ovs_rwlock_wrlock(&xlate_rwlock);
xlate_ofproto_set(ofproto, ofproto->up.name,
ofproto->backer->dpif, ofproto->miss_rule,
ofproto->no_packet_in_rule, ofproto->ml,
@@ -824,6 +825,7 @@ type_run(const char *type)
ofport->up.pp.config, ofport->is_tunnel,
ofport->may_enable);
}
+ ovs_rwlock_unlock(&xlate_rwlock);
cls_cursor_init(&cursor, &ofproto->facets, NULL);
CLS_CURSOR_FOR_EACH_SAFE (facet, next, cr, &cursor) {
@@ -1444,7 +1446,9 @@ destruct(struct ofproto *ofproto_)
struct oftable *table;
ofproto->backer->need_revalidate = REV_RECONFIGURE;
+ ovs_rwlock_wrlock(&xlate_rwlock);
xlate_remove_ofproto(ofproto);
+ ovs_rwlock_unlock(&xlate_rwlock);
hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node);
complete_operations(ofproto);
@@ -1867,7 +1871,9 @@ port_destruct(struct ofport *port_)
const char *dp_port_name;
ofproto->backer->need_revalidate = REV_RECONFIGURE;
+ ovs_rwlock_wrlock(&xlate_rwlock);
xlate_ofport_remove(port);
+ ovs_rwlock_unlock(&xlate_rwlock);
dp_port_name = netdev_vport_get_dpif_port(port->up.netdev, namebuf,
sizeof namebuf);
@@ -2458,7 +2464,9 @@ bundle_destroy(struct ofbundle *bundle)
ofproto = bundle->ofproto;
mbridge_unregister_bundle(ofproto->mbridge, bundle->aux);
+ ovs_rwlock_wrlock(&xlate_rwlock);
xlate_bundle_remove(bundle);
+ ovs_rwlock_unlock(&xlate_rwlock);
LIST_FOR_EACH_SAFE (port, next_port, bundle_node, &bundle->ports) {
bundle_del_port(port);
--
1.7.9.5
More information about the dev
mailing list