[PATCH 077/368] Staging: batman-adv: Use forw_bcast_list_lock always with disabled interrupts

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Greg KH
Date: Thursday, March 4, 2010 - 1:04 pm

From: Sven Eckelmann <sven.eckelmann@gmx.de>

forw_bcast_list_lock is spin_locked in both process and softirq context.
SoftIRQ calls the spinlock with disabled IRQ and normal process context
with enabled IRQs.

When process context is inside an spin_locked area protected by
forw_bcast_list_lock and gets interrupted by an IRQ, it could happen
that something tries to lock forw_bcast_list_lock again in SoftIRQ
context. It cannot proceed further since the lock is already taken
somewhere else, but no reschedule will happen inside the SoftIRQ
context. This leads to an complete kernel hang without any chance of
resurrection.

All functions called in process context must disable IRQs when they try
to get get that lock to to prevent any reschedule due to IRQs.

Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Acked-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/staging/batman-adv/send.c |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index fc4953f..49b1534 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -338,12 +338,13 @@ static void forw_packet_free(struct forw_packet *forw_packet)
 static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
 				      unsigned long send_time)
 {
+	unsigned long flags;
 	INIT_HLIST_NODE(&forw_packet->list);
 
 	/* add new packet to packet list */
-	spin_lock(&forw_bcast_list_lock);
+	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_add_head(&forw_packet->list, &forw_bcast_list);
-	spin_unlock(&forw_bcast_list_lock);
+	spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 	/* start timer for this packet */
 	INIT_DELAYED_WORK(&forw_packet->delayed_work,
@@ -382,10 +383,11 @@ void send_outstanding_bcast_packet(struct work_struct *work)
 		container_of(work, struct delayed_work, work);
 	struct forw_packet *forw_packet =
 		container_of(delayed_work, struct forw_packet, delayed_work);
+	unsigned long flags;
 
-	spin_lock(&forw_bcast_list_lock);
+	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_del(&forw_packet->list);
-	spin_unlock(&forw_bcast_list_lock);
+	spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 	/* rebroadcast packet */
 	rcu_read_lock();
@@ -436,24 +438,25 @@ void purge_outstanding_packets(void)
 {
 	struct forw_packet *forw_packet;
 	struct hlist_node *tmp_node, *safe_tmp_node;
+	unsigned long flags;
 
 	bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
 
 	/* free bcast list */
-	spin_lock(&forw_bcast_list_lock);
+	spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
 				  &forw_bcast_list, list) {
 
-		spin_unlock(&forw_bcast_list_lock);
+		spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 		/**
 		 * send_outstanding_bcast_packet() will lock the list to
 		 * delete the item from the list
 		 */
 		cancel_delayed_work_sync(&forw_packet->delayed_work);
-		spin_lock(&forw_bcast_list_lock);
+		spin_lock_irqsave(&forw_bcast_list_lock, flags);
 	}
-	spin_unlock(&forw_bcast_list_lock);
+	spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
 
 	/* free batman packet list */
 	spin_lock(&forw_bat_list_lock);
-- 
1.7.0.1

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 043/368] Staging: add dt3155 driver, Greg KH, (Thu Mar 4, 1:03 pm)
[PATCH 045/368] Staging: dt3155: add TODO file, Greg KH, (Thu Mar 4, 1:03 pm)
[PATCH 077/368] Staging: batman-adv: Use forw_bcast_list_l ..., Greg KH, (Thu Mar 4, 1:04 pm)
[GIT PATCH] STAGING patches for 2.6.33-git, Greg KH, (Thu Mar 4, 1:04 pm)
[PATCH 190/368] Staging: et131x: kill EXP_ROM, Greg KH, (Thu Mar 4, 1:06 pm)
[PATCH 222/368] Staging: otus: fix memory leak, Greg KH, (Thu Mar 4, 1:06 pm)
[PATCH 264/368] staging: dream: Codestyle fix, Greg KH, (Thu Mar 4, 1:07 pm)
Re: [PATCH 264/368] staging: dream: Codestyle fix, Pavel Machek, (Fri Mar 5, 12:08 am)