From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Vrabel Subject: [PATCHv1] x86: only check for one watchdog NMI Date: Mon, 22 Jun 2015 17:21:51 +0100 Message-ID: <1434990111-14360-1-git-send-email-david.vrabel@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Z74U5-0001zS-LW for xen-devel@lists.xenproject.org; Mon, 22 Jun 2015 16:22:09 +0000 List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xenproject.org Cc: Andrew Cooper , Keir Fraser , David Vrabel , Jan Beulich List-Id: xen-devel@lists.xenproject.org Since the NMI handler can now recognize watchdog NMIs, make check_nmi_watchdog() only check for at least one watchdog NMI. This prevents false negatives caused by other processors (which may be being power managed by the BIOS) running at reduced clock frequencies. This will also slightly speed up boot times since we only wait the full 10 ticks if the NMI watchdog on one or more CPUs is not working. Signed-off-by: David Vrabel --- xen/arch/x86/nmi.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c index 2ab97a0..725ea04 100644 --- a/xen/arch/x86/nmi.c +++ b/xen/arch/x86/nmi.c @@ -139,7 +139,18 @@ int nmi_active; static void __init wait_for_nmis(void *p) { - mdelay((10*1000)/nmi_hz); /* wait 10 ticks */ + unsigned int cpu = smp_processor_id(); + unsigned int start_count = nmi_count(cpu); + unsigned long ticks = 10 * 1000 * cpu_khz / nmi_hz; + unsigned long s, e; + + s = rdtsc(); + do { + cpu_relax(); + if ( nmi_count(cpu) > start_count ) + break; + e = rdtsc(); + } while( e - s < ticks ); } int __init check_nmi_watchdog (void) @@ -156,15 +167,16 @@ int __init check_nmi_watchdog (void) for_each_online_cpu ( cpu ) prev_nmi_count[cpu] = nmi_count(cpu); - /* Wait for 10 ticks. Busy-wait on all CPUs: the LAPIC counter that - * the NMI watchdog uses only runs while the core's not halted */ - if ( nmi_watchdog == NMI_LOCAL_APIC ) - smp_call_function(wait_for_nmis, NULL, 0); - wait_for_nmis(NULL); + /* + * Wait at most 10 ticks for a watchdog NMI on each CPU. + * Busy-wait on all CPUs: the LAPIC counter that the NMI watchdog + * uses only runs while the core's not halted + */ + on_selected_cpus(&cpu_online_map, wait_for_nmis, NULL, 1); for_each_online_cpu ( cpu ) { - if ( nmi_count(cpu) - prev_nmi_count[cpu] <= 5 ) + if ( nmi_count(cpu) - prev_nmi_count[cpu] < 1 ) { printk(" %d", cpu); ok = 0; -- 1.7.10.4