public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
From: James Chapman <jchapman@katalix•com>
To: netdev@vger•kernel.org
Subject: [PATCH net-next-2.6 v4 10/14] l2tp: Convert rwlock to RCU
Date: Fri, 02 Apr 2010 17:19:16 +0100	[thread overview]
Message-ID: <20100402161916.11367.32252.stgit@bert.katalix.com> (raw)
In-Reply-To: <20100402161822.11367.70454.stgit@bert.katalix.com>

Reader/write locks are discouraged because they are slower than spin
locks. So this patch converts the rwlocks used in the per_net structs
to rcu.

Signed-off-by: James Chapman <jchapman@katalix•com>
---
 net/l2tp/l2tp_core.c |   78 +++++++++++++++++++++++++++-----------------------
 1 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index fbd1f21..473cf2d 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/list.h>
+#include <linux/rculist.h>
 #include <linux/uaccess.h>
 
 #include <linux/kernel.h>
@@ -105,9 +106,9 @@ static atomic_t l2tp_session_count;
 static unsigned int l2tp_net_id;
 struct l2tp_net {
 	struct list_head l2tp_tunnel_list;
-	rwlock_t l2tp_tunnel_list_lock;
+	spinlock_t l2tp_tunnel_list_lock;
 	struct hlist_head l2tp_session_hlist[L2TP_HASH_SIZE_2];
-	rwlock_t l2tp_session_hlist_lock;
+	spinlock_t l2tp_session_hlist_lock;
 };
 
 static inline struct l2tp_net *l2tp_pernet(struct net *net)
@@ -139,14 +140,14 @@ static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id)
 	struct l2tp_session *session;
 	struct hlist_node *walk;
 
-	read_lock_bh(&pn->l2tp_session_hlist_lock);
-	hlist_for_each_entry(session, walk, session_list, global_hlist) {
+	rcu_read_lock_bh();
+	hlist_for_each_entry_rcu(session, walk, session_list, global_hlist) {
 		if (session->session_id == session_id) {
-			read_unlock_bh(&pn->l2tp_session_hlist_lock);
+			rcu_read_unlock_bh();
 			return session;
 		}
 	}
-	read_unlock_bh(&pn->l2tp_session_hlist_lock);
+	rcu_read_unlock_bh();
 
 	return NULL;
 }
@@ -225,17 +226,17 @@ struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname)
 	struct hlist_node *walk;
 	struct l2tp_session *session;
 
-	read_lock_bh(&pn->l2tp_session_hlist_lock);
+	rcu_read_lock_bh();
 	for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++) {
-		hlist_for_each_entry(session, walk, &pn->l2tp_session_hlist[hash], global_hlist) {
+		hlist_for_each_entry_rcu(session, walk, &pn->l2tp_session_hlist[hash], global_hlist) {
 			if (!strcmp(session->ifname, ifname)) {
-				read_unlock_bh(&pn->l2tp_session_hlist_lock);
+				rcu_read_unlock_bh();
 				return session;
 			}
 		}
 	}
 
-	read_unlock_bh(&pn->l2tp_session_hlist_lock);
+	rcu_read_unlock_bh();
 
 	return NULL;
 }
@@ -248,14 +249,14 @@ struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id)
 	struct l2tp_tunnel *tunnel;
 	struct l2tp_net *pn = l2tp_pernet(net);
 
-	read_lock_bh(&pn->l2tp_tunnel_list_lock);
-	list_for_each_entry(tunnel, &pn->l2tp_tunnel_list, list) {
+	rcu_read_lock_bh();
+	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
 		if (tunnel->tunnel_id == tunnel_id) {
-			read_unlock_bh(&pn->l2tp_tunnel_list_lock);
+			rcu_read_unlock_bh();
 			return tunnel;
 		}
 	}
-	read_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	rcu_read_unlock_bh();
 
 	return NULL;
 }
@@ -267,15 +268,15 @@ struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth)
 	struct l2tp_tunnel *tunnel;
 	int count = 0;
 
-	read_lock_bh(&pn->l2tp_tunnel_list_lock);
-	list_for_each_entry(tunnel, &pn->l2tp_tunnel_list, list) {
+	rcu_read_lock_bh();
+	list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
 		if (++count > nth) {
-			read_unlock_bh(&pn->l2tp_tunnel_list_lock);
+			rcu_read_unlock_bh();
 			return tunnel;
 		}
 	}
 
-	read_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	rcu_read_unlock_bh();
 
 	return NULL;
 }
@@ -1167,9 +1168,10 @@ again:
 			if (tunnel->version != L2TP_HDR_VER_2) {
 				struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
 
-				write_lock_bh(&pn->l2tp_session_hlist_lock);
-				hlist_del_init(&session->global_hlist);
-				write_unlock_bh(&pn->l2tp_session_hlist_lock);
+				spin_lock_bh(&pn->l2tp_session_hlist_lock);
+				hlist_del_init_rcu(&session->global_hlist);
+				spin_unlock_bh(&pn->l2tp_session_hlist_lock);
+				synchronize_rcu();
 			}
 
 			if (session->session_close != NULL)
@@ -1206,9 +1208,10 @@ void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
 	       "%s: free...\n", tunnel->name);
 
 	/* Remove from tunnel list */
