netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 20/38] netfilter: nf_conncount: Move locking into count_tree()
Date: Fri, 20 Jul 2018 15:08:48 +0200	[thread overview]
Message-ID: <20180720130906.27687-21-pablo@netfilter.org> (raw)
In-Reply-To: <20180720130906.27687-1-pablo@netfilter.org>

From: Yi-Hung Wei <yihung.wei@gmail.com>

This patch is originally from Florian Westphal.

This is a preparation patch to allow lockless traversal
of the tree via RCU.

Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_conncount.c | 52 +++++++++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 27 deletions(-)

diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
index 7dfd9d5e6a3e..d1a4fd1c0f81 100644
--- a/net/netfilter/nf_conncount.c
+++ b/net/netfilter/nf_conncount.c
@@ -262,18 +262,26 @@ static void tree_nodes_free(struct rb_root *root,
 }
 
 static unsigned int
-count_tree(struct net *net, struct rb_root *root,
-	   const u32 *key, u8 keylen,
+count_tree(struct net *net,
+	   struct nf_conncount_data *data,
+	   const u32 *key,
 	   const struct nf_conntrack_tuple *tuple,
 	   const struct nf_conntrack_zone *zone)
 {
 	struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES];
+	struct rb_root *root;
 	struct rb_node **rbnode, *parent;
 	struct nf_conncount_rb *rbconn;
 	struct nf_conncount_tuple *conn;
-	unsigned int gc_count;
+	unsigned int gc_count, hash;
 	bool no_gc = false;
+	unsigned int count = 0;
+	u8 keylen = data->keylen;
 
+	hash = jhash2(key, data->keylen, conncount_rnd) % CONNCOUNT_SLOTS;
+	root = &data->root[hash];
+
+	spin_lock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]);
  restart:
 	gc_count = 0;
 	parent = NULL;
@@ -292,20 +300,20 @@ count_tree(struct net *net, struct rb_root *root,
 			rbnode = &((*rbnode)->rb_right);
 		} else {
 			/* same source network -> be counted! */
-			unsigned int count;
-
 			nf_conncount_lookup(net, &rbconn->list, tuple, zone,
 					    &addit);
 			count = rbconn->list.count;
 
 			tree_nodes_free(root, gc_nodes, gc_count);
 			if (!addit)
-				return count;
+				goto out_unlock;
 
 			if (!nf_conncount_add(&rbconn->list, tuple, zone))
-				return 0; /* hotdrop */
+				count = 0; /* hotdrop */
+				goto out_unlock;
 
-			return count + 1;
+			count++;
+			goto out_unlock;
 		}
 
 		if (no_gc || gc_count >= ARRAY_SIZE(gc_nodes))
@@ -328,18 +336,18 @@ count_tree(struct net *net, struct rb_root *root,
 		goto restart;
 	}
 
+	count = 0;
 	if (!tuple)
-		return 0;
-
+		goto out_unlock;
 	/* no match, need to insert new node */
 	rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC);
 	if (rbconn == NULL)
-		return 0;
+		goto out_unlock;
 
 	conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
 	if (conn == NULL) {
 		kmem_cache_free(conncount_rb_cachep, rbconn);
-		return 0;
+		goto out_unlock;
 	}
 
 	conn->tuple = *tuple;
