From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> To: linux-kernel@vger.kernel.org Cc: tglx@linutronix.de, Tony Luck <tony.luck@intel.com>, Borislav Petkov <bp@alien8.de>, Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>, x86@kernel.org, linux-edac@vger.kernel.org, Sebastian Andrzej Siewior <bigeasy@linutronix.de> Subject: [PATCH] x86: Convert mce timer to hrtimer Date: Fri, 4 May 2018 13:14:58 +0200 [thread overview] Message-ID: <20180504111459.24825-1-bigeasy@linutronix.de> (raw) From: Thomas Gleixner <tglx@linutronix.de> mce_timer is started in atomic contexts of cpu bringup. This results in might_sleep() warnings on RT. Convert mce_timer to a hrtimer to avoid this. Cc: Tony Luck <tony.luck@intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: x86@kernel.org Cc: linux-edac@vger.kernel.org (open list:X86 MCE INFRASTRUCTURE) Signed-off-by: Thomas Gleixner <tglx@linutronix.de> fold in: |From: Mike Galbraith <bitbucket@online.de> |Date: Wed, 29 May 2013 13:52:13 +0200 |Subject: [PATCH] x86/mce: fix mce timer interval | |Seems mce timer fire at the wrong frequency in -rt kernels since roughly |forever due to 32 bit overflow. 3.8-rt is also missing a multiplier. | |Add missing us -> ns conversion and 32 bit overflow prevention. | |Signed-off-by: Mike Galbraith <bitbucket@online.de> |[bigeasy: use ULL instead of u64 cast] Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- arch/x86/kernel/cpu/mcheck/mce.c | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -41,6 +41,7 @@ #include <linux/debugfs.h> #include <linux/irq_work.h> #include <linux/export.h> +#include <linux/jiffies.h> #include <linux/jump_label.h> #include <asm/intel-family.h> @@ -1358,7 +1359,7 @@ int memory_failure(unsigned long pfn, in static unsigned long check_interval = INITIAL_CHECK_INTERVAL; static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ -static DEFINE_PER_CPU(struct timer_list, mce_timer); +static DEFINE_PER_CPU(struct hrtimer, mce_timer); static unsigned long mce_adjust_timer_default(unsigned long interval) { @@ -1367,26 +1368,18 @@ static unsigned long mce_adjust_timer_de static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default; -static void __start_timer(struct timer_list *t, unsigned long interval) +static void __start_timer(struct hrtimer *t, unsigned long iv) { - unsigned long when = jiffies + interval; - unsigned long flags; - - local_irq_save(flags); - - if (!timer_pending(t) || time_before(when, t->expires)) - mod_timer(t, round_jiffies(when)); - - local_irq_restore(flags); + if (!iv) + return; + hrtimer_start_range_ns(t, ns_to_ktime(jiffies_to_usecs(iv) * 1000ULL), + 0, HRTIMER_MODE_REL_PINNED); } -static void mce_timer_fn(struct timer_list *t) +static enum hrtimer_restart mce_timer_fn(struct hrtimer *timer) { - struct timer_list *cpu_t = this_cpu_ptr(&mce_timer); unsigned long iv; - WARN_ON(cpu_t != t); - iv = __this_cpu_read(mce_next_interval); if (mce_available(this_cpu_ptr(&cpu_info))) { @@ -1409,7 +1402,11 @@ static void mce_timer_fn(struct timer_li done: __this_cpu_write(mce_next_interval, iv); - __start_timer(t, iv); + if (!iv) + return HRTIMER_NORESTART; + + hrtimer_forward_now(timer, ns_to_ktime(jiffies_to_nsecs(iv))); + return HRTIMER_RESTART; } /* @@ -1417,7 +1414,7 @@ static void mce_timer_fn(struct timer_li */ void mce_timer_kick(unsigned long interval) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); unsigned long iv = __this_cpu_read(mce_next_interval); __start_timer(t, interval); @@ -1432,7 +1429,7 @@ static void mce_timer_delete_all(void) int cpu; for_each_online_cpu(cpu) - del_timer_sync(&per_cpu(mce_timer, cpu)); + hrtimer_cancel(&per_cpu(mce_timer, cpu)); } /* @@ -1761,7 +1758,7 @@ static void __mcheck_cpu_clear_vendor(st } } -static void mce_start_timer(struct timer_list *t) +static void mce_start_timer(struct hrtimer *t) { unsigned long iv = check_interval * HZ; @@ -1774,16 +1771,19 @@ static void mce_start_timer(struct timer static void __mcheck_cpu_setup_timer(void) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); - timer_setup(t, mce_timer_fn, TIMER_PINNED); + hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t->function = mce_timer_fn; } static void __mcheck_cpu_init_timer(void) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); + + hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t->function = mce_timer_fn; - timer_setup(t, mce_timer_fn, TIMER_PINNED); mce_start_timer(t); } @@ -2285,7 +2285,7 @@ static int mce_cpu_dead(unsigned int cpu static int mce_cpu_online(unsigned int cpu) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); int ret; mce_device_create(cpu); @@ -2302,10 +2302,10 @@ static int mce_cpu_online(unsigned int c static int mce_cpu_pre_down(unsigned int cpu) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); mce_disable_cpu(); - del_timer_sync(t); + hrtimer_cancel(t); mce_threshold_remove_device(cpu); mce_device_remove(cpu); return 0;
WARNING: multiple messages have this Message-ID (diff)
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> To: linux-kernel@vger.kernel.org Cc: tglx@linutronix.de, Tony Luck <tony.luck@intel.com>, Borislav Petkov <bp@alien8.de>, Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>, x86@kernel.org, linux-edac@vger.kernel.org, Sebastian Andrzej Siewior <bigeasy@linutronix.de> Subject: x86: Convert mce timer to hrtimer Date: Fri, 4 May 2018 13:14:58 +0200 [thread overview] Message-ID: <20180504111459.24825-1-bigeasy@linutronix.de> (raw) From: Thomas Gleixner <tglx@linutronix.de> mce_timer is started in atomic contexts of cpu bringup. This results in might_sleep() warnings on RT. Convert mce_timer to a hrtimer to avoid this. Cc: Tony Luck <tony.luck@intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: x86@kernel.org Cc: linux-edac@vger.kernel.org (open list:X86 MCE INFRASTRUCTURE) Signed-off-by: Thomas Gleixner <tglx@linutronix.de> fold in: |From: Mike Galbraith <bitbucket@online.de> |Date: Wed, 29 May 2013 13:52:13 +0200 |Subject: [PATCH] x86/mce: fix mce timer interval | |Seems mce timer fire at the wrong frequency in -rt kernels since roughly |forever due to 32 bit overflow. 3.8-rt is also missing a multiplier. | |Add missing us -> ns conversion and 32 bit overflow prevention. | |Signed-off-by: Mike Galbraith <bitbucket@online.de> |[bigeasy: use ULL instead of u64 cast] Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- arch/x86/kernel/cpu/mcheck/mce.c | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-edac" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -41,6 +41,7 @@ #include <linux/debugfs.h> #include <linux/irq_work.h> #include <linux/export.h> +#include <linux/jiffies.h> #include <linux/jump_label.h> #include <asm/intel-family.h> @@ -1358,7 +1359,7 @@ int memory_failure(unsigned long pfn, in static unsigned long check_interval = INITIAL_CHECK_INTERVAL; static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ -static DEFINE_PER_CPU(struct timer_list, mce_timer); +static DEFINE_PER_CPU(struct hrtimer, mce_timer); static unsigned long mce_adjust_timer_default(unsigned long interval) { @@ -1367,26 +1368,18 @@ static unsigned long mce_adjust_timer_de static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default; -static void __start_timer(struct timer_list *t, unsigned long interval) +static void __start_timer(struct hrtimer *t, unsigned long iv) { - unsigned long when = jiffies + interval; - unsigned long flags; - - local_irq_save(flags); - - if (!timer_pending(t) || time_before(when, t->expires)) - mod_timer(t, round_jiffies(when)); - - local_irq_restore(flags); + if (!iv) + return; + hrtimer_start_range_ns(t, ns_to_ktime(jiffies_to_usecs(iv) * 1000ULL), + 0, HRTIMER_MODE_REL_PINNED); } -static void mce_timer_fn(struct timer_list *t) +static enum hrtimer_restart mce_timer_fn(struct hrtimer *timer) { - struct timer_list *cpu_t = this_cpu_ptr(&mce_timer); unsigned long iv; - WARN_ON(cpu_t != t); - iv = __this_cpu_read(mce_next_interval); if (mce_available(this_cpu_ptr(&cpu_info))) { @@ -1409,7 +1402,11 @@ static void mce_timer_fn(struct timer_li done: __this_cpu_write(mce_next_interval, iv); - __start_timer(t, iv); + if (!iv) + return HRTIMER_NORESTART; + + hrtimer_forward_now(timer, ns_to_ktime(jiffies_to_nsecs(iv))); + return HRTIMER_RESTART; } /* @@ -1417,7 +1414,7 @@ static void mce_timer_fn(struct timer_li */ void mce_timer_kick(unsigned long interval) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); unsigned long iv = __this_cpu_read(mce_next_interval); __start_timer(t, interval); @@ -1432,7 +1429,7 @@ static void mce_timer_delete_all(void) int cpu; for_each_online_cpu(cpu) - del_timer_sync(&per_cpu(mce_timer, cpu)); + hrtimer_cancel(&per_cpu(mce_timer, cpu)); } /* @@ -1761,7 +1758,7 @@ static void __mcheck_cpu_clear_vendor(st } } -static void mce_start_timer(struct timer_list *t) +static void mce_start_timer(struct hrtimer *t) { unsigned long iv = check_interval * HZ; @@ -1774,16 +1771,19 @@ static void mce_start_timer(struct timer static void __mcheck_cpu_setup_timer(void) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); - timer_setup(t, mce_timer_fn, TIMER_PINNED); + hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t->function = mce_timer_fn; } static void __mcheck_cpu_init_timer(void) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); + + hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t->function = mce_timer_fn; - timer_setup(t, mce_timer_fn, TIMER_PINNED); mce_start_timer(t); } @@ -2285,7 +2285,7 @@ static int mce_cpu_dead(unsigned int cpu static int mce_cpu_online(unsigned int cpu) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); int ret; mce_device_create(cpu); @@ -2302,10 +2302,10 @@ static int mce_cpu_online(unsigned int c static int mce_cpu_pre_down(unsigned int cpu) { - struct timer_list *t = this_cpu_ptr(&mce_timer); + struct hrtimer *t = this_cpu_ptr(&mce_timer); mce_disable_cpu(); - del_timer_sync(t); + hrtimer_cancel(t); mce_threshold_remove_device(cpu); mce_device_remove(cpu); return 0;
next reply other threads:[~2018-05-04 11:16 UTC|newest] Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-04 11:14 Sebastian Andrzej Siewior [this message] 2018-05-04 11:14 ` x86: Convert mce timer to hrtimer Sebastian Andrzej Siewior 2018-05-04 11:14 ` [PATCH] x86: UV: raw_spinlock conversion Sebastian Andrzej Siewior 2018-05-06 10:26 ` Thomas Gleixner 2018-05-06 10:59 ` Mike Galbraith 2018-05-07 7:39 ` Sebastian Andrzej Siewior 2018-05-07 7:59 ` Mike Galbraith 2018-05-19 14:09 ` Mike Galbraith 2018-05-22 6:50 ` Sebastian Andrzej Siewior 2018-05-22 8:24 ` Mike Galbraith 2018-05-22 9:14 ` Sebastian Andrzej Siewior 2018-05-22 9:46 ` Mike Galbraith 2018-05-22 12:48 ` Mike Galbraith 2018-05-07 9:04 ` [PATCH] x86: Convert mce timer to hrtimer Sebastian Andrzej Siewior 2018-05-07 9:04 ` Sebastian Andrzej Siewior
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=20180504111459.24825-1-bigeasy@linutronix.de \ --to=bigeasy@linutronix.de \ --cc=bp@alien8.de \ --cc=hpa@zytor.com \ --cc=linux-edac@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mingo@redhat.com \ --cc=tglx@linutronix.de \ --cc=tony.luck@intel.com \ --cc=x86@kernel.org \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.