On Thu, Jul 18, 2013 at 03:57:26PM +0800, Zhouping Liu wrote: > On 07/18/2013 01:00 PM, gregkh@xxxxxxxxxxxxxxxxxxx wrote: > > The patch below does not apply to the 3.10-stable tree. > > If someone wants it applied there, or to any other stable or longterm > > tree, then please email the backport, including the original git commit > > id to <stable@xxxxxxxxxxxxxxx>. > > Hi Greg, > > Its prerequisite patch is: > 7c4c3a0f18b hrtimers: Support resuming with two or more CPUs online (but > stopped) > how about also back-port this patch? I could do that, but from reading the changelog comments below, is this patch really needed for 3.10-stable? 3.11 seems to make sense, as some other code was using this api and causing problems, but that isn't in 3.10 from what I can tell, right? So, is it really needed for 3.10? thanks, greg k-h > > ------------------ original commit in Linus's tree ------------------ > > > > From 5ec2481b7b47a4005bb446d176e5d0257400c77d Mon Sep 17 00:00:00 2001 > > From: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > > Date: Fri, 5 Jul 2013 12:09:18 +0200 > > Subject: [PATCH] hrtimers: Move SMP function call to thread context > > > > smp_call_function_* must not be called from softirq context. > > > > But clock_was_set() which calls on_each_cpu() is called from softirq > > context to implement a delayed clock_was_set() for the timer interrupt > > handler. Though that almost never gets invoked. A recent change in the > > resume code uses the softirq based delayed clock_was_set to support > > Xens resume mechanism. > > > > linux-next contains a new warning which warns if smp_call_function_* > > is called from softirq context which gets triggered by that Xen > > change. > > > > Fix this by moving the delayed clock_was_set() call to a work context. > > > > Reported-and-tested-by: Artem Savkov <artem.savkov@xxxxxxxxx> > > Reported-by: Sasha Levin <sasha.levin@xxxxxxxxxx> > > Cc: David Vrabel <david.vrabel@xxxxxxxxxx> > > Cc: Ingo Molnar <mingo@xxxxxxxxxx> > > Cc: H. Peter Anvin <hpa@xxxxxxxxx>, > > Cc: Konrad Wilk <konrad.wilk@xxxxxxxxxx> > > Cc: John Stultz <john.stultz@xxxxxxxxxx> > > Cc: xen-devel@xxxxxxxxxxxxx > > Cc: stable@xxxxxxxxxxxxxxx > > Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > > > > diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c > > index e86827e..b9b9420 100644 > > --- a/kernel/hrtimer.c > > +++ b/kernel/hrtimer.c > > @@ -721,17 +721,20 @@ static int hrtimer_switch_to_hres(void) > > return 1; > > } > > > > +static void clock_was_set_work(struct work_struct *work) > > +{ > > + clock_was_set(); > > +} > > + > > +static DECLARE_WORK(hrtimer_work, clock_was_set_work); > > + > > /* > > - * Called from timekeeping code to reprogramm the hrtimer interrupt > > - * device. If called from the timer interrupt context we defer it to > > - * softirq context. > > + * Called from timekeeping and resume code to reprogramm the hrtimer > > + * interrupt device on all cpus. > > */ > > void clock_was_set_delayed(void) > > { > > - struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); > > - > > - cpu_base->clock_was_set = 1; > > - __raise_softirq_irqoff(HRTIMER_SOFTIRQ); > > + schedule_work(&hrtimer_work); > > } > > > > #else > > @@ -775,12 +778,7 @@ void clock_was_set(void) > > * During resume we might have to reprogram the high resolution timer > > * interrupt on all online CPUs. However, all other CPUs will be > > * stopped with IRQs interrupts disabled so the clock_was_set() call > > - * must be deferred to the softirq. > > - * > > - * The one-shot timer has already been programmed to fire immediately > > - * (see tick_resume_oneshot()) and this interrupt will trigger the > > - * softirq to run early enough to correctly reprogram the timers on > > - * all CPUs. > > + * must be deferred. > > */ > > void hrtimers_resume(void) > > { > > @@ -789,8 +787,10 @@ void hrtimers_resume(void) > > WARN_ONCE(!irqs_disabled(), > > KERN_INFO "hrtimers_resume() called with IRQs enabled!"); > > > > - cpu_base->clock_was_set = 1; > > - __raise_softirq_irqoff(HRTIMER_SOFTIRQ); > > + /* Retrigger on the local CPU */ > > + retrigger_next_event(NULL); > > + /* And schedule a retrigger for all others */ > > + clock_was_set_delayed(); > > } > > > > static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) > > @@ -1441,13 +1441,6 @@ void hrtimer_peek_ahead_timers(void) > > > > static void run_hrtimer_softirq(struct softirq_action *h) > > { > > - struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); > > - > > - if (cpu_base->clock_was_set) { > > - cpu_base->clock_was_set = 0; > > - clock_was_set(); > > - } > > - > > hrtimer_peek_ahead_timers(); > > } > > > > > > -- > > To unsubscribe from this list: send the line "unsubscribe stable" in > > the body of a message to majordomo@xxxxxxxxxxxxxxx > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > To unsubscribe from this list: send the line "unsubscribe stable" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html