From da82e59adf9d0fd1e813f220da62c4804c2e1b7b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 3 Jul 2009 08:29:56 -0500 Subject: [PATCH] tasklet: busy loop workaround commit 4bd0125629790076941e1b663234cdbb22524421 in tip. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Signed-off-by: Paul Gortmaker --- include/linux/interrupt.h | 6 ++---- kernel/softirq.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 86cf03e..0fd5b27 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -476,10 +476,8 @@ static inline void tasklet_unlock(struct tasklet_struct *t) clear_bit(TASKLET_STATE_RUN, &(t)->state); } -static inline void tasklet_unlock_wait(struct tasklet_struct *t) -{ - while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); } -} +extern void tasklet_unlock_wait(struct tasklet_struct *t); + #else #define tasklet_trylock(t) 1 #define tasklet_tryunlock(t) 1 diff --git a/kernel/softirq.c b/kernel/softirq.c index 1be5ff4..31db011 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -811,6 +812,23 @@ void __init softirq_init(void) open_softirq(HI_SOFTIRQ, tasklet_hi_action); } +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) +void tasklet_unlock_wait(struct tasklet_struct *t) +{ + while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { + /* + * Hack for now to avoid this busy-loop: + */ +#ifdef CONFIG_PREEMPT_RT + msleep(1); +#else + barrier(); +#endif + } +} +EXPORT_SYMBOL(tasklet_unlock_wait); +#endif + static int run_ksoftirqd(void * __data) { /* Priority needs to be below hardirqs */ -- 1.7.0.4