From patchwork Fri Aug 25 16:43:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Yu X-Patchwork-Id: 9922475 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 21530602BD for ; Fri, 25 Aug 2017 16:42:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 112B3280CF for ; Fri, 25 Aug 2017 16:42:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 05F2E283CF; Fri, 25 Aug 2017 16:42:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9DF7B280CF for ; Fri, 25 Aug 2017 16:42:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934524AbdHYQmM (ORCPT ); Fri, 25 Aug 2017 12:42:12 -0400 Received: from mga01.intel.com ([192.55.52.88]:34667 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934474AbdHYQmK (ORCPT ); Fri, 25 Aug 2017 12:42:10 -0400 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Aug 2017 09:42:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,426,1498546800"; d="scan'208";a="894092623" Received: from yu-desktop-1.sh.intel.com ([10.239.160.151]) by FMSMGA003.fm.intel.com with ESMTP; 25 Aug 2017 09:42:09 -0700 From: Chen Yu To: linux-acpi@vger.kernel.org Cc: linux-pm@vger.kernel.org, "Rafael J. Wysocki" , Len Brown , Chen Yu , linux-kernel@vger.kernel.org Subject: [PATCH 2/2][RFC] ACPI / PM: Disable the MSR T-state during CPU online Date: Sat, 26 Aug 2017 00:43:45 +0800 Message-Id: <169b775a81dcd3b8297b48f992ac7668257aca66.1503678995.git.yu.c.chen@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In 2015 a bug was once reported that on a Broadwell platform, after resumed from S3, the CPU was running at an anomalously low speed, due to the BIOS has enabled the MSR throttling across S3. This was a BIOS issue and the solution to that was to introduce a quirk to save/restore T-state MSR register around suspend/resume, in Commit 7a9c2dd08ead ("x86/pm: Introduce quirk framework to save/restore extra MSR registers around suspend/resume"). However there are still three problems left: 1. More and more reports show that other platforms also encountered the same issue, so the quirk list might be endless. 2. Each CPUs should take the save/restore operation into consideration, rather than the boot CPU alone. 3. Normally ACPI T-state re-evaluation should be taken care of during resume in the ACPI throttling driver, however there is no _TSS on that bogus platform, thus the re-evaluation code does not run on that machine. Solution: This patch is based on the fact that, we generally should not expect the system to come back from resume(or event CPU been brought online) with throttling enabled, but leverage the OS components to deal with it, so we simply clear the MSR T-state after that CPU has been brought online. In addition to that, print the warning if the T-state is found to be enabled. The side effect of this patch is that, we might lose the T-state evaluation value in the ACPI throttling driver during CPU online stage, because we can not guarantee that the clear action we introduced is invoked strictly before the T-state evaluation in the ACPI throttling driver. But anyway it is expected that there should be an event later to adjust the T-state for us. Besides, we can remove the quirk later. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=90041 Reported-by: Kadir Reported-by: Victor Trac Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: linux-pm@vger.kernel.org Cc: linux-acpi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Chen Yu --- drivers/acpi/sleep.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index cad1a0f..8802ffd 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -870,8 +870,51 @@ static int acpi_syscore_suspend(void) return acpi_save_bm_rld(); } +#ifdef CONFIG_X86 +static long msr_fix_fn(void *data) +{ + u64 msr; + + if (this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) + return 0; + + /* + * It was found after resumed from suspend to ram, some BIOSes would + * adjust the MSR tstate, however on these platforms no _PSS is provided + * thus we never have a chance to adjust the MSR T-state anymore. + * Thus force clearing it if MSR T-state is enabled, because generally + * we never expect to come back from resume(or CPU online) with + * throttling enabled. Later let other components to adjust the + * T-state if necessary. + */ + if (!rdmsrl_safe(MSR_IA32_THERM_CONTROL, &msr) && msr) { + pr_err("PM: The MSR T-state is enabled after CPU%d online, clear it.\n", + smp_processor_id()); + wrmsrl_safe(MSR_IA32_THERM_CONTROL, 0); + } + return 0; +} + +static int msr_fix_cpu_online(unsigned int cpu) +{ + work_on_cpu(cpu, msr_fix_fn, NULL); + return 0; +} +#else +static long msr_fix_fn(void *data) +{ + return 0; +} +static int msr_fix_cpu_online(unsigned int cpu) +{ + return 0; +} +#endif + static void acpi_syscore_restore(void) { + /* Fix the boot CPU. */ + msr_fix_fn(NULL); acpi_restore_bm_rld(); } @@ -883,6 +926,9 @@ static struct syscore_ops acpi_sleep_syscore_ops = { void acpi_sleep_syscore_init(void) { register_syscore_ops(&acpi_sleep_syscore_ops); + cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "msr_fix:online", + msr_fix_cpu_online, NULL); } #else static inline void acpi_sleep_syscore_init(void) {}