[commits] r1779 - trunk/batman-adv

postmaster at open-mesh.org postmaster at open-mesh.org
Sun Aug 29 02:02:47 CEST 2010


Author: marek
Date: 2010-08-29 02:02:13 +0200 (Sun, 29 Aug 2010)
New Revision: 1779

Modified:
   trunk/batman-adv/bat_sysfs.c
   trunk/batman-adv/hard-interface.c
   trunk/batman-adv/soft-interface.c
Log:
batman-adv: Don't call unregister_netdev with locked rtnl semaphore

We currently try to call unregister_netdev when we can destroy a softif
after all corresponding hard-interfaces announced that they will be
removed.

This will be done when we receive a hard_if_event which already takes
the rtnl semaphore and thus we try to get it again in unregister_netdev.
This results in a deadlock. This call to unregister_netdev cannot easily
replaced by unregister_netdevice, because other parts of the batman-adv
module still call that code indirectly without holding the rtnl
semaphore.

                    (needs rtln_unlocked)
                     unregister_netdev
                             ^
                             |
                       softif_destroy
                             ^
                             |
                  hardif_disable_interface
                 ^           ^
                /            |
store_mesh_iface   hardif_remove_interface
(rtln_unlocked)              ^            ^
                             |             \
                 hardif_remove_interfaces   hard_if_event
                             ^              (rtln_locked)
                             |
                        batman_exit
                      (rtln_unlocked)

A consistent workaround is to change store_mesh_iface and
hardif_remove_interfaces to call rtnl_lock before they call the
mentioned child function, release the semaphore afterwards and change
unregister_netdev in softif_destroy to unregister_netdevice.

Reported-by: Kazuki Shimada <zukky at bb.banban.jp>
Signed-off-by: Sven Eckelmann <sven.eckelmann at gmx.de>

Modified: trunk/batman-adv/bat_sysfs.c
===================================================================
--- trunk/batman-adv/bat_sysfs.c	2010-08-23 17:45:22 UTC (rev 1778)
+++ trunk/batman-adv/bat_sysfs.c	2010-08-29 00:02:13 UTC (rev 1779)
@@ -492,13 +492,18 @@
 		return count;
 
 	if (status_tmp == IF_NOT_IN_USE) {
+		rtnl_lock();
 		hardif_disable_interface(batman_if);
+		rtnl_unlock();
 		return count;
 	}
 
 	/* if the interface already is in use */
-	if (batman_if->if_status != IF_NOT_IN_USE)
+	if (batman_if->if_status != IF_NOT_IN_USE) {
+		rtnl_lock();
 		hardif_disable_interface(batman_if);
+		rtnl_unlock();
+	}
 
 	return hardif_enable_interface(batman_if, buff);
 }

Modified: trunk/batman-adv/hard-interface.c
===================================================================
--- trunk/batman-adv/hard-interface.c	2010-08-23 17:45:22 UTC (rev 1778)
+++ trunk/batman-adv/hard-interface.c	2010-08-29 00:02:13 UTC (rev 1779)
@@ -441,8 +441,11 @@
 {
 	struct batman_if *batman_if, *batman_if_tmp;
 
-	list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list)
+	list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
+		rtnl_lock();
 		hardif_remove_interface(batman_if);
+		rtnl_unlock();
+	}
 }
 
 static int hard_if_event(struct notifier_block *this,

Modified: trunk/batman-adv/soft-interface.c
===================================================================
--- trunk/batman-adv/soft-interface.c	2010-08-23 17:45:22 UTC (rev 1778)
+++ trunk/batman-adv/soft-interface.c	2010-08-29 00:02:13 UTC (rev 1779)
@@ -351,7 +351,7 @@
 	debugfs_del_meshif(soft_iface);
 	sysfs_del_meshif(soft_iface);
 	mesh_free(soft_iface);
-	unregister_netdev(soft_iface);
+	unregister_netdevice(soft_iface);
 }
 
 /* ethtool */



More information about the commits mailing list