All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rémi Denis-Courmont" <remi@remlab.net>
To: netdev@vger.kernel.org
Cc: "Rémi Denis-Courmont" <remi.denis-courmont@nokia.com>
Subject: [PATCH net-next 2/2] Phonet: convert routing table to RCU
Date: Fri, 13 Nov 2009 17:01:19 +0200	[thread overview]
Message-ID: <1258124479-1167-2-git-send-email-remi@remlab.net> (raw)
In-Reply-To: <1258124479-1167-1-git-send-email-remi@remlab.net>

From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 net/phonet/pn_dev.c |   59 +++++++++++++++++++++++++++++---------------------
 1 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 6d64fda..3287f8f 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -34,7 +34,7 @@
 #include <net/phonet/pn_dev.h>
 
 struct phonet_routes {
-	spinlock_t		lock;
+	struct mutex		lock;
 	struct net_device	*table[64];
 };
 
@@ -248,17 +248,22 @@ static void phonet_route_autodel(struct net_device *dev)
 
 	/* Remove left-over Phonet routes */
 	bitmap_zero(deleted, 64);
-	spin_lock_bh(&pnn->routes.lock);
+	mutex_lock(&pnn->routes.lock);
 	for (i = 0; i < 64; i++)
 		if (dev == pnn->routes.table[i]) {
+			rcu_assign_pointer(pnn->routes.table[i], NULL);
 			set_bit(i, deleted);
-			pnn->routes.table[i] = NULL;
-			dev_put(dev);
 		}
-	spin_unlock_bh(&pnn->routes.lock);
+	mutex_unlock(&pnn->routes.lock);
+
+	if (bitmap_empty(deleted, 64))
+		return; /* short-circuit RCU */
+	synchronize_rcu();
 	for (i = find_first_bit(deleted, 64); i < 64;
-			i = find_next_bit(deleted, 64, i + 1))
+			i = find_next_bit(deleted, 64, i + 1)) {
 		rtm_phonet_notify(RTM_DELROUTE, dev, i);
+		dev_put(dev);
+	}
 }
 
 /* notify Phonet of device events */
@@ -300,7 +305,7 @@ static int phonet_init_net(struct net *net)
 
 	INIT_LIST_HEAD(&pnn->pndevs.list);
 	spin_lock_init(&pnn->pndevs.lock);
-	spin_lock_init(&pnn->routes.lock);
+	mutex_init(&pnn->routes.lock);
 	net_assign_generic(net, phonet_net_id, pnn);
 	return 0;
 }
@@ -361,13 +366,13 @@ int phonet_route_add(struct net_device *dev, u8 daddr)
 	int err = -EEXIST;
 
 	daddr = daddr >> 2;
-	spin_lock_bh(&routes->lock);
+	mutex_lock(&routes->lock);
 	if (routes->table[daddr] == NULL) {
-		routes->table[daddr] = dev;
+		rcu_assign_pointer(routes->table[daddr], dev);
 		dev_hold(dev);
 		err = 0;
 	}
-	spin_unlock_bh(&routes->lock);
+	mutex_unlock(&routes->lock);
 	return err;
 }
 
@@ -375,17 +380,20 @@ int phonet_route_del(struct net_device *dev, u8 daddr)
 {
 	struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id);
 	struct phonet_routes *routes = &pnn->routes;
-	int err = -ENOENT;
 
 	daddr = daddr >> 2;
-	spin_lock_bh(&routes->lock);
-	if (dev == routes->table[daddr]) {
-		routes->table[daddr] = NULL;
-		dev_put(dev);
-		err = 0;
-	}
-	spin_unlock_bh(&routes->lock);
-	return err;
+	mutex_lock(&routes->lock);
+	if (dev == routes->table[daddr])
+		rcu_assign_pointer(routes->table[daddr], NULL);
+	else
+		dev = NULL;
+	mutex_unlock(&routes->lock);
+
+	if (!dev)
+		return -ENOENT;
+	synchronize_rcu();
+	dev_put(dev);
+	return 0;
 }
 
 struct net_device *phonet_route_get(struct net *net, u8 daddr)
@@ -397,9 +405,9 @@ struct net_device *phonet_route_get(struct net *net, u8 daddr)
 	ASSERT_RTNL(); /* no need to hold the device */
 
 	daddr >>= 2;
-	spin_lock_bh(&routes->lock);
-	dev = routes->table[daddr];
-	spin_unlock_bh(&routes->lock);
+	rcu_read_lock();
+	dev = rcu_dereference(routes->table[daddr]);
+	rcu_read_unlock();
 	return dev;
 }
 
@@ -409,11 +417,12 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr)
 	struct phonet_routes *routes = &pnn->routes;
 	struct net_device *dev;
 
-	spin_lock_bh(&routes->lock);
-	dev = routes->table[daddr >> 2];
+	daddr >>= 2;
+	rcu_read_lock();
+	dev = rcu_dereference(routes->table[daddr]);
 	if (dev)
 		dev_hold(dev);
-	spin_unlock_bh(&routes->lock);
+	rcu_read_unlock();
 
 	if (!dev)
 		dev = phonet_device_get(net); /* Default route */
-- 
1.6.3.3


  reply	other threads:[~2009-11-13 15:01 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-13 15:01 [PATCH net-next 1/2] Phonet: put protocols array under RCU Rémi Denis-Courmont
2009-11-13 15:01 ` Rémi Denis-Courmont [this message]
2009-11-14  4:51   ` [PATCH net-next 2/2] Phonet: convert routing table to RCU David Miller
2009-11-14  4:51 ` [PATCH net-next 1/2] Phonet: put protocols array under RCU David Miller
2009-11-16 17:26 ` Paul E. McKenney
2009-11-16 17:34   ` Rémi Denis-Courmont

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=1258124479-1167-2-git-send-email-remi@remlab.net \
    --to=remi@remlab.net \
    --cc=netdev@vger.kernel.org \
    --cc=remi.denis-courmont@nokia.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.