linux-rt-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] fix might sleep oops in irq affinity callback hook
@ 2013-08-20 17:59 Joe Korty
  2013-08-21 15:53 ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 7+ messages in thread
From: Joe Korty @ 2013-08-20 17:59 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: linux-rt-users

Fix might_sleep oops in the irq affinity notifier logic.

Bug was due to the generic support function
irq_set_affinity() invoking schedule_work() underneath
a raw spin lock.  Our workaround is to move the
schedule_work() down a few lines to where the lock has
just been dropped.  This may not be ideal, as the resultant
code is a bit ugly.

This bug was discovered when the sfc networking driver
was loaded.  Perusal of the kernel source shows that the
mellanox and infiniband drivers are also likely to suffer
from this problem.

(applies to 3.6.11.6-rt38, appears to be applicable to
all later rt's and I expect it is valid for all earlier
rt's as well).

Signed-off-by: Joe Korty <joe.korty@ccur.com>

Index: b/kernel/irq/manage.c
===================================================================
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -163,7 +163,7 @@ int irq_do_set_affinity(struct irq_data 
 	return ret;
 }
 
-int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
+static int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
 {
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
 	struct irq_desc *desc = irq_data_to_desc(data);
@@ -179,10 +179,6 @@ int __irq_set_affinity_locked(struct irq
 		irq_copy_pending(desc, mask);
 	}
 
-	if (desc->affinity_notify) {
-		kref_get(&desc->affinity_notify->kref);
-		schedule_work(&desc->affinity_notify->work);
-	}
 	irqd_set(data, IRQD_AFFINITY_SET);
 
 	return ret;
@@ -205,7 +201,14 @@ int irq_set_affinity(unsigned int irq, c
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	ret =  __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask);
-	raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+	if (!ret && desc->affinity_notify) {
+		kref_get(&desc->affinity_notify->kref);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+		schedule_work(&desc->affinity_notify->work);
+	} else
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+
 	return ret;
 }
 
Index: b/include/linux/irq.h
===================================================================
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -381,7 +381,6 @@ extern void remove_percpu_irq(unsigned i
 
 extern void irq_cpu_online(void);
 extern void irq_cpu_offline(void);
-extern int __irq_set_affinity_locked(struct irq_data *data,  const struct cpumask *cpumask);
 
 #ifdef CONFIG_GENERIC_HARDIRQS
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-08-30 13:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-20 17:59 [PATCH] fix might sleep oops in irq affinity callback hook Joe Korty
2013-08-21 15:53 ` Sebastian Andrzej Siewior
2013-08-21 21:09   ` Joe Korty
2013-08-22 19:01     ` Joe Korty
2013-08-23  7:23       ` Sebastian Andrzej Siewior
2013-08-29 11:22       ` Sebastian Andrzej Siewior
2013-08-30 13:53         ` Joe Korty

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).