From patchwork Wed Sep 15 03:51:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingfan Liu X-Patchwork-Id: 12495453 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFC25C433EF for ; Wed, 15 Sep 2021 03:54:06 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7E38260F25 for ; Wed, 15 Sep 2021 03:54:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7E38260F25 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=la6sylOflyjz6dHRzMaC8WuBv54qZazUAhLbogAcCDA=; b=btQ7+ep/x8D2AK mDwPZqz8JtjHaHmzirQjfbCNNKamj9uTdK7HKJxh/ktJYy8fRFarIn3snbGHwebypJSOIHIVyz6KP tYaBHjYwRCaVjJ2ABeH5r/ZJptYFgYJuF6AVpP403mK74woU0R/hFLVipqfpcjqQFbWosbuVZaWfl CWy9wcUDyGJHZCwcAVBF5lAirZ+L4eRH4mnz116V3sQp7scLsm3+YQsLFIDLMbomGG1Ct0anzIlS0 sb40cFn3Vq01Fedzeu8J/4Ob8HOkarN00Ah7KKa5QaGp3f8lH1+ygqEdD1CqY6WGSroZhTSOAZOrp Z9zxqOCI2mH8cOzrtn2w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mQLxh-0080FW-9J; Wed, 15 Sep 2021 03:51:53 +0000 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mQLxc-0080DK-5t for linux-arm-kernel@lists.infradead.org; Wed, 15 Sep 2021 03:51:50 +0000 Received: by mail-pf1-x434.google.com with SMTP id q22so1549426pfu.0 for ; Tue, 14 Sep 2021 20:51:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5D7wwV9A8hOS3bHMonP493eHo3ii1Zb9/f1nywqD1lQ=; b=mIGQIFQKgI2AI0owZgvTAW5tYBU+xgbyw8L/jwH0VJPCb7t1BADYZRPI/2+iN082+j lUBOS+5Ib9t37pZ4LbxU76Nvy64CBD/xujxvdnbHO7yxEKMametVrCEqCd/Ov9fx5Ea0 Xnxgx2nzJoqqrfAZaWalWNH/XkE4UPFf/KSJN5x6P/uDpmRvthjBSh8oxe+qYZiCXm+A 9F/MZllk6ZUBrfzTYMbqRtQ1QwdsRUkw4TX2Bmpl0gtXGhuKYDfA+jc42Ezmmt3c333C 09XDyYfj9h+jRWPb46CZEuxvzzpAenH2Nidk8KPi8xDffH9xCGs7E71Nz1Z9nD77+VKT VAhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5D7wwV9A8hOS3bHMonP493eHo3ii1Zb9/f1nywqD1lQ=; b=UOwbbH5YsdlAV079Er9BQL848qcbfN5K9KVGKVSKK4lWvyXanV+Gt6/Ql9cjloTBFX d8QAZ9+5Pja5OLXtd+bBexu8bl9q2knyn6x2GICb+ehepJ6ge996mS/chBj8b2a78cSi gc8GzhRS1N3bTnPNb08zd/2B1MU+8AYaQcV2G/4PNq3aPyktMvHq6Ldf6/vW32K554Eq 7vx/s4tIp4VWdlRK5gtYSnO7UTI136su4yD3nmuwMFCvK2iAoJPK689huBogCX3N3uDI EmKwu8bMIZIHwIBPsIAypyASBqA5X1sqbtX5FQd2eLILuojviRoNanAzOrjSfnDOs1sZ DW2w== X-Gm-Message-State: AOAM531LdGTBAxpgtXNytt3ZIL+rCYzPyN6fAU6tdfPIZb5I3jLaSPKO kL3FlbmPt7ECrqDPh8Q6fPB3j8jj3A== X-Google-Smtp-Source: ABdhPJy6c1uH9pGXaEDPt441Ud4f45h8uX+sf3aDZWFowAIFvH285EtKCCcrMoqBKYE9t15iR2XvEA== X-Received: by 2002:aa7:9596:0:b0:43e:48:dbeb with SMTP id z22-20020aa79596000000b0043e0048dbebmr6617575pfj.77.1631677907032; Tue, 14 Sep 2021 20:51:47 -0700 (PDT) Received: from piliu.users.ipa.redhat.com ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id x13sm8602357pfp.133.2021.09.14.20.51.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Sep 2021 20:51:46 -0700 (PDT) From: Pingfan Liu To: linux-arm-kernel@lists.infradead.org Cc: Pingfan Liu , Catalin Marinas , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Marc Zyngier , Julien Thierry , Kees Cook , Masahiro Yamada , Sami Tolvanen , linux-kernel@vger.kernel.org Subject: [PATCH 5/5] arm64/watchdog_hld: enable hard lockup on arm64 platform Date: Wed, 15 Sep 2021 11:51:03 +0800 Message-Id: <20210915035103.15586-6-kernelfans@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210915035103.15586-1-kernelfans@gmail.com> References: <20210915035103.15586-1-kernelfans@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210914_205148_309503_6FD6020A X-CRM114-Status: GOOD ( 29.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org With watchdog_hld armed with the async model, arm64 can probe and enable perf NMI after smp_init(). At the boot stage, all of cpus arm hard lockup detector in the async model. In this patch, the function hw_nmi_get_sample_period() is borrowed from [1], credit goes to Sumit. [1]: http://lore.kernel.org/linux-arm-kernel/1610712101-14929-1-git-send-email-sumit.garg@linaro.org Signed-off-by: Pingfan Liu Cc: Catalin Marinas Cc: Will Deacon Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Arnaldo Carvalho de Melo Cc: Mark Rutland Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Namhyung Kim Cc: Marc Zyngier Cc: Julien Thierry Cc: Kees Cook Cc: Masahiro Yamada Cc: Sami Tolvanen To: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- arch/arm64/Kconfig | 3 ++ arch/arm64/include/asm/perf_event.h | 5 ++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/perf_event.c | 14 ++++- arch/arm64/kernel/watchdog_hld.c | 83 +++++++++++++++++++++++++++++ drivers/perf/arm_pmu.c | 5 ++ 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/kernel/watchdog_hld.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 62c3c1d2190f..0f49e58a9dd8 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -193,6 +193,9 @@ config ARM64 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PERF_EVENTS_NMI + select HAVE_HARDLOCKUP_DETECTOR_PERF \ + if PERF_EVENTS && HW_PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_FUTEX_CMPXCHG if FUTEX diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h index 4ef6f19331f9..712a75f432f0 100644 --- a/arch/arm64/include/asm/perf_event.h +++ b/arch/arm64/include/asm/perf_event.h @@ -6,6 +6,7 @@ #ifndef __ASM_PERF_EVENT_H #define __ASM_PERF_EVENT_H +#include #include #include @@ -259,4 +260,8 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs); (regs)->pstate = PSR_MODE_EL1h; \ } +extern bool arm_pmu_initialized; +extern wait_queue_head_t arm_pmu_wait; +extern bool check_pmu_nmi_ability(void); + #endif diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 3f1490bfb938..789c2fe5bb90 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o +obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_CPU_PM) += sleep.o suspend.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index d07788dad388..c4144cea0d55 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -24,6 +24,9 @@ #include #include +bool arm_pmu_initialized; +DECLARE_WAIT_QUEUE_HEAD(arm_pmu_wait); + /* ARMv8 Cortex-A53 specific event types. */ #define ARMV8_A53_PERFCTR_PREF_LINEFILL 0xC2 @@ -1284,10 +1287,17 @@ static struct platform_driver armv8_pmu_driver = { static int __init armv8_pmu_driver_init(void) { + int ret; + if (acpi_disabled) - return platform_driver_register(&armv8_pmu_driver); + ret = platform_driver_register(&armv8_pmu_driver); else - return arm_pmu_acpi_probe(armv8_pmuv3_init); + ret = arm_pmu_acpi_probe(armv8_pmuv3_init); + + arm_pmu_initialized = true; + wake_up_all(&arm_pmu_wait); + + return ret; } device_initcall(armv8_pmu_driver_init) diff --git a/arch/arm64/kernel/watchdog_hld.c b/arch/arm64/kernel/watchdog_hld.c new file mode 100644 index 000000000000..18bfa62f1058 --- /dev/null +++ b/arch/arm64/kernel/watchdog_hld.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +/* + * Safe maximum CPU frequency in case a particular platform doesn't implement + * cpufreq driver. Although, architecture doesn't put any restrictions on + * maximum frequency but 5 GHz seems to be safe maximum given the available + * Arm CPUs in the market which are clocked much less than 5 GHz. On the other + * hand, we can't make it much higher as it would lead to a large hard-lockup + * detection timeout on parts which are running slower (eg. 1GHz on + * Developerbox) and doesn't possess a cpufreq driver. + */ +#define SAFE_MAX_CPU_FREQ 5000000000UL // 5 GHz +u64 hw_nmi_get_sample_period(int watchdog_thresh) +{ + unsigned int cpu = smp_processor_id(); + unsigned long max_cpu_freq; + + max_cpu_freq = cpufreq_get_hw_max_freq(cpu) * 1000UL; + if (!max_cpu_freq) + max_cpu_freq = SAFE_MAX_CPU_FREQ; + + return (u64)max_cpu_freq * watchdog_thresh; +} + +static watchdog_nmi_status_reporter status_reporter; + +static int hld_enabled_thread_fun(void *unused) +{ + struct watchdog_nmi_status status; + watchdog_nmi_status_reporter local_reporter; + int ret; + + wait_event(arm_pmu_wait, arm_pmu_initialized); + status.cpu = raw_smp_processor_id(); + + if (!check_pmu_nmi_ability()) { + status.status = -ENODEV; + goto report; + } + + ret = hardlockup_detector_perf_enable(); + status.status = ret; + +report: + local_reporter = (watchdog_nmi_status_reporter)atomic64_fetch_and(0, + (atomic64_t *)&status_reporter); + if (local_reporter) + (*local_reporter)(&status); + + return 0; +} + +/* As for watchdog_nmi_disable(), using the default implement */ +void watchdog_nmi_enable(unsigned int cpu) +{ + struct task_struct *t; + + /* PMU is not ready */ + if (!arm_pmu_initialized) { + t = kthread_create_on_cpu(hld_enabled_thread_fun, NULL, cpu, + "arm64_hld.%u"); + if (IS_ERR(t)) + return; + wake_up_process(t); + return; + } + + /* For hotplug in cpu */ + hardlockup_detector_perf_enable(); +} + +int __init watchdog_nmi_probe(watchdog_nmi_status_reporter notifier) +{ + /* On arm64, arm pmu is not ready at this stage */ + status_reporter = notifier; + return -EBUSY; +} + diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 3cbc3baf087f..e08961b37922 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -105,6 +105,11 @@ static DEFINE_PER_CPU(const struct pmu_irq_ops *, cpu_irq_ops); static bool has_nmi; +bool check_pmu_nmi_ability(void) +{ + return has_nmi; +} + static inline u64 arm_pmu_event_max_period(struct perf_event *event) { if (event->hw.flags & ARMPMU_EVT_64BIT)