Remove locking that is not needed.
Signed-off-by: Jarno Rajahalme <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev