[B.A.T.M.A.N.] [PATCHv3] batman-adv: postpone sysfs removal when unregistering

2013-01-11 Thread Simon Wunderlich
When processing the unregister notify for a hard interface, removing
the sysfs files may lead to a circular deadlock (rtnl mutex -
s_active).

To overcome this problem, postpone the sysfs removal in a worker.

Reported-by: Sasha Levin sasha.le...@oracle.com
Reported-by: Sven Eckelmann s...@narfation.org
Signed-off-by: Simon Wunderlich s...@hrz.tu-chemnitz.de
---
Changes from PATCHv2:
 * kerneldoc for functions

Changes from PATCHv1:
 * INIT_WORK() in respective struct initialization functions
 * kerneldoc

Changes from RFCv1:
 * use work_struct properly, instead of delayed_work
 * postpone for softifs as well as for hardifs

Postponing the sysfs removal for the hardif unregister is easier than
other alternatives involving deferring. This should bring us to the
same level to the bridge code, which also messes with sysfs in the
notifier processing function, and uses rtnl_trylock when called
from within sysfs.

As far as I could understand the net/core code, only the unregister
case is the critical one, so the original bug should hopefully be
fixed.
---
 hard-interface.c |   24 ++--
 soft-interface.c |   32 +---
 types.h  |6 ++
 3 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/hard-interface.c b/hard-interface.c
index 78cf350..368219e 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -457,6 +457,24 @@ out:
batadv_hardif_free_ref(primary_if);
 }
 
+/**
+ * batadv_hardif_remove_interface_finish - cleans up the remains of a hardif
+ * @work: work queue item
+ *
+ * Free the parts of the hard interface which can not be removed under
+ * rtnl lock (to prevent deadlock situations).
+ */
+static void batadv_hardif_remove_interface_finish(struct work_struct *work)
+{
+   struct batadv_hard_iface *hard_iface;
+
+   hard_iface = container_of(work, struct batadv_hard_iface,
+ cleanup_work);
+
+   batadv_sysfs_del_hardif(hard_iface-hardif_obj);
+   batadv_hardif_free_ref(hard_iface);
+}
+
 static struct batadv_hard_iface *
 batadv_hardif_add_interface(struct net_device *net_dev)
 {
@@ -484,6 +502,9 @@ batadv_hardif_add_interface(struct net_device *net_dev)
hard_iface-soft_iface = NULL;
hard_iface-if_status = BATADV_IF_NOT_IN_USE;
INIT_LIST_HEAD(hard_iface-list);
+   INIT_WORK(hard_iface-cleanup_work,
+ batadv_hardif_remove_interface_finish);
+
/* extra reference for return */
atomic_set(hard_iface-refcount, 2);
 
@@ -518,8 +539,7 @@ static void batadv_hardif_remove_interface(struct 
batadv_hard_iface *hard_iface)
return;
 
hard_iface-if_status = BATADV_IF_TO_BE_REMOVED;
-   batadv_sysfs_del_hardif(hard_iface-hardif_obj);
-   batadv_hardif_free_ref(hard_iface);
+   queue_work(batadv_event_workqueue, hard_iface-cleanup_work);
 }
 
 void batadv_hardif_remove_interfaces(void)
diff --git a/soft-interface.c b/soft-interface.c
index e67e013..2711e87 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -449,6 +449,30 @@ static void batadv_interface_setup(struct net_device *dev)
memset(priv, 0, sizeof(*priv));
 }
 
