Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752639AbbKOLGu (ORCPT ); Sun, 15 Nov 2015 06:06:50 -0500 Received: from www.linutronix.de ([62.245.132.108]:36106 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752514AbbKOLGl (ORCPT ); Sun, 15 Nov 2015 06:06:41 -0500 Date: Sun, 15 Nov 2015 12:05:51 +0100 (CET) From: Thomas Gleixner To: yjin cc: Steven Rostedt , mingo@redhat.com, bigeasy@linutronix.de, peterz@infradead.org, linux-kernel@vger.kernel.org, jinyanjiang@gmail.com, stable-rt@vger.kernel.org, linux-rt-users@vger.kernel.org Subject: Re: [RT PATCH] sched: rt: fix two possible deadlocks in push_irq_work_func In-Reply-To: Message-ID: References: <1447469598-31876-1-git-send-email-yanjiang.jin@windriver.com> <20151113232512.53df431f@gandalf.local.home> <5646BB4A.50307@windriver.com> User-Agent: Alpine 2.11 (DEB 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2390 Lines: 79 On Sun, 15 Nov 2015, Thomas Gleixner wrote: > Which does not happen on MIPS as it uses the generic > arch_irq_work_has_interrupt() implementation which returns 'false'. So the proper fix is to ensure that the irq safe irq work actually happens in interrupt context. Patch below. Thanks, tglx 8<------------- diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h index 0e427a9997f3..2543aab05daa 100644 --- a/include/linux/irq_work.h +++ b/include/linux/irq_work.h @@ -52,4 +52,10 @@ static inline bool irq_work_needs_cpu(void) { return false; } static inline void irq_work_run(void) { } #endif +#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) +void irq_work_tick_soft(void); +#else +static inline void irq_work_tick_soft(void) { } +#endif + #endif /* _LINUX_IRQ_WORK_H */ diff --git a/kernel/irq_work.c b/kernel/irq_work.c index 5a0f4525139c..58cf46638ca0 100644 --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -200,8 +200,17 @@ void irq_work_tick(void) if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) irq_work_run_list(raised); + + if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) + irq_work_run_list(this_cpu_ptr(&lazy_list)); +} + +#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) +void irq_work_tick_soft(void) +{ irq_work_run_list(this_cpu_ptr(&lazy_list)); } +#endif /* * Synchronize against the irq_work @entry, ensures the entry is not diff --git a/kernel/time/timer.c b/kernel/time/timer.c index adb1d82d6631..c68ba873da3c 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1455,7 +1455,7 @@ void update_process_times(int user_tick) scheduler_tick(); run_local_timers(); rcu_check_callbacks(user_tick); -#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL) +#if defined(CONFIG_IRQ_WORK) if (in_irq()) irq_work_tick(); #endif @@ -1471,9 +1471,7 @@ static void run_timer_softirq(struct softirq_action *h) hrtimer_run_pending(); -#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) - irq_work_tick(); -#endif + irq_work_tick_soft(); if (time_after_eq(jiffies, base->timer_jiffies)) __run_timers(base); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/