* [B.A.T.M.A.N.] [PATCHv4 1/2] batman-adv: Remove unnecessary hardif_list_lock
@ 2011-05-02 19:19 Sven Eckelmann
2011-05-02 19:19 ` [B.A.T.M.A.N.] [PATCHv4 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Sven Eckelmann
2011-05-03 9:51 ` [B.A.T.M.A.N.] (no subject) Linus Lüssing
0 siblings, 2 replies; 10+ messages in thread
From: Sven Eckelmann @ 2011-05-02 19:19 UTC (permalink / raw)
To: b.a.t.m.a.n
hardif_list_lock is unneccessary because we already ensure that no
multiple admin operations can take place through rtnl_lock.
hardif_list_lock only adds additional overhead and complexity.
Critical functions now check whether they are called with rtnl_lock
using ASSERT_RTNL.
It indirectly fixes the problem that orig_hash_del_if() expects that
only one interface is deleted from hardif_list at a time, but
hardif_remove_interfaces() removes all at once and then calls
orig_hash_del_if().
Reported-by: Linus Lüssing <linus.luessing@web.de>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Addressed Linus' comments:
* Merged patch 1/3 and 2/3 again
* Ensure that primary_if_select is only called with rtnl_lock through
hardif_enable_interface (was fixed in patch 3/3... but now in a
patch earlier)
* Add a comment above hardif_list to inform about needed locking
bat_sysfs.c | 2 ++
hard-interface.c | 30 +++++++-----------------------
main.c | 3 +++
3 files changed, 12 insertions(+), 23 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c
index e449bf6..85ba20d 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -502,7 +502,9 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
rtnl_unlock();
}
+ rtnl_lock();
ret = hardif_enable_interface(hard_iface, buff);
+ rtnl_unlock();
out:
hardif_free_ref(hard_iface);
diff --git a/hard-interface.c b/hard-interface.c
index 3e888f1..7e2f772 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -31,9 +31,6 @@
#include <linux/if_arp.h>
-/* protect update critical side of hardif_list - but not the content */
-static DEFINE_SPINLOCK(hardif_list_lock);
-
static int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
@@ -136,7 +133,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
struct hard_iface *curr_hard_iface;
struct batman_packet *batman_packet;
- spin_lock_bh(&hardif_list_lock);
+ ASSERT_RTNL();
if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
new_hard_iface = NULL;
@@ -148,7 +145,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
hardif_free_ref(curr_hard_iface);
if (!new_hard_iface)
- goto out;
+ return;
batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
batman_packet->flags = PRIMARIES_FIRST_HOP;
@@ -161,9 +158,6 @@ static void primary_if_select(struct bat_priv *bat_priv,
* our new primary interface
*/
atomic_set(&bat_priv->hna_local_changed, 1);
-
-out:
- spin_unlock_bh(&hardif_list_lock);
}
static bool hardif_is_iface_up(struct hard_iface *hard_iface)
@@ -456,6 +450,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
struct hard_iface *hard_iface;
int ret;
+ ASSERT_RTNL();
+
ret = is_valid_iface(net_dev);
if (ret != 1)
goto out;
@@ -482,10 +478,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
atomic_set(&hard_iface->refcount, 2);
check_known_mac_addr(hard_iface->net_dev);
-
- spin_lock(&hardif_list_lock);
list_add_tail_rcu(&hard_iface->list, &hardif_list);
- spin_unlock(&hardif_list_lock);
return hard_iface;
@@ -499,6 +492,8 @@ out:
static void hardif_remove_interface(struct hard_iface *hard_iface)
{
+ ASSERT_RTNL();
+
/* first deactivate interface */
if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
@@ -514,20 +509,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
void hardif_remove_interfaces(void)
{
struct hard_iface *hard_iface, *hard_iface_tmp;
- struct list_head if_queue;
- INIT_LIST_HEAD(&if_queue);
-
- spin_lock(&hardif_list_lock);
+ rtnl_lock();
list_for_each_entry_safe(hard_iface, hard_iface_tmp,
&hardif_list, list) {
list_del_rcu(&hard_iface->list);
- list_add_tail(&hard_iface->list, &if_queue);
- }
- spin_unlock(&hardif_list_lock);
-
- rtnl_lock();
- list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
hardif_remove_interface(hard_iface);
}
rtnl_unlock();
@@ -556,9 +542,7 @@ static int hard_if_event(struct notifier_block *this,
hardif_deactivate_interface(hard_iface);
break;
case NETDEV_UNREGISTER:
- spin_lock(&hardif_list_lock);
list_del_rcu(&hard_iface->list);
- spin_unlock(&hardif_list_lock);
hardif_remove_interface(hard_iface);
break;
diff --git a/main.c b/main.c
index 709b33b..39feb5a 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,9 @@
#include "vis.h"
#include "hash.h"
+
+/* List manipulations on hardif_list have to be rtnl_lock()'ed,
+ * list traversals just rcu-locked */
struct list_head hardif_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
--
1.7.4.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [B.A.T.M.A.N.] [PATCHv4 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active
2011-05-02 19:19 [B.A.T.M.A.N.] [PATCHv4 1/2] batman-adv: Remove unnecessary hardif_list_lock Sven Eckelmann
@ 2011-05-02 19:19 ` Sven Eckelmann
2011-05-03 9:51 ` [B.A.T.M.A.N.] (no subject) Linus Lüssing
1 sibling, 0 replies; 10+ messages in thread
From: Sven Eckelmann @ 2011-05-02 19:19 UTC (permalink / raw)
To: b.a.t.m.a.n
The hard_if_event is called by the notifier with rtnl_lock and tries to
remove sysfs entries when a NETDEV_UNREGISTER event is received. This
will automatically take the s_active lock.
The s_active lock is also used when a new interface is added to a meshif
through sysfs. In that situation we cannot wait for the rntl_lock before
creating the actual batman-adv interface to prevent a deadlock. It is
still possible to try to get the rtnl_lock and immediately abort the
current operation when the trylock call failed.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Rebased on new merged patch 1/2
bat_sysfs.c | 18 +++++++++---------
soft-interface.c | 2 +-
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c
index 85ba20d..497a070 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -488,24 +488,24 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out;
+ if (!rtnl_trylock()) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+
if (status_tmp == IF_NOT_IN_USE) {
- rtnl_lock();
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- goto out;
+ goto unlock;
}
/* if the interface already is in use */
- if (hard_iface->if_status != IF_NOT_IN_USE) {
- rtnl_lock();
+ if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- }
- rtnl_lock();
ret = hardif_enable_interface(hard_iface, buff);
+
+unlock:
rtnl_unlock();
-
out:
hardif_free_ref(hard_iface);
return ret;
diff --git a/soft-interface.c b/soft-interface.c
index 1772e2b..a78e923 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -639,7 +639,7 @@ struct net_device *softif_create(char *name)
goto out;
}
- ret = register_netdev(soft_iface);
+ ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
--
1.7.4.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [B.A.T.M.A.N.] (no subject)
2011-05-02 19:19 [B.A.T.M.A.N.] [PATCHv4 1/2] batman-adv: Remove unnecessary hardif_list_lock Sven Eckelmann
2011-05-02 19:19 ` [B.A.T.M.A.N.] [PATCHv4 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Sven Eckelmann
@ 2011-05-03 9:51 ` Linus Lüssing
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Linus Lüssing
` (2 more replies)
1 sibling, 3 replies; 10+ messages in thread
From: Linus Lüssing @ 2011-05-03 9:51 UTC (permalink / raw)
To: b.a.t.m.a.n
With that tiny change, it now all works as expected and the patch 1/2 can also
be used and verified without having to add patch 2/2 as well. Hope I'm not
getting too picky :D.
Thanks for your effort again, Sven!
Cheers, Linus
^ permalink raw reply [flat|nested] 10+ messages in thread
* [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock
2011-05-03 9:51 ` [B.A.T.M.A.N.] (no subject) Linus Lüssing
@ 2011-05-03 9:51 ` Linus Lüssing
2011-05-03 11:10 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
2011-05-04 14:50 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Marek Lindner
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
2011-05-03 12:40 ` [B.A.T.M.A.N.] (no subject) Sven Eckelmann
2 siblings, 2 replies; 10+ messages in thread
From: Linus Lüssing @ 2011-05-03 9:51 UTC (permalink / raw)
To: b.a.t.m.a.n
From: Sven Eckelmann <sven@narfation.org>
hardif_list_lock is unneccessary because we already ensure that no
multiple admin operations can take place through rtnl_lock.
hardif_list_lock only adds additional overhead and complexity.
Critical functions now check whether they are called with rtnl_lock
using ASSERT_RTNL.
It indirectly fixes the problem that orig_hash_del_if() expects that
only one interface is deleted from hardif_list at a time, but
hardif_remove_interfaces() removes all at once and then calls
orig_hash_del_if().
Reported-by: Linus Lüssing <linus.luessing@web.de>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
* Also doing the register_netdev->register_netdevice change one commit
earlier, as patch 1/2 would otherwise deadlock due to the rtnl_lock()
already being grabbed before the hardif_enable_interface() and
register_netdev() trying to get it again.
bat_sysfs.c | 2 ++
hard-interface.c | 30 +++++++-----------------------
main.c | 3 +++
soft-interface.c | 2 +-
4 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c
index e449bf6..85ba20d 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -502,7 +502,9 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
rtnl_unlock();
}
+ rtnl_lock();
ret = hardif_enable_interface(hard_iface, buff);
+ rtnl_unlock();
out:
hardif_free_ref(hard_iface);
diff --git a/hard-interface.c b/hard-interface.c
index 3e888f1..7e2f772 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -31,9 +31,6 @@
#include <linux/if_arp.h>
-/* protect update critical side of hardif_list - but not the content */
-static DEFINE_SPINLOCK(hardif_list_lock);
-
static int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
@@ -136,7 +133,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
struct hard_iface *curr_hard_iface;
struct batman_packet *batman_packet;
- spin_lock_bh(&hardif_list_lock);
+ ASSERT_RTNL();
if (new_hard_iface && !atomic_inc_not_zero(&new_hard_iface->refcount))
new_hard_iface = NULL;
@@ -148,7 +145,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
hardif_free_ref(curr_hard_iface);
if (!new_hard_iface)
- goto out;
+ return;
batman_packet = (struct batman_packet *)(new_hard_iface->packet_buff);
batman_packet->flags = PRIMARIES_FIRST_HOP;
@@ -161,9 +158,6 @@ static void primary_if_select(struct bat_priv *bat_priv,
* our new primary interface
*/
atomic_set(&bat_priv->hna_local_changed, 1);
-
-out:
- spin_unlock_bh(&hardif_list_lock);
}
static bool hardif_is_iface_up(struct hard_iface *hard_iface)
@@ -456,6 +450,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
struct hard_iface *hard_iface;
int ret;
+ ASSERT_RTNL();
+
ret = is_valid_iface(net_dev);
if (ret != 1)
goto out;
@@ -482,10 +478,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
atomic_set(&hard_iface->refcount, 2);
check_known_mac_addr(hard_iface->net_dev);
-
- spin_lock(&hardif_list_lock);
list_add_tail_rcu(&hard_iface->list, &hardif_list);
- spin_unlock(&hardif_list_lock);
return hard_iface;
@@ -499,6 +492,8 @@ out:
static void hardif_remove_interface(struct hard_iface *hard_iface)
{
+ ASSERT_RTNL();
+
/* first deactivate interface */
if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
@@ -514,20 +509,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
void hardif_remove_interfaces(void)
{
struct hard_iface *hard_iface, *hard_iface_tmp;
- struct list_head if_queue;
-
- INIT_LIST_HEAD(&if_queue);
- spin_lock(&hardif_list_lock);
+ rtnl_lock();
list_for_each_entry_safe(hard_iface, hard_iface_tmp,
&hardif_list, list) {
list_del_rcu(&hard_iface->list);
- list_add_tail(&hard_iface->list, &if_queue);
- }
- spin_unlock(&hardif_list_lock);
-
- rtnl_lock();
- list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
hardif_remove_interface(hard_iface);
}
rtnl_unlock();
@@ -556,9 +542,7 @@ static int hard_if_event(struct notifier_block *this,
hardif_deactivate_interface(hard_iface);
break;
case NETDEV_UNREGISTER:
- spin_lock(&hardif_list_lock);
list_del_rcu(&hard_iface->list);
- spin_unlock(&hardif_list_lock);
hardif_remove_interface(hard_iface);
break;
diff --git a/main.c b/main.c
index 709b33b..39feb5a 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,9 @@
#include "vis.h"
#include "hash.h"
+
+/* List manipulations on hardif_list have to be rtnl_lock()'ed,
+ * list traversals just rcu-locked */
struct list_head hardif_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/soft-interface.c b/soft-interface.c
index 1772e2b..a78e923 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -639,7 +639,7 @@ struct net_device *softif_create(char *name)
goto out;
}
- ret = register_netdev(soft_iface);
+ ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Linus Lüssing
@ 2011-05-03 11:10 ` Linus Lüssing
2011-05-04 14:57 ` Marek Lindner
2011-05-04 14:50 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Marek Lindner
1 sibling, 1 reply; 10+ messages in thread
From: Linus Lüssing @ 2011-05-03 11:10 UTC (permalink / raw)
To: b.a.t.m.a.n
From: Sven Eckelmann <sven@narfation.org>
The hard_if_event is called by the notifier with rtnl_lock and tries to
remove sysfs entries when a NETDEV_UNREGISTER event is received. This
will automatically take the s_active lock.
The s_active lock is also used when a new interface is added to a meshif
through sysfs. In that situation we cannot wait for the rntl_lock before
creating the actual batman-adv interface to prevent a deadlock. It is
still possible to try to get the rtnl_lock and immediately abort the
current operation when the trylock call failed.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
bat_sysfs.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c
index 85ba20d..497a070 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -488,24 +488,24 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out;
+ if (!rtnl_trylock()) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+
if (status_tmp == IF_NOT_IN_USE) {
- rtnl_lock();
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- goto out;
+ goto unlock;
}
/* if the interface already is in use */
- if (hard_iface->if_status != IF_NOT_IN_USE) {
- rtnl_lock();
+ if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- }
- rtnl_lock();
ret = hardif_enable_interface(hard_iface, buff);
- rtnl_unlock();
+unlock:
+ rtnl_unlock();
out:
hardif_free_ref(hard_iface);
return ret;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active
2011-05-03 11:10 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
@ 2011-05-04 14:57 ` Marek Lindner
0 siblings, 0 replies; 10+ messages in thread
From: Marek Lindner @ 2011-05-04 14:57 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
On Tuesday 03 May 2011 13:10:06 Linus Lüssing wrote:
> From: Sven Eckelmann <sven@narfation.org>
>
> The hard_if_event is called by the notifier with rtnl_lock and tries to
> remove sysfs entries when a NETDEV_UNREGISTER event is received. This
> will automatically take the s_active lock.
>
> The s_active lock is also used when a new interface is added to a meshif
> through sysfs. In that situation we cannot wait for the rntl_lock before
> creating the actual batman-adv interface to prevent a deadlock. It is
> still possible to try to get the rtnl_lock and immediately abort the
> current operation when the trylock call failed.
Applied in b278a6c.
Thanks,
Marek
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Linus Lüssing
2011-05-03 11:10 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
@ 2011-05-04 14:50 ` Marek Lindner
1 sibling, 0 replies; 10+ messages in thread
From: Marek Lindner @ 2011-05-04 14:50 UTC (permalink / raw)
To: The list for a Better Approach To Mobile Ad-hoc Networking
On Tuesday 03 May 2011 11:51:38 Linus Lüssing wrote:
> hardif_list_lock is unneccessary because we already ensure that no
> multiple admin operations can take place through rtnl_lock.
> hardif_list_lock only adds additional overhead and complexity.
>
> Critical functions now check whether they are called with rtnl_lock
> using ASSERT_RTNL.
>
> It indirectly fixes the problem that orig_hash_del_if() expects that
> only one interface is deleted from hardif_list at a time, but
> hardif_remove_interfaces() removes all at once and then calls
> orig_hash_del_if().
Applied in revision 7e95055.
Thanks,
Marek
^ permalink raw reply [flat|nested] 10+ messages in thread
* [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active
2011-05-03 9:51 ` [B.A.T.M.A.N.] (no subject) Linus Lüssing
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Linus Lüssing
@ 2011-05-03 9:51 ` Linus Lüssing
2011-05-03 12:40 ` [B.A.T.M.A.N.] (no subject) Sven Eckelmann
2 siblings, 0 replies; 10+ messages in thread
From: Linus Lüssing @ 2011-05-03 9:51 UTC (permalink / raw)
To: b.a.t.m.a.n
From: Sven Eckelmann <sven@narfation.org>
The hard_if_event is called by the notifier with rtnl_lock and tries to
remove sysfs entries when a NETDEV_UNREGISTER event is received. This
will automatically take the s_active lock.
The s_active lock is also used when a new interface is added to a meshif
through sysfs. In that situation we cannot wait for the rntl_lock before
creating the actual batman-adv interface to prevent a deadlock. It is
still possible to try to get the rtnl_lock and immediately abort the
current operation when the trylock call failed.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
bat_sysfs.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c
index 85ba20d..497a070 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -488,24 +488,24 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out;
+ if (!rtnl_trylock()) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+
if (status_tmp == IF_NOT_IN_USE) {
- rtnl_lock();
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- goto out;
+ goto unlock;
}
/* if the interface already is in use */
- if (hard_iface->if_status != IF_NOT_IN_USE) {
- rtnl_lock();
+ if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
- rtnl_unlock();
- }
- rtnl_lock();
ret = hardif_enable_interface(hard_iface, buff);
- rtnl_unlock();
+unlock:
+ rtnl_unlock();
out:
hardif_free_ref(hard_iface);
return ret;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [B.A.T.M.A.N.] (no subject)
2011-05-03 9:51 ` [B.A.T.M.A.N.] (no subject) Linus Lüssing
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Linus Lüssing
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
@ 2011-05-03 12:40 ` Sven Eckelmann
2 siblings, 0 replies; 10+ messages in thread
From: Sven Eckelmann @ 2011-05-03 12:40 UTC (permalink / raw)
To: b.a.t.m.a.n
[-- Attachment #1: Type: Text/Plain, Size: 394 bytes --]
On Tuesday 03 May 2011 11:51:37 Linus Lüssing wrote:
> With that tiny change, it now all works as expected and the patch 1/2 can
> also be used and verified without having to add patch 2/2 as well. Hope
> I'm not getting too picky :D.
>
> Thanks for your effort again, Sven!
No, I am very happy with your changes. I think that it can be applied with
your changes.
thanks,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock
@ 2011-04-29 20:00 Sven Eckelmann
0 siblings, 0 replies; 10+ messages in thread
From: Sven Eckelmann @ 2011-04-29 20:00 UTC (permalink / raw)
To: b.a.t.m.a.n
hardif_list_lock is unneccessary because we already ensure that no
multiple admin operations can take place through rtnl_lock.
hardif_list_lock only adds additional overhead and complexity.
Critical functions now check whether they are called with rtnl_lock
using ASSERT_RTNL.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
hard-interface.c | 23 +++++------------------
1 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/hard-interface.c b/hard-interface.c
index b3058e4..ebd7ef0 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -31,9 +31,6 @@
#include <linux/if_arp.h>
-/* protect update critical side of hardif_list - but not the content */
-static DEFINE_SPINLOCK(hardif_list_lock);
-
static int batman_skb_recv(struct sk_buff *skb,
struct net_device *dev,
@@ -432,6 +429,8 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
struct hard_iface *hard_iface;
int ret;
+ ASSERT_RTNL();
+
ret = is_valid_iface(net_dev);
if (ret != 1)
goto out;
@@ -458,10 +457,7 @@ static struct hard_iface *hardif_add_interface(struct net_device *net_dev)
atomic_set(&hard_iface->refcount, 2);
check_known_mac_addr(hard_iface->net_dev);
-
- spin_lock(&hardif_list_lock);
list_add_tail_rcu(&hard_iface->list, &hardif_list);
- spin_unlock(&hardif_list_lock);
return hard_iface;
@@ -475,6 +471,8 @@ out:
static void hardif_remove_interface(struct hard_iface *hard_iface)
{
+ ASSERT_RTNL();
+
/* first deactivate interface */
if (hard_iface->if_status != IF_NOT_IN_USE)
hardif_disable_interface(hard_iface);
@@ -490,20 +488,11 @@ static void hardif_remove_interface(struct hard_iface *hard_iface)
void hardif_remove_interfaces(void)
{
struct hard_iface *hard_iface, *hard_iface_tmp;
- struct list_head if_queue;
- INIT_LIST_HEAD(&if_queue);
-
- spin_lock(&hardif_list_lock);
+ rtnl_lock();
list_for_each_entry_safe(hard_iface, hard_iface_tmp,
&hardif_list, list) {
list_del_rcu(&hard_iface->list);
- list_add_tail(&hard_iface->list, &if_queue);
- }
- spin_unlock(&hardif_list_lock);
-
- rtnl_lock();
- list_for_each_entry_safe(hard_iface, hard_iface_tmp, &if_queue, list) {
hardif_remove_interface(hard_iface);
}
rtnl_unlock();
@@ -531,9 +520,7 @@ static int hard_if_event(struct notifier_block *this,
hardif_deactivate_interface(hard_iface);
break;
case NETDEV_UNREGISTER:
- spin_lock(&hardif_list_lock);
list_del_rcu(&hard_iface->list);
- spin_unlock(&hardif_list_lock);
hardif_remove_interface(hard_iface);
break;
--
1.7.4.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-05-04 14:57 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-02 19:19 [B.A.T.M.A.N.] [PATCHv4 1/2] batman-adv: Remove unnecessary hardif_list_lock Sven Eckelmann
2011-05-02 19:19 ` [B.A.T.M.A.N.] [PATCHv4 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Sven Eckelmann
2011-05-03 9:51 ` [B.A.T.M.A.N.] (no subject) Linus Lüssing
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Linus Lüssing
2011-05-03 11:10 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
2011-05-04 14:57 ` Marek Lindner
2011-05-04 14:50 ` [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Marek Lindner
2011-05-03 9:51 ` [B.A.T.M.A.N.] [PATCH 2/2] batman-adv: Avoid deadlock between rtnl_lock and s_active Linus Lüssing
2011-05-03 12:40 ` [B.A.T.M.A.N.] (no subject) Sven Eckelmann
-- strict thread matches above, loose matches on Subject: below --
2011-04-29 20:00 [B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Remove unnecessary hardif_list_lock Sven Eckelmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).