Remove locking that is not needed.

Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 lib/tnl-ports.c |  102 ++++++++++++++++++++++---------------------------------
 1 file changed, 41 insertions(+), 61 deletions(-)

diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c
index 4dbda7d..e46dc58 100644
--- a/lib/tnl-ports.c
+++ b/lib/tnl-ports.c
@@ -18,44 +18,43 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "bitmap.h"
 #include "classifier.h"
-#include "coverage.h"
-#include "dpif-netdev.h"
 #include "fat-rwlock.h"
 #include "dynamic-string.h"
 #include "errno.h"
-#include "flow.h"
 #include "hash.h"
-#include "list.h"
-#include "netdev.h"
+#include "ofpbuf.h"
 #include "ovs-thread.h"
 #include "odp-util.h"
-#include "packet-dpif.h"
-#include "packets.h"
-#include "poll-loop.h"
-#include "timeval.h"
 #include "tnl-arp-cache.h"
 #include "tnl-ports.h"
-#include "tnl-ports.h"
-#include "unaligned.h"
 #include "unixctl.h"
 #include "util.h"
 
-static struct classifier cls;
-static struct ovs_mutex tunnel_mutex = OVS_MUTEX_INITIALIZER;
+static struct classifier cls;   /* Tunnel ports. */
 
-struct tunnel_ports {
+struct tunnel_port {
     struct cls_rule cr;
     odp_port_t portno;
     struct ovs_refcount ref_cnt;
     char dev_name[IFNAMSIZ];
 };
 
-static struct tunnel_ports *
+static struct tunnel_port *
 tnl_port_cast(const struct cls_rule *cr)
 {
-    return cr ? CONTAINER_OF(cr, struct tunnel_ports, cr) : NULL;
+    if (offsetof(struct tunnel_port, cr) == 0) {
+        return CONTAINER_OF(cr, struct tunnel_port, cr);
+    } else {
+        return cr ? CONTAINER_OF(cr, struct tunnel_port, cr) : NULL;
+    }
+}
+
+static void
+tnl_port_free(struct tunnel_port *p)
+{
+    cls_rule_destroy(&p->cr);
+    free(p);
 }
 
 void
@@ -63,58 +62,50 @@ tnl_port_insert_udp(odp_port_t port, ovs_be32 ip_dst, 
ovs_be16 udp_port,
                     const char dev_name[])
 {
     const struct cls_rule *cr;
-    struct tunnel_ports *p;
-    struct flow_wildcards wc;
+    struct tunnel_port *p;
     struct match match;
-    struct flow flow;
 
-    memset(&flow, 0, sizeof flow);
+    memset(&match, 0, sizeof match);
 
-    flow.dl_type = htons(ETH_TYPE_IP);
-    flow.nw_proto = IPPROTO_UDP;
-    flow.tp_dst = udp_port;
-    flow.nw_src = ip_dst;
-
-    cr = classifier_lookup(&cls, &flow, NULL);
-    if (cr) {
-        struct tunnel_ports *p;
+    match.flow.dl_type = htons(ETH_TYPE_IP);
+    match.flow.nw_proto = IPPROTO_UDP;
+    match.flow.tp_dst = udp_port;
+    match.flow.nw_src = ip_dst;
 
+    do {
+        cr = classifier_lookup(&cls, &match.flow, NULL);
         p = tnl_port_cast(cr);
+        /* Try again if the rule was released before we get the reference. */
+    } while (p && !ovs_refcount_try_ref_rcu(&p->ref_cnt));
 
-        ovs_refcount_ref(&p->ref_cnt);
-        return;
+    if (p) {
+        return; /* Added refcount of an existing port. */
     }
 
     p = xzalloc(sizeof *p);
     p->portno = port;
 
-    memset(&wc, 0, sizeof(wc));
-    wc.masks.dl_type = 0xffff;
-    wc.masks.nw_proto = 0xff;
-    wc.masks.nw_frag = 0xff;
-    wc.masks.tp_dst = 0xffff;
-    wc.masks.nw_src = 0xffffffff;
+    match.wc.masks.dl_type = OVS_BE16_MAX;
+    match.wc.masks.nw_proto = 0xff;
+    match.wc.masks.nw_frag = 0xff;      /* XXX: No fragments support. */
+    match.wc.masks.tp_dst = OVS_BE16_MAX;
+    match.wc.masks.nw_src = OVS_BE32_MAX;
 
-    /* Need to check IP address. */
-    match_init(&match, &flow, &wc);
-    cls_rule_init(&p->cr, &match, 1);
+    cls_rule_init(&p->cr, &match, 0);   /* Priority == 0. */
     ovs_refcount_init(&p->ref_cnt);
     strncpy(p->dev_name, dev_name, IFNAMSIZ);
 
-    ovs_mutex_lock(&tunnel_mutex);
     classifier_insert(&cls, &p->cr);
-    ovs_mutex_unlock(&tunnel_mutex);
 }
 
 static void
 tnl_port_unref(struct cls_rule *cr)
 {
-    if (cr) {
-        struct tunnel_ports *p;
+    struct tunnel_port *p = tnl_port_cast(cr);
 
-        p = tnl_port_cast(cr);
-        if (ovs_refcount_unref_relaxed(&p->ref_cnt) == 1) {
-           classifier_remove(&cls, cr);
+    if (cr && ovs_refcount_unref_relaxed(&p->ref_cnt) == 1) {
+        if (classifier_remove(&cls, cr)) {
+            ovsrcu_postpone(tnl_port_free, p);
         }
     }
 }
@@ -131,25 +122,16 @@ tnl_port_delete(ovs_be32 ip_dst, ovs_be16 udp_port)
     flow.tp_dst = udp_port;
     flow.nw_src = ip_dst;
 
-    ovs_mutex_lock(&tunnel_mutex);
     cr = classifier_lookup(&cls, &flow, NULL);
     tnl_port_unref(cr);
-    ovs_mutex_unlock(&tunnel_mutex);
 }
 
 odp_port_t
 tnl_port_lookup(const struct flow *flow, struct flow_wildcards *wc)
 {
-    const struct cls_rule *cr;
-    const struct tunnel_ports *p;
+    const struct cls_rule *cr = classifier_lookup(&cls, flow, wc);
 
-    /* Un wildcard protocol and stuff */
-    cr = classifier_lookup(&cls, flow, wc);
-    if (!cr) {
-        return ODPP_NONE;
-    }
-    p = tnl_port_cast(cr);
-    return p->portno;
+    return (cr) ? tnl_port_cast(cr)->portno : ODPP_NONE;
 }
 
 static void
@@ -157,9 +139,8 @@ tnl_port_show(struct unixctl_conn *conn, int argc 
OVS_UNUSED,
               const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
 {
     struct ds ds = DS_EMPTY_INITIALIZER;
-    const struct tunnel_ports *p;
+    const struct tunnel_port *p;
 
-    ovs_mutex_lock(&tunnel_mutex);
     CLS_FOR_EACH(p, cr, &cls) {
         struct odputil_keybuf keybuf;
         struct odputil_keybuf maskbuf;
@@ -190,7 +171,6 @@ tnl_port_show(struct unixctl_conn *conn, int argc 
OVS_UNUSED,
         /* build string. */
         odp_flow_format(key, key_len, mask, mask_len, NULL, &ds, false);
     }
-    ovs_mutex_unlock(&tunnel_mutex);
     unixctl_command_reply(conn, ds_cstr(&ds));
     ds_destroy(&ds);
 }
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to