All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven.eckelmann@gmx.de>
To: b.a.t.m.a.n@lists.open-mesh.net
Subject: [B.A.T.M.A.N.] [PATCH 1/4] batman-adv: Introduce if_list_lock to protect if_list
Date: Thu, 16 Sep 2010 22:18:34 +0200	[thread overview]
Message-ID: <1284668317-19890-2-git-send-email-sven.eckelmann@gmx.de> (raw)
In-Reply-To: <1284668317-19890-1-git-send-email-sven.eckelmann@gmx.de>

The update critical sections of if_list must be protected by a locking
primitive other than RCU. The iterator must also be protected by the
chosen locking mechanism.

The rtnl_lock in hardif_remove_interfaces must also be moved outside the
iterator primitive to ensure that we don't deadlock the kernel due to
differently nested locks in hardif_remove_interfaces and hard_if_event.

Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
---
 batman-adv/hard-interface.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c
index edbfddf..3cd7cb1 100644
--- a/batman-adv/hard-interface.c
+++ b/batman-adv/hard-interface.c
@@ -35,6 +35,9 @@
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
+/* protect update critical side of if_list - but not the content */
+static DEFINE_SPINLOCK(if_list_lock);
+
 struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev)
 {
 	struct batman_if *batman_if;
@@ -402,7 +405,11 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
 	INIT_LIST_HEAD(&batman_if->list);
 
 	check_known_mac_addr(batman_if->net_dev->dev_addr);
+
+	spin_lock(&if_list_lock);
 	list_add_tail_rcu(&batman_if->list, &if_list);
+	spin_unlock(&if_list_lock);
+
 	return batman_if;
 
 free_if:
@@ -430,6 +437,8 @@ static void hardif_remove_interface(struct batman_if *batman_if)
 		return;
 
 	batman_if->if_status = IF_TO_BE_REMOVED;
+
+	/* caller must take if_list_lock */
 	list_del_rcu(&batman_if->list);
 	sysfs_del_hardif(&batman_if->hardif_obj);
 	dev_put(batman_if->net_dev);
@@ -440,11 +449,13 @@ void hardif_remove_interfaces(void)
 {
 	struct batman_if *batman_if, *batman_if_tmp;
 
+	rtnl_lock();
+	spin_lock(&if_list_lock);
 	list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
-		rtnl_lock();
 		hardif_remove_interface(batman_if);
-		rtnl_unlock();
 	}
+	spin_unlock(&if_list_lock);
+	rtnl_unlock();
 }
 
 static int hard_if_event(struct notifier_block *this,
@@ -469,7 +480,9 @@ static int hard_if_event(struct notifier_block *this,
 		hardif_deactivate_interface(batman_if);
 		break;
 	case NETDEV_UNREGISTER:
+		spin_lock(&if_list_lock);
 		hardif_remove_interface(batman_if);
+		spin_unlock(&if_list_lock);
 		break;
 	case NETDEV_CHANGEMTU:
 		if (batman_if->soft_iface)
-- 
1.7.2.3


  reply	other threads:[~2010-09-16 20:18 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-16 20:18 [B.A.T.M.A.N.] Initial rcu locking patchset Sven Eckelmann
2010-09-16 20:18 ` Sven Eckelmann [this message]
2010-09-16 20:18 ` [B.A.T.M.A.N.] [PATCH 2/4] batman-adv: Protect update side of gw_list Sven Eckelmann
2010-09-16 20:18 ` [B.A.T.M.A.N.] [PATCH 3/4] batman-adv: Always protect list_for_each_entry_rcu with RCU Sven Eckelmann
2010-09-16 20:18 ` [B.A.T.M.A.N.] [PATCH 4/4] batman-adv: Remove unneeded rcu_read_lock Sven Eckelmann
2010-09-16 21:22 ` [B.A.T.M.A.N.] Adding of basic gw_node/batman_if refcnt Sven Eckelmann
2010-09-17  1:17   ` Sven Eckelmann
2010-09-16 21:22 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Use refcnt to track usage count of gw_node Sven Eckelmann
2010-09-16 21:22 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Use refcnt to track usage count of batman_if Sven Eckelmann
2010-09-16 21:32   ` Sven Eckelmann

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=1284668317-19890-2-git-send-email-sven.eckelmann@gmx.de \
    --to=sven.eckelmann@gmx.de \
    --cc=b.a.t.m.a.n@lists.open-mesh.net \
    --cc=b.a.t.m.a.n@lists.open-mesh.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 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.