@@ -348,10 +356,13 @@ count_tree(struct net *net, struct rb_root *root,
 
 	nf_conncount_list_init(&rbconn->list);
 	list_add(&conn->node, &rbconn->list.head);
+	count = 1;
 
 	rb_link_node(&rbconn->node, parent, rbnode);
 	rb_insert_color(&rbconn->node, root);
-	return 1;
+out_unlock:
+	spin_unlock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]);
+	return count;
 }
 
 /* Count and return number of conntrack entries in 'net' with particular 'key'.
@@ -363,20 +374,7 @@ unsigned int nf_conncount_count(struct net *net,
 				const struct nf_conntrack_tuple *tuple,
 				const struct nf_conntrack_zone *zone)
 {
-	struct rb_root *root;
-	int count;
-	u32 hash;
-
-	hash = jhash2(key, data->keylen, conncount_rnd) % CONNCOUNT_SLOTS;
-	root = &data->root[hash];
-
-	spin_lock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]);
-
-	count = count_tree(net, root, key, data->keylen, tuple, zone);
-
-	spin_unlock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]);
-
-	return count;
+	return count_tree(net, data, key, tuple, zone);
 }
 EXPORT_SYMBOL_GPL(nf_conncount_count);
 
-- 
2.11.0

  parent reply	other threads:[~2018-07-20 13:08 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-20 13:08 [PATCH 00/38] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 01/38] netfilter: nft_reject_bridge: remove unnecessary ttl set Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 02/38] netfilter: flowtables: use fixed renew timeout on teardown Pablo Neira Ayuso
2018-07-20 13:20   ` Felix Fietkau
2018-07-20 13:32     ` Florian Westphal
2018-07-20 13:08 ` [PATCH 03/38] netfilter: nft_tproxy: Move nf_tproxy_assign_sock() to nf_tproxy.h Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 04/38] netfilter: utils: move nf_ip_checksum* from ipv4 to utils Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 05/38] netfilter: utils: move nf_ip6_checksum* from ipv6 " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 06/38] openvswitch: use nf_ct_get_tuplepr, invert_tuplepr Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 07/38] netfilter: Kconfig: Make NETFILTER_XT_MATCH_SOCKET select NF_SOCKET_IPV4/6 Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 08/38] netfilter: conntrack: remove ctnetlink callbacks from l3 protocol trackers Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 09/38] netfilter: conntrack: remove pkt_to_tuple indirection " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 10/38] netfilter: conntrack: remove invert_tuple " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 11/38] netfilter: conntrack: remove get_l4proto " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 12/38] netfilter: conntrack: avoid calls to l4proto invert_tuple Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 13/38] netfilter: conntrack: avoid l4proto pkt_to_tuple calls Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 14/38] netfilter: conntrack: remove get_timeout() indirection Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 15/38] netfilter: conntrack: remove l3proto abstraction Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 16/38] netfilter: Kconfig: Change select IPv6 dependencies Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 17/38] netfilter: nf_conncount: Early exit for garbage collection Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 18/38] netfilter: nf_conncount: Switch to plain list Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 19/38] netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup Pablo Neira Ayuso
2018-07-20 13:08 ` Pablo Neira Ayuso [this message]
2018-07-20 13:08 ` [PATCH 21/38] netfilter: nf_conncount: Split insert and traversal Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 22/38] netfilter: nf_conncount: Add list lock and gc worker, and RCU for init tree search Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 23/38] netfilter: nf_conntrack: resolve clash for matching conntracks Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 24/38] ipvs: provide just conn to ip_vs_state_name Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 25/38] ipvs: add assured state for conn templates Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 26/38] ipvs: drop conn templates under attack Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 27/38] netfilter: Remove useless param helper of nf_ct_helper_ext_add Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 28/38] netfilter: nf_tables: add and use helper for module autoload Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 29/38] netfilter: nf_tables: make valid_genid callback mandatory Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 30/38] netfilter: nf_tables: take module reference when starting a batch Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 31/38] netfilter: nf_tables: avoid global info storage Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 32/38] netfilter: nf_tables: use dedicated mutex to guard transactions Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 33/38] netfilter: nf_osf: add nf_osf_match_one() Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 34/38] netfilter: nf_osf: add struct nf_osf_hdr_ctx Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 35/38] netfilter: nft_socket: Break evaluation if no socket found Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 36/38] netfilter: nft_socket: Expose socket mark Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 37/38] ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 38/38] netfilter: nf_osf: add missing definitions to header file Pablo Neira Ayuso
2018-07-21  6:33 ` [PATCH 00/38] Netfilter/IPVS updates for net-next David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180720130906.27687-21-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).