intel_idle: Introduce 'use_acpi' module parameter

For diagnostics, it is generally useful to be able to make intel_idle
take the system's ACPI tables into consideration even if that is not
required for the processor model in there, so introduce a new module
parameter, 'use_acpi', to make that happen and update the documentation
to cover it.

While at it, fix the 'no_acpi' module parameter name in the
documentation.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Rafael J. Wysocki 2020-02-03 11:57:08 +01:00
parent cf3c8f84d1
commit 3a5be9b8f4
2 changed files with 18 additions and 6 deletions

View File

@ -60,6 +60,9 @@ of the system. The former are always used if the processor model at hand is
recognized by ``intel_idle`` and the latter are used if that is required for recognized by ``intel_idle`` and the latter are used if that is required for
the given processor model (which is the case for all server processor models the given processor model (which is the case for all server processor models
recognized by ``intel_idle``) or if the processor model is not recognized. recognized by ``intel_idle``) or if the processor model is not recognized.
[There is a module parameter that can be used to make the driver use the ACPI
tables with any processor model recognized by it; see
`below <intel-idle-parameters_>`_.]
If the ACPI tables are going to be used for building the list of available idle If the ACPI tables are going to be used for building the list of available idle
states, ``intel_idle`` first looks for a ``_CST`` object under one of the ACPI states, ``intel_idle`` first looks for a ``_CST`` object under one of the ACPI
@ -165,7 +168,7 @@ and ``idle=nomwait``. If any of them is present in the kernel command line, the
``MWAIT`` instruction is not allowed to be used, so the initialization of ``MWAIT`` instruction is not allowed to be used, so the initialization of
``intel_idle`` will fail. ``intel_idle`` will fail.
Apart from that there are two module parameters recognized by ``intel_idle`` Apart from that there are three module parameters recognized by ``intel_idle``
itself that can be set via the kernel command line (they cannot be updated via itself that can be set via the kernel command line (they cannot be updated via
sysfs, so that is the only way to change their values). sysfs, so that is the only way to change their values).
@ -186,9 +189,11 @@ QoS) feature can be used to prevent ``CPUIdle`` from touching those idle states
even if they have been enumerated (see :ref:`cpu-pm-qos` in :doc:`cpuidle`). even if they have been enumerated (see :ref:`cpu-pm-qos` in :doc:`cpuidle`).
Setting ``max_cstate`` to 0 causes the ``intel_idle`` initialization to fail. Setting ``max_cstate`` to 0 causes the ``intel_idle`` initialization to fail.
The ``noacpi`` module parameter (which is recognized by ``intel_idle`` if the The ``no_acpi`` and ``use_acpi`` module parameters (recognized by ``intel_idle``
kernel has been configured with ACPI support), can be set to make the driver if the kernel has been configured with ACPI support) can be set to make the
ignore the system's ACPI tables entirely (it is unset by default). driver ignore the system's ACPI tables entirely or use them for all of the
recognized processor models, respectively (they both are unset by default and
``use_acpi`` has no effect if ``no_acpi`` is set).
.. _intel-idle-core-and-package-idle-states: .. _intel-idle-core-and-package-idle-states:

View File

@ -1131,6 +1131,10 @@ static bool no_acpi __read_mostly;
module_param(no_acpi, bool, 0444); module_param(no_acpi, bool, 0444);
MODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list"); MODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list");
static bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */
module_param_named(use_acpi, force_use_acpi, bool, 0444);
MODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list");
static struct acpi_processor_power acpi_state_table __initdata; static struct acpi_processor_power acpi_state_table __initdata;
/** /**
@ -1258,6 +1262,8 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
return true; return true;
} }
#else /* !CONFIG_ACPI_PROCESSOR_CSTATE */ #else /* !CONFIG_ACPI_PROCESSOR_CSTATE */
#define force_use_acpi (false)
static inline bool intel_idle_acpi_cst_extract(void) { return false; } static inline bool intel_idle_acpi_cst_extract(void) { return false; }
static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { } static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
@ -1460,7 +1466,8 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
/* Structure copy. */ /* Structure copy. */
drv->states[drv->state_count] = cpuidle_state_table[cstate]; drv->states[drv->state_count] = cpuidle_state_table[cstate];
if (icpu->use_acpi && intel_idle_off_by_default(mwait_hint) && if ((icpu->use_acpi || force_use_acpi) &&
intel_idle_off_by_default(mwait_hint) &&
!(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE)) !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE))
drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF; drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF;
@ -1607,7 +1614,7 @@ static int __init intel_idle_init(void)
icpu = (const struct idle_cpu *)id->driver_data; icpu = (const struct idle_cpu *)id->driver_data;
if (icpu) { if (icpu) {
cpuidle_state_table = icpu->state_table; cpuidle_state_table = icpu->state_table;
if (icpu->use_acpi) if (icpu->use_acpi || force_use_acpi)
intel_idle_acpi_cst_extract(); intel_idle_acpi_cst_extract();
} else if (!intel_idle_acpi_cst_extract()) { } else if (!intel_idle_acpi_cst_extract()) {
return -ENODEV; return -ENODEV;