From patchwork Wed Feb 5 15:20:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Bityutskiy X-Patchwork-Id: 862339 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97D2D18DF65 for ; Wed, 5 Feb 2025 15:21:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768864; cv=none; b=rK5Q7yKRs1PeksSIXRaoS/iiXgCyCgDWBJ2CUXxsMK0FmsAReD+BAGfTM2zlFOkvzAp4MFP+ptIlEnZc0J7WcZLrI7W4v3z5pskPP6zLiglgsuC7bI8HqJ17dinw/susgYJ7JMaNgMnrJkdcDsQ230pml0S+uDTuKghZnYXoeIc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768864; c=relaxed/simple; bh=P7xvTLkJHVqOInIo6HNxZgRzaoROy2vY83UcOxhlEkA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EM++KLvXJ+MDRu7mCuf0lXp3jaoE9+MCa/fDK3/0tN7IQRPf77pEGeFS8qxflzYLA8R3GVpkx93Z20Ll0CEl0Vq9R7FaV/bU5FtlqHIIDFmqTco3u0DBB+MPPgg/YO/EPUtlytK09TfPqDZTtf1DVaquvuXvA+zW4hDwSZ4srWA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=GF9ry2E+; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="GF9ry2E+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1738768862; x=1770304862; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=P7xvTLkJHVqOInIo6HNxZgRzaoROy2vY83UcOxhlEkA=; b=GF9ry2E+Ddnu0ELbGVaAkBfqI6iFqC/bljPqT5DZlKG2683aJbNk5CmN ScVnM4UNyINL/F0tBBmkhPmareED4nYLhqca0eLnjKPtpdxUcj1oYP8uC O45d5tQZVTG8caggINKAS7w2HeiVp1J4tQXW2YLxqD/BiE9FcIVd6wigz tmfDuk/U961HEhAnUDmQIxhPsG0qhYOiNV+jVN+POKcSynMXYMtr1i3Vb Y4uYZdS0va/2Dlu58NwF7f0VvzkM1SdhdaR/7DtnemnTwJcQRqACZgRVo ZUIAJSJwTvUSHXg56WxcFx+4tqxHvXOBo3SOif8v/WdYkmPJRVQqGSHOj g==; X-CSE-ConnectionGUID: 7rrRs8GVS62PKhHUwYPq9A== X-CSE-MsgGUID: WdQySd3RRIKN73eP7+qPQg== X-IronPort-AV: E=McAfee;i="6700,10204,11336"; a="39498152" X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="39498152" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Feb 2025 07:21:01 -0800 X-CSE-ConnectionGUID: 3OV5PKd0QKqagauGhfGfvA== X-CSE-MsgGUID: 0ox1W5CJSFSSTyEYPkssfA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="111109494" Received: from powerlab.fi.intel.com (HELO powerlab.backendnet) ([10.237.71.25]) by fmviesa008.fm.intel.com with ESMTP; 05 Feb 2025 07:21:00 -0800 From: Artem Bityutskiy To: x86@kernel.org Cc: Linux PM Mailing List , "Rafael J. Wysocki" , Len Brown , Artem Bityutskiy , dave.hansen@linux.intel.com Subject: [PATCH v10 1/4] x86/smp: Allow calling mwait_play_dead with an arbitrary hint Date: Wed, 5 Feb 2025 17:20:53 +0200 Message-ID: <20250205152057.171030-2-artem.bityutskiy@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> References: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce a helper function to allow offlined CPUs to enter idle states with a specific MWAIT hint. The new helper will be used in subsequent patches by the acpi_idle and intel_idle drivers. No functional change intended. Based on patches from Patryk Wlazlyn . Reviewed-by: Gautham R. Shenoy Signed-off-by: Artem Bityutskiy --- arch/x86/include/asm/smp.h | 3 ++ arch/x86/kernel/smpboot.c | 88 ++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index ca073f40698f..80f8bfd83fc7 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -114,6 +114,7 @@ void wbinvd_on_cpu(int cpu); int wbinvd_on_all_cpus(void); void smp_kick_mwait_play_dead(void); +void mwait_play_dead(unsigned int eax_hint); void native_smp_send_reschedule(int cpu); void native_send_call_func_ipi(const struct cpumask *mask); @@ -164,6 +165,8 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu) { return (struct cpumask *)cpumask_of(0); } + +static inline void mwait_play_dead(unsigned int eax_hint) { } #endif /* CONFIG_SMP */ #ifdef CONFIG_DEBUG_NMI_SELFTEST diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c10850ae6f09..8aad14e43f54 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1258,47 +1258,9 @@ void play_dead_common(void) local_irq_disable(); } -/* - * We need to flush the caches before going to sleep, lest we have - * dirty data in our caches when we come back up. - */ -static inline void mwait_play_dead(void) +void __noreturn mwait_play_dead(unsigned int eax_hint) { struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead); - unsigned int eax, ebx, ecx, edx; - unsigned int highest_cstate = 0; - unsigned int highest_subcstate = 0; - int i; - - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || - boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) - return; - if (!this_cpu_has(X86_FEATURE_MWAIT)) - return; - if (!this_cpu_has(X86_FEATURE_CLFLUSH)) - return; - - eax = CPUID_LEAF_MWAIT; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - - /* - * eax will be 0 if EDX enumeration is not valid. - * Initialized below to cstate, sub_cstate value when EDX is valid. - */ - if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) { - eax = 0; - } else { - edx >>= MWAIT_SUBSTATE_SIZE; - for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { - if (edx & MWAIT_SUBSTATE_MASK) { - highest_cstate = i; - highest_subcstate = edx & MWAIT_SUBSTATE_MASK; - } - } - eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | - (highest_subcstate - 1); - } /* Set up state for the kexec() hack below */ md->status = CPUDEAD_MWAIT_WAIT; @@ -1319,7 +1281,7 @@ static inline void mwait_play_dead(void) mb(); __monitor(md, 0, 0); mb(); - __mwait(eax, 0); + __mwait(eax_hint, 0); if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) { /* @@ -1341,6 +1303,50 @@ static inline void mwait_play_dead(void) } } +/* + * We need to flush the caches before going to sleep, lest we have + * dirty data in our caches when we come back up. + */ +static inline void mwait_play_dead_cpuid_hint(void) +{ + unsigned int eax, ebx, ecx, edx; + unsigned int highest_cstate = 0; + unsigned int highest_subcstate = 0; + int i; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) + return; + if (!this_cpu_has(X86_FEATURE_MWAIT)) + return; + if (!this_cpu_has(X86_FEATURE_CLFLUSH)) + return; + + eax = CPUID_LEAF_MWAIT; + ecx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + + /* + * eax will be 0 if EDX enumeration is not valid. + * Initialized below to cstate, sub_cstate value when EDX is valid. + */ + if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) { + eax = 0; + } else { + edx >>= MWAIT_SUBSTATE_SIZE; + for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { + if (edx & MWAIT_SUBSTATE_MASK) { + highest_cstate = i; + highest_subcstate = edx & MWAIT_SUBSTATE_MASK; + } + } + eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | + (highest_subcstate - 1); + } + + mwait_play_dead(eax); +} + /* * Kick all "offline" CPUs out of mwait on kexec(). See comment in * mwait_play_dead(). @@ -1391,7 +1397,7 @@ void native_play_dead(void) play_dead_common(); tboot_shutdown(TB_SHUTDOWN_WFS); - mwait_play_dead(); + mwait_play_dead_cpuid_hint(); if (cpuidle_play_dead()) hlt_play_dead(); } From patchwork Wed Feb 5 15:20:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Bityutskiy X-Patchwork-Id: 862883 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00C31CA64 for ; Wed, 5 Feb 2025 15:21:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768865; cv=none; b=O4o2T221igQkGkKvxwA/uJxfc6Pfc2VaTijJauc0VXl6NntOQTwh2qmh/mK5Dznti2EDbDAG1+5bEs7Mvg2PKhlzFjiTU62vJjTOQHC3bR8E5JTwyksRrFw8eXJ+K1RU0irx7/yxEfoX0I6ZPTfnAT/T5TLOPiU+1Jhs30SDv5k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768865; c=relaxed/simple; bh=iVvYWC6cKhlDIg5xivFFUGdfUxQs/GwvlEi8AzEZSx8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t3xcJDJhgYiW8OMUK0zJ3GUsnIcnk+3y0HXAGTUsaT6zqAi1c93NmZ03kVXakXKm1RtERlUQ5n69sI1WmK6ILLRv7Q23MpSlMehYm+VGobljb6uVsjXGc90RlxyAYLBy+WhlUTITt12PjghncdPOkSHlrM0tPitn/AFjUd+UOIo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FtGMLUbo; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FtGMLUbo" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1738768864; x=1770304864; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iVvYWC6cKhlDIg5xivFFUGdfUxQs/GwvlEi8AzEZSx8=; b=FtGMLUbovdqAopK01rI5pCNR4f1VBW7KNUPPcjsIo8us7vJAldtyy9Ib /6M0n89w81LisGV4sX5zrTOV7YdPS1gaH36LYBbOZvMGD1PnYj60QiwHM kXy81z8+iXMCa+7DosoO0xOip4qVi1yxXpOSw72nayBEVsHcMqMbr3NKG XBm2jEaA10zqTDdFddr1iXoCJ+m7Dby3aydVYhQl/YSZkgizdwPwj//dG uTfMu7yt0b2QuYaLHNIoHA2EmwsRvb5i1X36rBZM00N4nzIP2oPHOP+1K CNowzThxf6s+f3GlCVd/VKsQJv277iqruEOTThJ6tF2/PVePO5h+z+kQ5 A==; X-CSE-ConnectionGUID: i0lLO+bXTfOmEePa8iTF/A== X-CSE-MsgGUID: 4ppILSJ5SA+gwFHPNY8eYw== X-IronPort-AV: E=McAfee;i="6700,10204,11336"; a="39498159" X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="39498159" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Feb 2025 07:21:03 -0800 X-CSE-ConnectionGUID: 7SV2DHhLTNG8RpEmR4qNvw== X-CSE-MsgGUID: SF/q9kqWQSuJ6omEzJZX1w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="111109533" Received: from powerlab.fi.intel.com (HELO powerlab.backendnet) ([10.237.71.25]) by fmviesa008.fm.intel.com with ESMTP; 05 Feb 2025 07:21:02 -0800 From: Artem Bityutskiy To: x86@kernel.org Cc: Linux PM Mailing List , "Rafael J. Wysocki" , Len Brown , Artem Bityutskiy , dave.hansen@linux.intel.com Subject: [PATCH v10 2/4] ACPI: processor_idle: Add FFH state handling Date: Wed, 5 Feb 2025 17:20:54 +0200 Message-ID: <20250205152057.171030-3-artem.bityutskiy@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> References: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Recent Intel platforms will depend on the idle driver to pass the correct hint for playing dead via mwait_play_dead_with_hint(). Expand the existing enter_dead interface with handling for FFH states and pass the MWAIT hint to the mwait_play_dead code. Based on patches from Patryk Wlazlyn . Suggested-by: Gautham R. Shenoy Signed-off-by: Artem Bityutskiy --- arch/x86/kernel/acpi/cstate.c | 10 ++++++++++ drivers/acpi/processor_idle.c | 2 ++ include/acpi/processor.h | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 5854f0b8f0f1..5bdb65516969 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * Initialize bm_flags based on the CPU cache properties @@ -205,6 +206,15 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, } EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); +void acpi_processor_ffh_play_dead(struct acpi_processor_cx *cx) +{ + unsigned int cpu = smp_processor_id(); + struct cstate_entry *percpu_entry; + + percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); + mwait_play_dead(percpu_entry->states[cx->index].eax); +} + void __cpuidle acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) { unsigned int cpu = smp_processor_id(); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 698897b29de2..586cc7d1d8aa 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -590,6 +590,8 @@ static void acpi_idle_play_dead(struct cpuidle_device *dev, int index) raw_safe_halt(); else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { io_idle(cx->address); + } else if (cx->entry_method == ACPI_CSTATE_FFH) { + acpi_processor_ffh_play_dead(cx); } else return; } diff --git a/include/acpi/processor.h b/include/acpi/processor.h index a17e97e634a6..63a37e72b721 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -280,6 +280,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, struct acpi_processor_cx *cx, struct acpi_power_register *reg); void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cstate); +void acpi_processor_ffh_play_dead(struct acpi_processor_cx *cx); #else static inline void acpi_processor_power_init_bm_check(struct acpi_processor_flags @@ -300,6 +301,10 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx { return; } +static inline void acpi_processor_ffh_play_dead(struct acpi_processor_cx *cx) +{ + return; +} #endif static inline int call_on_cpu(int cpu, long (*fn)(void *), void *arg, From patchwork Wed Feb 5 15:20:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Bityutskiy X-Patchwork-Id: 862338 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81055CA64 for ; Wed, 5 Feb 2025 15:21:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768868; cv=none; b=tfhrN8plOHxkQT/tgbSrxAq8n4PAHDePzwsG0/JKZGmEi009kfy2ZLlk8975xLsl08YgpIRzi0ct1oiF9LTFAIE4ybVI92Piqv2Y3N+51awR2KE7RJo7rmFqgFzgJOrgnqfvm1nkfZMvtY+m3+GRkEST5xwGJOdYTiDp8SyC9+A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768868; c=relaxed/simple; bh=TWm3TIWnOhFXJN/WTqyntRa56wJddFgOeIx/dPRUwHQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T1rlr/iTV/4nTsI1XcDIZgiKQHnw+/6Xx2J0RpQzNIXw0C8dbxid13SP0Q/jEN1+dG7RF8qU9hzfZKefSq+6dX/SNBd60oXMRruJ66yg8rJbzy9e2Eo9aH0sea/iCUIRVgIDOn1R/B1ojQks5kHHYTujDwKsiE4y3M2sF60gxOA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=H3nIo/Gb; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="H3nIo/Gb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1738768866; x=1770304866; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TWm3TIWnOhFXJN/WTqyntRa56wJddFgOeIx/dPRUwHQ=; b=H3nIo/GbsT2Avyzs0ocnwE6tTS7z1NCR/2dPLFkmV4D/T84cMjFvGpQI NlKBh0otrOhPdSkFGksEiP1ndMxT0CokVo64G0M9zZssaJPKnLQAFKe69 Dvei9aKZNCtPCq6skTdxyVocqXJ558VGk8Foc/ZhWZ/JJRugNTRIMdWyY MP+m56xDB7qMQRpw4uy7CwBfjH78byKCoFkFiN2SjcOSlAWBmdAO7OETm HAG/2jUqQOh2/1FM7K5JoL4epY4XyGKYLIpGkLk9cXUOVTqJf7vbsbzWE 1OYqQeRQphGqBeD2E6JpRIpYJDY0cFf40u3h1rYwd4+x3mkRbBVedi36Y w==; X-CSE-ConnectionGUID: GkAY6qMFSQKiR20DI3HFtQ== X-CSE-MsgGUID: SbCTvzx1Ro621FOt6BtUdw== X-IronPort-AV: E=McAfee;i="6700,10204,11336"; a="39498162" X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="39498162" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Feb 2025 07:21:05 -0800 X-CSE-ConnectionGUID: ymXg2qESTu+4tgM/kbBNhA== X-CSE-MsgGUID: 82GsB5IiSLGhT8ktgUL+PQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="111109565" Received: from powerlab.fi.intel.com (HELO powerlab.backendnet) ([10.237.71.25]) by fmviesa008.fm.intel.com with ESMTP; 05 Feb 2025 07:21:04 -0800 From: Artem Bityutskiy To: x86@kernel.org Cc: Linux PM Mailing List , "Rafael J. Wysocki" , Len Brown , Artem Bityutskiy , dave.hansen@linux.intel.com Subject: [PATCH v10 3/4] intel_idle: Provide the default enter_dead() handler Date: Wed, 5 Feb 2025 17:20:55 +0200 Message-ID: <20250205152057.171030-4-artem.bityutskiy@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> References: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Recent Intel platforms require idle driver to provide information about the MWAIT hint used to enter the deepest idle state in the play_dead code. Provide the default enter_dead() handler for all of the platforms and allow overwriting with a custom handler for each platform if needed. Based on patches from Patryk Wlazlyn . Signed-off-by: Artem Bityutskiy --- drivers/idle/intel_idle.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 118fe1d37c22..e59073efb6fa 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -57,6 +57,7 @@ #include #include #include +#include #define INTEL_IDLE_VERSION "0.5.1" @@ -228,6 +229,15 @@ static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev, return 0; } +static void intel_idle_enter_dead(struct cpuidle_device *dev, int index) +{ + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); + struct cpuidle_state *state = &drv->states[index]; + unsigned long eax = flg2MWAIT(state->flags); + + mwait_play_dead(eax); +} + /* * States are indexed by the cstate number, * which is also the index into the MWAIT hint array. @@ -1800,6 +1810,7 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) state->flags |= CPUIDLE_FLAG_TIMER_STOP; state->enter = intel_idle; + state->enter_dead = intel_idle_enter_dead; state->enter_s2idle = intel_idle_s2idle; } } @@ -2149,6 +2160,9 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) !cpuidle_state_table[cstate].enter_s2idle) break; + if (!cpuidle_state_table[cstate].enter_dead) + cpuidle_state_table[cstate].enter_dead = intel_idle_enter_dead; + /* If marked as unusable, skip this state. */ if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) { pr_debug("state %s is disabled\n", From patchwork Wed Feb 5 15:20:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Bityutskiy X-Patchwork-Id: 862882 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E55018FDBD for ; Wed, 5 Feb 2025 15:21:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768869; cv=none; b=aJk4z5bQsjhHX2v2WS9At7y5Pji9A4qrvhK3hAz9Zg+s6M/aDMyy0oa7xkKpDZYtuIB833hjKJ4xSPqjfPHSjbh3YqH1lyUWNmptGV2uSQW0Dykec71w2iJKBjUK3H//WNaZ7zY6xatKAdj29wtHEg2UWiBqQwNpppgz4xuWqms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738768869; c=relaxed/simple; bh=lPtztsIzhTbtdknG3YE1TiZH4LIuiXEmHZsR47i++LM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mpaGfIqCxLl4uYaZiOg+j2ZOpMZlgx8b/xE2RqNXADg/HXlMvFC0EdlmDB9aWtWHs5L2kouAsgsxrO/vaEg8dLR5rwL/MYeqwDC32Y/hIBHJbtPKOmaYbzUKKJ5sien/VejOPRp7BK9x4b+BqPjW809bjRfJI7yD2iWTW0pEfKg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=b+tuCT/q; arc=none smtp.client-ip=192.198.163.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="b+tuCT/q" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1738768868; x=1770304868; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lPtztsIzhTbtdknG3YE1TiZH4LIuiXEmHZsR47i++LM=; b=b+tuCT/qJQXspHcBPvFKRed8P9v+rJRoJheiYnYbTSc/Ra4BzbhNukVr /GU6+eck4uS2Id84PBgN/1oqT2vQ/2k1z6UhgvYDcpc7tZfRpY+nxd7Ac tLvGEyMks5UK3TygzHM209rgCV6sgpA5fi7mjGWrUavAKyXGbNXHr4eH2 scQlyPMSzb4ttgfahCGXbN7XTwzFo+jG724dgPmdRey4IlveafiTSz7fE jG5Daj2Bjawn68fM0DAyCzBv5Ki1Fiz8TVEsAmkxLdbPhSXSLlzU456Ea GIN9VHx4glCy/KQKyrnp/DWdaM29BK5U7Ao27RAEJh/Hv0cV/NrwUMM4W w==; X-CSE-ConnectionGUID: BUAUqT5FRwOiolQE7ZIhaw== X-CSE-MsgGUID: JIqO2fUWTGu5EuymH2rQbg== X-IronPort-AV: E=McAfee;i="6700,10204,11336"; a="39498173" X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="39498173" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Feb 2025 07:21:07 -0800 X-CSE-ConnectionGUID: MuJmap+kRF+b3MWxHpOMkQ== X-CSE-MsgGUID: GIP8jcnMQfiBgIJkfVU7qA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,261,1732608000"; d="scan'208";a="111109605" Received: from powerlab.fi.intel.com (HELO powerlab.backendnet) ([10.237.71.25]) by fmviesa008.fm.intel.com with ESMTP; 05 Feb 2025 07:21:06 -0800 From: Artem Bityutskiy To: x86@kernel.org Cc: Linux PM Mailing List , "Rafael J. Wysocki" , Len Brown , Artem Bityutskiy , dave.hansen@linux.intel.com Subject: [PATCH v10 4/4] x86/smp: Eliminate mwait_play_dead_cpuid_hint() Date: Wed, 5 Feb 2025 17:20:56 +0200 Message-ID: <20250205152057.171030-5-artem.bityutskiy@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> References: <20250205152057.171030-1-artem.bityutskiy@linux.intel.com> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently, mwait_play_dead_cpuid_hint() looks up the MWAIT hint of the deepest idle state by inspecting CPUID leaf 0x5 with the assumption that, if the number of sub-states for a given major C-state is nonzero, those sub-states are always represented by consecutive numbers starting from 0. This assumption is not based on the documented platform behavior and in fact it is not met on recent Intel platforms. For example, Intel's Sierra Forest report two C-states with two substates each in cpuid leaf 0x5: Name* target cstate target subcstate (mwait hint) =========================================================== C1 0x00 0x00 C1E 0x00 0x01 -- 0x10 ---- C6S 0x20 0x22 C6P 0x20 0x23 -- 0x30 ---- /* No more (sub)states all the way down to the end. */ =========================================================== * Names of the cstates are not included in the CPUID leaf 0x5, they are taken from the product specific documentation. Notice that hints 0x20 and 0x21 are not defined for C-state 0x20 (C6), so the existing MWAIT hint lookup in mwait_play_dead_cpuid_hint() based on the CPUID leaf 0x5 contents does not work in this case. Instead of using MWAIT hint lookup that is not guaranteed to work, make native_play_dead() rely on the idle driver for the given platform to put CPUs going offline into appropriate idle state and, if that fails, fall back to hlt_play_dead(). Accordingly, drop mwait_play_dead_cpuid_hint() altogether and make native_play_dead() call cpuidle_play_dead() instead of it unconditionally with the assumption that it will not return if it is successful. Still, in case cpuidle_play_dead() fails, call hlt_play_dead() at the end. Based on patches from Patryk Wlazlyn . Reviewed-by: Gautham R. Shenoy Signed-off-by: Artem Bityutskiy --- arch/x86/kernel/smpboot.c | 54 +++++---------------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 8aad14e43f54..5746084bafe4 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1258,6 +1258,10 @@ void play_dead_common(void) local_irq_disable(); } +/* + * We need to flush the caches before going to sleep, lest we have + * dirty data in our caches when we come back up. + */ void __noreturn mwait_play_dead(unsigned int eax_hint) { struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead); @@ -1303,50 +1307,6 @@ void __noreturn mwait_play_dead(unsigned int eax_hint) } } -/* - * We need to flush the caches before going to sleep, lest we have - * dirty data in our caches when we come back up. - */ -static inline void mwait_play_dead_cpuid_hint(void) -{ - unsigned int eax, ebx, ecx, edx; - unsigned int highest_cstate = 0; - unsigned int highest_subcstate = 0; - int i; - - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || - boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) - return; - if (!this_cpu_has(X86_FEATURE_MWAIT)) - return; - if (!this_cpu_has(X86_FEATURE_CLFLUSH)) - return; - - eax = CPUID_LEAF_MWAIT; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - - /* - * eax will be 0 if EDX enumeration is not valid. - * Initialized below to cstate, sub_cstate value when EDX is valid. - */ - if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) { - eax = 0; - } else { - edx >>= MWAIT_SUBSTATE_SIZE; - for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { - if (edx & MWAIT_SUBSTATE_MASK) { - highest_cstate = i; - highest_subcstate = edx & MWAIT_SUBSTATE_MASK; - } - } - eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | - (highest_subcstate - 1); - } - - mwait_play_dead(eax); -} - /* * Kick all "offline" CPUs out of mwait on kexec(). See comment in * mwait_play_dead(). @@ -1397,9 +1357,9 @@ void native_play_dead(void) play_dead_common(); tboot_shutdown(TB_SHUTDOWN_WFS); - mwait_play_dead_cpuid_hint(); - if (cpuidle_play_dead()) - hlt_play_dead(); + /* Below returns only on error. */ + cpuidle_play_dead(); + hlt_play_dead(); } #else /* ... !CONFIG_HOTPLUG_CPU */