Unverified Commit 61f39efb authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!200 x86: support MWAIT C1 as the default idle state

Merge Pull Request from: @haochengxie 
 
Two patches to support MWAIT C1 as the default idle state. For systems disabled global C-states in BIOS, kernel will use the default function as idle state. Historically, the default idle state uses HLT, but it should be mwait (if it support) to improve the exit latency.
 
 
Link:https://gitee.com/openeuler/kernel/pulls/200

 
Reviewed-by: default avatarHanjun Guo <guohanjun@huawei.com>
Reviewed-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 1789f7b7 3b877202
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -685,8 +685,8 @@ the ``menu`` governor to be used on the systems that use the ``ladder`` governor
by default this way, for example.

The other kernel command line parameters controlling CPU idle time management
described below are only relevant for the *x86* architecture and some of
them affect Intel processors only.
described below are only relevant for the *x86* architecture and references
to ``intel_idle`` affect Intel processors only.

The *x86* architecture support code recognizes three kernel command line
options related to CPU idle time management: ``idle=poll``, ``idle=halt``,
@@ -708,10 +708,13 @@ idle, so it very well may hurt single-thread computations performance as well as
energy-efficiency.  Thus using it for performance reasons may not be a good idea
at all.]

The ``idle=nomwait`` option disables the ``intel_idle`` driver and causes
``acpi_idle`` to be used (as long as all of the information needed by it is
there in the system's ACPI tables), but it is not allowed to use the
``MWAIT`` instruction of the CPUs to ask the hardware to enter idle states.
The ``idle=nomwait`` option prevents the use of ``MWAIT`` instruction of
the CPU to enter idle states. When this option is used, the ``acpi_idle``
driver will use the ``HLT`` instruction instead of ``MWAIT``. On systems
running Intel processors, this option disables the ``intel_idle`` driver
and forces the use of the ``acpi_idle`` driver instead. Note that in either
case, ``acpi_idle`` driver will function only if all the information needed
by it is in the system's ACPI tables.

In addition to the architecture-level kernel command line options affecting CPU
idle time management, there are parameters affecting individual ``CPUIdle``
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#define MWAIT_SUBSTATE_SIZE		4
#define MWAIT_HINT2CSTATE(hint)		(((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK)
#define MWAIT_HINT2SUBSTATE(hint)	((hint) & MWAIT_CSTATE_MASK)
#define MWAIT_C1_SUBSTATE_MASK  0xf0

#define CPUID_MWAIT_LEAF		5
#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
+31 −13
Original line number Diff line number Diff line
@@ -768,24 +768,43 @@ static void amd_e400_idle(void)
}

/*
 * Intel Core2 and older machines prefer MWAIT over HALT for C1.
 * We can't rely on cpuidle installing MWAIT, because it will not load
 * on systems that support only C1 -- so the boot default must be MWAIT.
 * Prefer MWAIT over HALT if MWAIT is supported, MWAIT_CPUID leaf
 * exists and whenever MONITOR/MWAIT extensions are present there is at
 * least one C1 substate.
 *
 * Some AMD machines are the opposite, they depend on using HALT.
 *
 * So for default C1, which is used during boot until cpuidle loads,
 * use MWAIT-C1 on Intel HW that has it, else use HALT.
 * Do not prefer MWAIT if MONITOR instruction has a bug or idle=nomwait
 * is passed to kernel commandline parameter.
 */
static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
{
	if (c->x86_vendor != X86_VENDOR_INTEL)
	u32 eax, ebx, ecx, edx;

	/* User has disallowed the use of MWAIT. Fallback to HALT */
	if (boot_option_idle_override == IDLE_NOMWAIT)
		return 0;

	if (!cpu_has(c, X86_FEATURE_MWAIT) || boot_cpu_has_bug(X86_BUG_MONITOR))
	/* MWAIT is not supported on this platform. Fallback to HALT */
	if (!cpu_has(c, X86_FEATURE_MWAIT))
		return 0;

	/* Monitor has a bug. Fallback to HALT */
	if (boot_cpu_has_bug(X86_BUG_MONITOR))
		return 0;

	cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);

	/*
	 * If MWAIT extensions are not available, it is safe to use MWAIT
	 * with EAX=0, ECX=0.
	 */
	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED))
		return 1;

	/*
	 * If MWAIT extensions are available, there should be at least one
	 * MWAIT C1 substate present.
	 */
	return (edx & MWAIT_C1_SUBSTATE_MASK);
}

/*
@@ -887,9 +906,8 @@ static int __init idle_setup(char *str)
	} else if (!strcmp(str, "nomwait")) {
		/*
		 * If the boot option of "idle=nomwait" is added,
		 * it means that mwait will be disabled for CPU C2/C3
		 * states. In such case it won't touch the variable
		 * of boot_option_idle_override.
		 * it means that mwait will be disabled for CPU C1/C2/C3
		 * states.
		 */
		boot_option_idle_override = IDLE_NOMWAIT;
	} else