From: Jarno Rajahalme Date: Fri, 7 Feb 2014 19:34:01 +0000 (-0800) Subject: ofproto: Lock for vlan splinters only if have them. X-Git-Tag: sliver-openvswitch-2.1.90-1~1^2~62 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=7614e5d01c3b971c57d825111e412b1182cc04c8 ofproto: Lock for vlan splinters only if have them. Reading the hmap count for determining if it is empty or not is thread safe, so avoid locking when not necessary. Signed-off-by: Jarno Rajahalme Signed-off-by: Ben Pfaff --- diff --git a/lib/hmap.h b/lib/hmap.h index 76a73ac1a..445e74f0b 100644 --- a/lib/hmap.h +++ b/lib/hmap.h @@ -19,6 +19,7 @@ #include #include +#include "ovs-atomic.h" #include "util.h" #ifdef __cplusplus @@ -189,10 +190,13 @@ hmap_capacity(const struct hmap *hmap) } /* Returns true if 'hmap' currently contains no nodes, - * false otherwise. */ + * false otherwise. + * Note: While hmap in general is not thread-safe without additional locking, + * hmap_is_empty() is. */ static inline bool hmap_is_empty(const struct hmap *hmap) { + atomic_thread_fence(memory_order_acquire); return hmap->n == 0; } diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index ffcfdf9be..ccf0b750b 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -1780,19 +1780,18 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, &ctx->xout->odp_actions); flow->tunnel = flow_tnl; /* Restore tunnel metadata */ } else { - ofp_port_t vlandev_port; - odp_port = xport->odp_port; + out_port = odp_port; if (ofproto_has_vlan_splinters(ctx->xbridge->ofproto)) { + ofp_port_t vlandev_port; + wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI); - } - vlandev_port = vsp_realdev_to_vlandev(ctx->xbridge->ofproto, ofp_port, - flow->vlan_tci); - if (vlandev_port == ofp_port) { - out_port = odp_port; - } else { - out_port = ofp_port_to_odp_port(ctx->xbridge, vlandev_port); - flow->vlan_tci = htons(0); + vlandev_port = vsp_realdev_to_vlandev(ctx->xbridge->ofproto, + ofp_port, flow->vlan_tci); + if (vlandev_port != ofp_port) { + out_port = ofp_port_to_odp_port(ctx->xbridge, vlandev_port); + flow->vlan_tci = htons(0); + } } } diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 7b3e1eb64..f2ae600cd 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -4250,12 +4250,8 @@ bool ofproto_has_vlan_splinters(const struct ofproto_dpif *ofproto) OVS_EXCLUDED(ofproto->vsp_mutex) { - bool ret; - - ovs_mutex_lock(&ofproto->vsp_mutex); - ret = !hmap_is_empty(&ofproto->realdev_vid_map); - ovs_mutex_unlock(&ofproto->vsp_mutex); - return ret; + /* hmap_is_empty is thread safe. */ + return !hmap_is_empty(&ofproto->realdev_vid_map); } static ofp_port_t @@ -4293,6 +4289,10 @@ vsp_realdev_to_vlandev(const struct ofproto_dpif *ofproto, { ofp_port_t ret; + /* hmap_is_empty is thread safe, see if we can return immediately. */ + if (hmap_is_empty(&ofproto->realdev_vid_map)) { + return realdev_ofp_port; + } ovs_mutex_lock(&ofproto->vsp_mutex); ret = vsp_realdev_to_vlandev__(ofproto, realdev_ofp_port, vlan_tci); ovs_mutex_unlock(&ofproto->vsp_mutex); @@ -4356,6 +4356,11 @@ vsp_adjust_flow(const struct ofproto_dpif *ofproto, struct flow *flow) ofp_port_t realdev; int vid; + /* hmap_is_empty is thread safe. */ + if (hmap_is_empty(&ofproto->vlandev_map)) { + return false; + } + ovs_mutex_lock(&ofproto->vsp_mutex); realdev = vsp_vlandev_to_realdev(ofproto, flow->in_port.ofp_port, &vid); ovs_mutex_unlock(&ofproto->vsp_mutex);