#include <stdbool.h>
#include <stdlib.h>
+#include "ovs-atomic.h"
#include "util.h"
#ifdef __cplusplus
}
/* 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;
}
&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);
+ }
}
}
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
{
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);
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);