Author: marek Date: 2010-08-08 15:01:11 +0200 (Sun, 08 Aug 2010) New Revision: 1764
Modified: trunk/batman-adv/originator.c Log: batman-adv: unify orig_hash_lock spinlock handling to avoid deadlocks
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
Modified: trunk/batman-adv/originator.c =================================================================== --- trunk/batman-adv/originator.c 2010-08-08 13:01:05 UTC (rev 1763) +++ trunk/batman-adv/originator.c 2010-08-08 13:01:11 UTC (rev 1764) @@ -408,11 +408,12 @@ 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; @@ -421,11 +422,11 @@ 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; }
@@ -485,12 +486,13 @@ { 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; @@ -517,10 +519,10 @@ 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; }