+/**
+ * batadv_softif_destroy_finish - cleans up the remains of a softif
+ * @work: work queue item
+ *
+ * Free the parts of the soft interface which can not be removed under
+ * rtnl lock (to prevent deadlock situations).
+ */
+static void batadv_softif_destroy_finish(struct work_struct *work)
+{
+   struct batadv_priv *bat_priv;
+   struct net_device *soft_iface;
+
+   bat_priv = container_of(work, struct batadv_priv,
+   cleanup_work);
+   soft_iface = bat_priv-soft_iface;
+
+   batadv_debugfs_del_meshif(soft_iface);
+   batadv_sysfs_del_meshif(soft_iface);
+
+   rtnl_lock();
+   unregister_netdevice(soft_iface);
+   rtnl_unlock();
+}
+
 struct net_device *batadv_softif_create(const char *name)
 {
struct net_device *soft_iface;
@@ -463,6 +487,8 @@ struct net_device *batadv_softif_create(const char *name)
goto out;
 
bat_priv = netdev_priv(soft_iface);
+   bat_priv-soft_iface = soft_iface;
+   INIT_WORK(bat_priv-cleanup_work, batadv_softif_destroy_finish);
 
/* batadv_interface_stats() needs to be available as soon as
 * register_netdevice() has been called
@@ -551,10 +577,10 @@ out:
 
 void batadv_softif_destroy(struct net_device *soft_iface)
 {
-   batadv_debugfs_del_meshif(soft_iface);
-   batadv_sysfs_del_meshif(soft_iface);
+   struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+
batadv_mesh_free(soft_iface);
-   unregister_netdevice(soft_iface);
+   queue_work(batadv_event_workqueue, bat_priv-cleanup_work);
 }
 
 int batadv_softif_is_valid(const struct net_device *net_dev)
diff --git a/types.h b/types.h
index 89ac1fb..4cd87a0 100644
--- a/types.h
+++ b/types.h
@@ -68,6 +68,7 @@ struct 

[B.A.T.M.A.N.] Batman-adv 2012.4.0 into attitude adjustment

2013-01-11 Thread HeXiLeD
I have posted this question on irc but since i may not be available on
irc today here it goes again.

I need to build 2012.4 into openwrt attitude adjustment which uses 3.3
kernel. By default this is not available through openwrt feeds which is
providing batman 2012.3.0

Which batman-adv feed should i use if there is one available ?

This
(http://www.open-mesh.org/projects/batman-adv/wiki/Building-with-openwrt)
takes me to git (batman-adv-devel) which i might not want  need. Will
change the revision help ?

If i am not mistaken; unless  batman-adv 2012.4.0 is moved by someone
from openwrt trunk to openwrt attitude adjustment i am not able to find
a feed that provides me what i need and build batman-adv 2012.4.0 with
attitude adjustment (kernel 3.3)

What are my options ?








Re: [B.A.T.M.A.N.] [OpenWrt-Devel] Batman-adv 2012.4.0 into attitude adjustment

2013-01-11 Thread Gui Iribarren
IIRC the openwrt package uses the out-of-kernel-tree batman release,
i.e. it doesn't depend on a particular kernel version.

So manually updating the package version in the makefile of your
openwrt AA build environment should work.
You don't need to add batman-adv feed in this case - having the 'packages'
official feed is enough.

What follows is taken from trunk, to serve you as a reference.

~/openwrt/ $ head feeds/packages/net/batman-adv/Makefile
PKG_VERSION:=2012.4.0
BATCTL_VERSION:=2012.4.0
PKG_MD5SUM:=24e922a64a507b146c32c585538407f2
BATCTL_MD5SUM:=79d5aa796ae8b008a9fa42c27d4da2c1

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)

hope that helps,

Cheers!

On Fri, Jan 11, 2013 at 7:37 AM, HeXiLeD hexi...@nixbits.net wrote:
 Which batman-adv feed should i use if there is one available ?

 This
 (http://www.open-mesh.org/projects/batman-adv/wiki/Building-with-openwrt)
 takes me to git (batman-adv-devel) which i might not want  need. Will
 change the revision help ?

 If i am not mistaken; unless  batman-adv 2012.4.0 is moved by someone
 from openwrt trunk to openwrt attitude adjustment i am not able to find
 a feed that provides me what i need and build batman-adv 2012.4.0 with
 attitude adjustment (kernel 3.3)

 What are my options ?






 ___
 openwrt-devel mailing list
 openwrt-de...@lists.openwrt.org
 https://lists.openwrt.org/mailman/listinfo/openwrt-devel