Signed-off-by: Ethan Jackson <et...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev