Messages in this thread | | | Date | Wed, 1 Jul 2015 15:16:06 +0800 (CST) | From | cfme_admin <> | Subject | Re:[PATCH] sched: fix BUG in preempt_notifier |
| |
more information about the bug is below: https://bugzilla.kernel.org/show_bug.cgi?id=100701
the preempt_notifier_unregister function is run in_atomic context, but static_key_slow_dec function may cause sleep.
At 2015-07-01 14:33:30, "Lidong Chen" <cfme_admin@163.com> wrote: >Signed-off-by: Lidong Chen <cfme_admin@163.com> >--- > kernel/sched/core.c | 25 ++++--------------------- > 1 file changed, 4 insertions(+), 21 deletions(-) > >diff --git a/kernel/sched/core.c b/kernel/sched/core.c >index b803e1b..4a5a964 100644 >--- a/kernel/sched/core.c >+++ b/kernel/sched/core.c >@@ -2318,15 +2318,12 @@ void wake_up_new_task(struct task_struct *p) > > #ifdef CONFIG_PREEMPT_NOTIFIERS > >-static struct static_key preempt_notifier_key = STATIC_KEY_INIT_FALSE; >- > /** > * preempt_notifier_register - tell me when current is being preempted & rescheduled > * @notifier: notifier struct to register > */ > void preempt_notifier_register(struct preempt_notifier *notifier) > { >- static_key_slow_inc(&preempt_notifier_key); > hlist_add_head(¬ifier->link, ¤t->preempt_notifiers); > } > EXPORT_SYMBOL_GPL(preempt_notifier_register); >@@ -2340,11 +2337,10 @@ EXPORT_SYMBOL_GPL(preempt_notifier_register); > void preempt_notifier_unregister(struct preempt_notifier *notifier) > { > hlist_del(¬ifier->link); >- static_key_slow_dec(&preempt_notifier_key); > } > EXPORT_SYMBOL_GPL(preempt_notifier_unregister); > >-static void __fire_sched_in_preempt_notifiers(struct task_struct *curr) >+static void fire_sched_in_preempt_notifiers(struct task_struct *curr) > { > struct preempt_notifier *notifier; > >@@ -2352,14 +2348,9 @@ static void __fire_sched_in_preempt_notifiers(struct task_struct *curr) > notifier->ops->sched_in(notifier, raw_smp_processor_id()); > } > >-static __always_inline void fire_sched_in_preempt_notifiers(struct task_struct *curr) >-{ >- if (static_key_false(&preempt_notifier_key)) >- __fire_sched_in_preempt_notifiers(curr); >-} > > static void >-__fire_sched_out_preempt_notifiers(struct task_struct *curr, >+fire_sched_out_preempt_notifiers(struct task_struct *curr, > struct task_struct *next) > { > struct preempt_notifier *notifier; >@@ -2368,21 +2359,13 @@ __fire_sched_out_preempt_notifiers(struct task_struct *curr, > notifier->ops->sched_out(notifier, next); > } > >-static __always_inline void >-fire_sched_out_preempt_notifiers(struct task_struct *curr, >- struct task_struct *next) >-{ >- if (static_key_false(&preempt_notifier_key)) >- __fire_sched_out_preempt_notifiers(curr, next); >-} >- > #else /* !CONFIG_PREEMPT_NOTIFIERS */ > >-static inline void fire_sched_in_preempt_notifiers(struct task_struct *curr) >+static void fire_sched_in_preempt_notifiers(struct task_struct *curr) > { > } > >-static inline void >+static void > fire_sched_out_preempt_notifiers(struct task_struct *curr, > struct task_struct *next) > { >-- >2.1.0 >
| |