From fccd7c092e09ce9767d34436bf9c70302c87c5f5 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 14 Nov 2014 15:58:09 -0800 Subject: classifier: Remove internal mutex. Almost all classifier users already exclude concurrent modifications, or are single-threaded, hence the classifier internal mutex can be removed. Due to this change, ovs-router.c and tnl-ports.c need new mutexes, which are added. As noted by Ben in review, ovs_router_flush() should also free the entries it removes from the classifier. It now calls ovsrcu_postpone() to that effect. Suggested-by: Ben Pfaff Signed-off-by: Jarno Rajahalme Acked-by: Ben Pfaff --- lib/tnl-ports.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'lib/tnl-ports.c') diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c index bcf055ba2..9832ef46d 100644 --- a/lib/tnl-ports.c +++ b/lib/tnl-ports.c @@ -26,9 +26,11 @@ #include "odp-util.h" #include "tnl-arp-cache.h" #include "tnl-ports.h" +#include "ovs-thread.h" #include "unixctl.h" #include "util.h" +static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; static struct classifier cls; /* Tunnel ports. */ struct tnl_port_in { @@ -80,30 +82,30 @@ tnl_port_map_insert(odp_port_t port, ovs_be32 ip_dst, ovs_be16 udp_port, memset(&match, 0, sizeof match); tnl_port_init_flow(&match.flow, ip_dst, udp_port); + ovs_mutex_lock(&mutex); 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)); - if (p) { - return; /* Added refcount of an existing port. */ - } - - p = xzalloc(sizeof *p); - p->portno = port; + if (!p) { + p = xzalloc(sizeof *p); + p->portno = port; - 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; + 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; - cls_rule_init(&p->cr, &match, 0); /* Priority == 0. */ - ovs_refcount_init(&p->ref_cnt); - strncpy(p->dev_name, dev_name, IFNAMSIZ); + cls_rule_init(&p->cr, &match, 0); /* Priority == 0. */ + ovs_refcount_init(&p->ref_cnt); + strncpy(p->dev_name, dev_name, IFNAMSIZ); - classifier_insert(&cls, &p->cr); + classifier_insert(&cls, &p->cr); + } + ovs_mutex_unlock(&mutex); } static void @@ -112,9 +114,11 @@ tnl_port_unref(const struct cls_rule *cr) struct tnl_port_in *p = tnl_port_cast(cr); if (cr && ovs_refcount_unref_relaxed(&p->ref_cnt) == 1) { + ovs_mutex_lock(&mutex); if (classifier_remove(&cls, cr)) { ovsrcu_postpone(tnl_port_free, p); } + ovs_mutex_unlock(&mutex); } } -- cgit v1.2.1