aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2010-08-09 23:56:39 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-26 16:46:22 -0700
commit37b419b202eaebc97c05e598895ea16cbde112a7 (patch)
tree4d99a2419f561e1241a566397648ed2b71fc1199
parentcbdd4c098ba34731ceec62c47c36ec8e3d0d252e (diff)
Staging: batman-adv: unify orig_hash_lock spinlock handling to avoid deadlocks
commit 9abc10238e1df7ce81c58a441f65efd5e905b9e8 upstream. The orig_hash_lock spinlock always has to be locked with IRQs being disabled to avoid deadlocks between code that is being executed in IRQ context and code that is being executed in non-IRQ context. Reported-by: Sven Eckelmann <sven.eckelmann@gmx.de> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/batman-adv/originator.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c
index 568aef8371b..2177c5007f1 100644
--- a/drivers/staging/batman-adv/originator.c
+++ b/drivers/staging/batman-adv/originator.c
@@ -401,11 +401,12 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
{
struct orig_node *orig_node;
+ unsigned long flags;
HASHIT(hashit);
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -414,11 +415,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
goto err;
}
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
err:
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return -ENOMEM;
}
@@ -480,12 +481,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
{
struct batman_if *batman_if_tmp;
struct orig_node *orig_node;
+ unsigned long flags;
HASHIT(hashit);
int ret;
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -512,10 +514,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
rcu_read_unlock();
batman_if->if_num = -1;
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
err:
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return -ENOMEM;
}