From patchwork Wed Jun 13 00:57:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Neri X-Patchwork-Id: 928545 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=sparclinux-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.intel.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4157mS3QH4z9s1R for ; Wed, 13 Jun 2018 11:03:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935075AbeFMBDW (ORCPT ); Tue, 12 Jun 2018 21:03:22 -0400 Received: from mga14.intel.com ([192.55.52.115]:64685 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935068AbeFMBBk (ORCPT ); Tue, 12 Jun 2018 21:01:40 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Jun 2018 18:01:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,216,1526367600"; d="scan'208";a="47283520" Received: from voyager.sc.intel.com ([10.3.52.149]) by fmsmga008.fm.intel.com with ESMTP; 12 Jun 2018 18:01:34 -0700 From: Ricardo Neri To: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" Cc: Andi Kleen , Ashok Raj , Borislav Petkov , Tony Luck , "Ravi V. Shankar" , x86@kernel.org, sparclinux@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Ricardo Neri , Jacob Pan , "Rafael J. Wysocki" , Don Zickus , Nicholas Piggin , Michael Ellerman , Frederic Weisbecker , Alexei Starovoitov , Babu Moger , Mathieu Desnoyers , Masami Hiramatsu , Peter Zijlstra , Andrew Morton , Philippe Ombredanne , Colin Ian King , Byungchul Park , "Paul E. McKenney" , "Luis R. Rodriguez" , Waiman Long , Josh Poimboeuf , Randy Dunlap , Davidlohr Bueso , Christoffer Dall , Marc Zyngier , Kai-Heng Feng , Konrad Rzeszutek Wilk , David Rientjes , iommu@lists.linux-foundation.org Subject: [RFC PATCH 18/23] watchdog/hardlockup/hpet: Add the NMI watchdog operations Date: Tue, 12 Jun 2018 17:57:38 -0700 Message-Id: <1528851463-21140-19-git-send-email-ricardo.neri-calderon@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1528851463-21140-1-git-send-email-ricardo.neri-calderon@linux.intel.com> References: <1528851463-21140-1-git-send-email-ricardo.neri-calderon@linux.intel.com> Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org Implement the start, stop and disable operations of the HPET-based NMI watchdog. Given that a single timer is used to monitor all the CPUs in the system, it is necessary to define a cpumask that keeps track of the CPUs that can be monitored. This cpumask is protected with a spin lock. As individual CPUs are put online and offline, this cpumask is updated. CPUs are unconditionally cleared from the mask when going offline. When going online, the CPU is set in the mask only if is one of the CPUs allowed to be monitored by the watchdog. It is not necessary to implement a start function. The NMI watchdog will be enabled when there is at least one CPU to monitor. The disable function clears the CPU mask and disables the timer. Cc: Ashok Raj Cc: Andi Kleen Cc: Tony Luck Cc: Borislav Petkov Cc: Jacob Pan Cc: "Rafael J. Wysocki" Cc: Don Zickus Cc: Nicholas Piggin Cc: Michael Ellerman Cc: Frederic Weisbecker Cc: Alexei Starovoitov Cc: Babu Moger Cc: Mathieu Desnoyers Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Andrew Morton Cc: Philippe Ombredanne Cc: Colin Ian King Cc: Byungchul Park Cc: "Paul E. McKenney" Cc: "Luis R. Rodriguez" Cc: Waiman Long Cc: Josh Poimboeuf Cc: Randy Dunlap Cc: Davidlohr Bueso Cc: Christoffer Dall Cc: Marc Zyngier Cc: Kai-Heng Feng Cc: Konrad Rzeszutek Wilk Cc: David Rientjes Cc: "Ravi V. Shankar" Cc: x86@kernel.org Cc: iommu@lists.linux-foundation.org Signed-off-by: Ricardo Neri --- arch/x86/include/asm/hpet.h | 2 + include/linux/nmi.h | 1 + kernel/watchdog_hld_hpet.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index 33309b7..6ace2d1 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h @@ -124,6 +124,8 @@ struct hpet_hld_data { u32 irq; u32 flags; u64 ticks_per_second; + struct cpumask monitored_mask; + spinlock_t lock; /* serialized access to monitored_mask */ }; extern struct hpet_hld_data *hpet_hardlockup_detector_assign_timer(void); diff --git a/include/linux/nmi.h b/include/linux/nmi.h index e608762..23e20d2 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -129,6 +129,7 @@ struct nmi_watchdog_ops { }; extern struct nmi_watchdog_ops hardlockup_detector_perf_ops; +extern struct nmi_watchdog_ops hardlockup_detector_hpet_ops; void watchdog_nmi_stop(void); void watchdog_nmi_start(void); diff --git a/kernel/watchdog_hld_hpet.c b/kernel/watchdog_hld_hpet.c index 3bedffa..857e051 100644 --- a/kernel/watchdog_hld_hpet.c +++ b/kernel/watchdog_hld_hpet.c @@ -345,6 +345,91 @@ static int setup_hpet_irq(struct hpet_hld_data *hdata) } /** + * hardlockup_detector_hpet_enable() - Enable the hardlockup detector + * + * The hardlockup detector is enabled for the CPU that executes the + * function. It is only enabled if such CPU is allowed to be monitored + * by the lockup detector. + * + * Returns: + * + * None + * + */ +static void hardlockup_detector_hpet_enable(void) +{ + struct cpumask *allowed = watchdog_get_allowed_cpumask(); + unsigned int cpu = smp_processor_id(); + + if (!hld_data) + return; + + if (!cpumask_test_cpu(cpu, allowed)) + return; + + spin_lock(&hld_data->lock); + + cpumask_set_cpu(cpu, &hld_data->monitored_mask); + + /* + * If this is the first CPU to be monitored, set everything in motion: + * move the interrupt to this CPU, kick and enable the timer. + */ + if (cpumask_weight(&hld_data->monitored_mask) == 1) { + if (irq_set_affinity(hld_data->irq, cpumask_of(cpu))) { + spin_unlock(&hld_data->lock); + pr_err("Unable to enable on CPU %d.!\n", cpu); + return; + } + + kick_timer(hld_data); + enable(hld_data); + } + + spin_unlock(&hld_data->lock); +} + +/** + * hardlockup_detector_hpet_disable() - Disable the hardlockup detector + * + * The hardlockup detector is disabled for the CPU that executes the + * function. + * + * None + */ +static void hardlockup_detector_hpet_disable(void) +{ + if (!hld_data) + return; + + spin_lock(&hld_data->lock); + + cpumask_clear_cpu(smp_processor_id(), &hld_data->monitored_mask); + + /* Only disable the timer if there are no more CPUs to monitor. */ + if (!cpumask_weight(&hld_data->monitored_mask)) + disable(hld_data); + + spin_unlock(&hld_data->lock); +} + +/** + * hardlockup_detector_hpet_stop() - Stop the NMI watchdog on all CPUs + * + * Returns: + * + * None + */ +static void hardlockup_detector_hpet_stop(void) +{ + disable(hld_data); + + spin_lock(&hld_data->lock); + cpumask_clear(&hld_data->monitored_mask); + spin_unlock(&hld_data->lock); +} + +/** * hardlockup_detector_hpet_init() - Initialize the hardlockup detector * * Only initialize and configure the detector if an HPET is available on the @@ -383,5 +468,18 @@ static int __init hardlockup_detector_hpet_init(void) */ disable(hld_data); + spin_lock_init(&hld_data->lock); + + spin_lock(&hld_data->lock); + cpumask_clear(&hld_data->monitored_mask); + spin_unlock(&hld_data->lock); + return 0; } + +struct nmi_watchdog_ops hardlockup_detector_hpet_ops = { + .init = hardlockup_detector_hpet_init, + .enable = hardlockup_detector_hpet_enable, + .disable = hardlockup_detector_hpet_disable, + .stop = hardlockup_detector_hpet_stop +};