linux-rt-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org,
	linux-rt-users <linux-rt-users@vger.kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Carsten Emde <C.Emde@osadl.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	John Kacur <jkacur@redhat.com>, <stable-rt@vger.kernel.org>
Subject: [PATCH RT 15/16] genirq: do not invoke the affinity callback via a workqueue
Date: Mon, 09 Sep 2013 08:48:00 -0400	[thread overview]
Message-ID: <20130909124801.672854008@goodmis.org> (raw)
In-Reply-To: 20130909124745.590777496@goodmis.org

[-- Attachment #1: 0015-genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch --]
[-- Type: text/plain, Size: 4445 bytes --]

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

Joe Korty reported, that __irq_set_affinity_locked() schedules a
workqueue while holding a rawlock which results in a might_sleep()
warning.
This patch moves the invokation into a process context so that we only
wakeup() a process while holding the lock.

Cc: stable-rt@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 include/linux/interrupt.h |    1 +
 kernel/irq/manage.c       |   79 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index f70a65b..42f79fb 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -271,6 +271,7 @@ struct irq_affinity_notify {
 	unsigned int irq;
 	struct kref kref;
 	struct work_struct work;
+	struct list_head list;
 	void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask);
 	void (*release)(struct kref *ref);
 };
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 2e8ca37..88a4ff5 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -141,6 +141,62 @@ static inline void
 irq_get_pending(struct cpumask *mask, struct irq_desc *desc) { }
 #endif
 
+#ifdef CONFIG_PREEMPT_RT_FULL
+static void _irq_affinity_notify(struct irq_affinity_notify *notify);
+static struct task_struct *set_affinity_helper;
+static LIST_HEAD(affinity_list);
+static DEFINE_RAW_SPINLOCK(affinity_list_lock);
+
+static int set_affinity_thread(void *unused)
+{
+	while (1) {
+		struct irq_affinity_notify *notify;
+		int empty;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		raw_spin_lock_irq(&affinity_list_lock);
+		empty = list_empty(&affinity_list);
+		raw_spin_unlock_irq(&affinity_list_lock);
+
+		if (empty)
+			schedule();
+		if (kthread_should_stop())
+			break;
+		set_current_state(TASK_RUNNING);
+try_next:
+		notify = NULL;
+
+		raw_spin_lock_irq(&affinity_list_lock);
+		if (!list_empty(&affinity_list)) {
+			notify = list_first_entry(&affinity_list,
+					struct irq_affinity_notify, list);
+			list_del_init(&notify->list);
+		}
+		raw_spin_unlock_irq(&affinity_list_lock);
+
+		if (!notify)
+			continue;
+		_irq_affinity_notify(notify);
+		goto try_next;
+	}
+	return 0;
+}
+
+static void init_helper_thread(void)
+{
+	if (set_affinity_helper)
+		return;
+	set_affinity_helper = kthread_run(set_affinity_thread, NULL,
+			"affinity-cb");
+	WARN_ON(IS_ERR(set_affinity_helper));
+}
+#else
+
+static inline void init_helper_thread(void) { }
+
+#endif
+
 int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
 {
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
@@ -166,7 +222,17 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
 
 	if (desc->affinity_notify) {
 		kref_get(&desc->affinity_notify->kref);
+
+#ifdef CONFIG_PREEMPT_RT_FULL
+		raw_spin_lock(&affinity_list_lock);
+		if (list_empty(&desc->affinity_notify->list))
+			list_add_tail(&affinity_list,
+					&desc->affinity_notify->list);
+		raw_spin_unlock(&affinity_list_lock);
+		wake_up_process(set_affinity_helper);
+#else
 		schedule_work(&desc->affinity_notify->work);
+#endif
 	}
 	irqd_set(data, IRQD_AFFINITY_SET);
 
@@ -207,10 +273,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
 }
 EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
 
-static void irq_affinity_notify(struct work_struct *work)
+static void _irq_affinity_notify(struct irq_affinity_notify *notify)
 {
-	struct irq_affinity_notify *notify =
-		container_of(work, struct irq_affinity_notify, work);
 	struct irq_desc *desc = irq_to_desc(notify->irq);
 	cpumask_var_t cpumask;
 	unsigned long flags;
@@ -232,6 +296,13 @@ out:
 	kref_put(&notify->kref, notify->release);
 }
 
+static void irq_affinity_notify(struct work_struct *work)
+{
+	struct irq_affinity_notify *notify =
+		container_of(work, struct irq_affinity_notify, work);
+	_irq_affinity_notify(notify);
+}
+
 /**
  *	irq_set_affinity_notifier - control notification of IRQ affinity changes
  *	@irq:		Interrupt for which to enable/disable notification
@@ -261,6 +332,8 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
 		notify->irq = irq;
 		kref_init(&notify->kref);
 		INIT_WORK(&notify->work, irq_affinity_notify);
+		INIT_LIST_HEAD(&notify->list);
+		init_helper_thread();
 	}
 
 	raw_spin_lock_irqsave(&desc->lock, flags);
-- 
1.7.10.4

  parent reply	other threads:[~2013-09-09 12:48 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-09 12:47 [PATCH RT 00/16] 3.2.50-rt71-rc1 stable review Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 01/16] sched/workqueue: Only wake up idle workers if not blocked on sleeping spin lock Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 02/16] x86/mce: fix mce timer interval Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 03/16] genirq: Set irq thread to RT priority on creation Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 04/16] list_bl.h: make list head locking RT safe Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 05/16] list_bl.h: fix it for for !SMP && !DEBUG_SPINLOCK Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 06/16] timers: prepare for full preemption improve Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 07/16] kernel/cpu: fix cpu down problem if kthreads cpu is going down Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 08/16] kernel/hotplug: restore original cpu mask oncpu/down Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 09/16] drm/i915: drop trace_i915_gem_ring_dispatch on rt Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 10/16] rt,ntp: Move call to schedule_delayed_work() to helper thread Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 11/16] hwlat-detector: Update hwlat_detector to add outer loop detection Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 12/16] hwlat-detect/trace: Export trace_clock_local for hwlat-detector Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 13/16] hwlat-detector: Use trace_clock_local if available Steven Rostedt
2013-09-09 12:47 ` [PATCH RT 14/16] hwlat-detector: Use thread instead of stop machine Steven Rostedt
2013-09-09 12:48 ` Steven Rostedt [this message]
2013-09-09 12:48 ` [PATCH RT 16/16] Linux 3.2.50-rt71-rc1 Steven Rostedt
  -- strict thread matches above, loose matches on Subject: below --
2013-09-09 14:35 [PATCH RT 00/16] 3.0.89-rt118-rc1 stable review Steven Rostedt
2013-09-09 14:35 ` [PATCH RT 15/16] genirq: do not invoke the affinity callback via a workqueue Steven Rostedt
2013-09-09 12:45 [PATCH RT 00/16] 3.4.57-rt73-rc1 stable review Steven Rostedt
2013-09-09 12:45 ` [PATCH RT 15/16] genirq: do not invoke the affinity callback via a workqueue Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130909124801.672854008@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=C.Emde@osadl.org \
    --cc=bigeasy@linutronix.de \
    --cc=jkacur@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=stable-rt@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).