-	write_lock_bh(&pn->l2tp_tunnel_list_lock);
-	list_del_init(&tunnel->list);
-	write_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+	list_del_rcu(&tunnel->list);
+	spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	synchronize_rcu();
 
 	atomic_dec(&l2tp_tunnel_count);
 	kfree(tunnel);
@@ -1310,9 +1313,10 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
 
 	/* Add tunnel to our list */
 	INIT_LIST_HEAD(&tunnel->list);
-	write_lock_bh(&pn->l2tp_tunnel_list_lock);
-	list_add(&tunnel->list, &pn->l2tp_tunnel_list);
-	write_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+	list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+	spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+	synchronize_rcu();
 	atomic_inc(&l2tp_tunnel_count);
 
 	/* Bump the reference count. The tunnel context is deleted
@@ -1370,9 +1374,10 @@ void l2tp_session_free(struct l2tp_session *session)
 		if (tunnel->version != L2TP_HDR_VER_2) {
 			struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
 
-			write_lock_bh(&pn->l2tp_session_hlist_lock);
-			hlist_del_init(&session->global_hlist);
-			write_unlock_bh(&pn->l2tp_session_hlist_lock);
+			spin_lock_bh(&pn->l2tp_session_hlist_lock);
+			hlist_del_init_rcu(&session->global_hlist);
+			spin_unlock_bh(&pn->l2tp_session_hlist_lock);
+			synchronize_rcu();
 		}
 
 		if (session->session_id != 0)
@@ -1494,10 +1499,11 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
 		if (tunnel->version != L2TP_HDR_VER_2) {
 			struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
 
-			write_lock_bh(&pn->l2tp_session_hlist_lock);
-			hlist_add_head(&session->global_hlist,
-				       l2tp_session_id_hash_2(pn, session_id));
-			write_unlock_bh(&pn->l2tp_session_hlist_lock);
+			spin_lock_bh(&pn->l2tp_session_hlist_lock);
+			hlist_add_head_rcu(&session->global_hlist,
+					   l2tp_session_id_hash_2(pn, session_id));
+			spin_unlock_bh(&pn->l2tp_session_hlist_lock);
+			synchronize_rcu();
 		}
 
 		/* Ignore management session in session count value */
@@ -1524,12 +1530,12 @@ static __net_init int l2tp_init_net(struct net *net)
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&pn->l2tp_tunnel_list);
-	rwlock_init(&pn->l2tp_tunnel_list_lock);
+	spin_lock_init(&pn->l2tp_tunnel_list_lock);
 
 	for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++)
 		INIT_HLIST_HEAD(&pn->l2tp_session_hlist[hash]);
 
-	rwlock_init(&pn->l2tp_session_hlist_lock);
+	spin_lock_init(&pn->l2tp_session_hlist_lock);
 
 	err = net_assign_generic(net, l2tp_net_id, pn);
 	if (err)


  parent reply	other threads:[~2010-04-02 16:18 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-02 16:18 [PATCH net-next-2.6 v4 00/14] l2tp: Introduce L2TPv3 support James Chapman
2010-04-02 16:18 ` [PATCH net-next-2.6 v4 01/14] l2tp: Relocate pppol2tp driver to new net/l2tp directory James Chapman
2010-04-02 16:18 ` [PATCH net-next-2.6 v4 02/14] l2tp: Split pppol2tp patch into separate l2tp and ppp parts James Chapman
2010-04-02 16:18 ` [PATCH net-next-2.6 v4 03/14] ppp: Add ppp_dev_name() exported function James Chapman
2010-04-02 16:18 ` [PATCH net-next-2.6 v4 04/14] l2tp: Add ppp device name to L2TP ppp session data James Chapman
2010-04-02 16:18 ` [PATCH net-next-2.6 v4 05/14] l2tp: Add L2TPv3 protocol support James Chapman
2010-04-02 16:18 ` [PATCH net-next-2.6 v4 06/14] l2tp: Update PPP-over-L2TP driver to work over L2TPv3 James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 07/14] l2tp: Add L2TPv3 IP encapsulation (no UDP) support James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 08/14] netlink: Export genl_lock() API for use by modules James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 09/14] l2tp: Add netlink control API for L2TP James Chapman
2010-04-02 16:19 ` James Chapman [this message]
2010-04-20 16:55   ` [PATCH net-next-2.6 v4 10/14] l2tp: Convert rwlock to RCU Eric Dumazet
2010-04-21 13:53     ` James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 11/14] l2tp: Add L2TP ethernet pseudowire support James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 12/14] l2tp: Add debugfs files for dumping l2tp debug info James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 13/14] l2tp: Add support for static unmanaged L2TPv3 tunnels James Chapman
2010-04-02 16:19 ` [PATCH net-next-2.6 v4 14/14] l2tp: Update documentation James Chapman
2010-04-03 21:25 ` [PATCH net-next-2.6 v4 00/14] l2tp: Introduce L2TPv3 support David Miller
2010-04-03 22:04   ` David Miller
2010-04-04  7:54   ` Eric Dumazet
2010-04-04  8:02     ` David Miller
2010-04-04  8:14       ` Eric Dumazet

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=20100402161916.11367.32252.stgit@bert.katalix.com \
    --to=jchapman@katalix$(echo .)com \
    --cc=netdev@vger$(echo .)kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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