Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21bdb584 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull power management and ACPI fixes from Rafael Wysocki:
 "These fix two bugs in the cpufreq core (including one recent
  regression), fix a 4.0 PCI regression related to the ACPI resources
  management and quieten an RCU-related lockdep complaint about a
  tracepoint in the suspend-to-idle code.

  Specifics:

   - Fix a recently introduced issue in the cpufreq policy object
     reinitialization that leads to CPU offline/online breakage (Viresh
     Kumar)

   - Make it possible to access frequency tables of offline CPUs which
     is needed by thermal management code among other things (Viresh
     Kumar)

   - Fix an ACPI resource management regression introduced during the
     4.0 cycle that may cause incorrect resource validation results to
     appear in 32-bit x86 kernels due to silent truncation of 64-bit
     values to 32-bit (Jiang Liu)

   - Fix up an RCU-related lockdep complaint about suspicious RCU usage
     in idle caused by using a suspend tracepoint in the core suspend-
     to-idle code (Rafael J Wysocki)"

* tag 'pm+acpi-4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / PCI: Fix regressions caused by resource_size_t overflow with 32-bit kernel
  cpufreq: Allow freq_table to be obtained for offline CPUs
  cpufreq: Initialize the governor again while restoring policy
  suspend-to-idle: Prevent RCU from complaining about tick_freeze()
parents 3e87ee06 17ffc8b0
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ static bool acpi_decode_space(struct resource_win *win,
	u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16;
	bool wp = addr->info.mem.write_protect;
	u64 len = attr->address_length;
	u64 start, end, offset = 0;
	struct resource *res = &win->res;

	/*
@@ -204,9 +205,6 @@ static bool acpi_decode_space(struct resource_win *win,
		pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n",
			 addr->min_address_fixed, addr->max_address_fixed, len);

	res->start = attr->minimum;
	res->end = attr->maximum;

	/*
	 * For bridges that translate addresses across the bridge,
	 * translation_offset is the offset that must be added to the
@@ -214,12 +212,22 @@ static bool acpi_decode_space(struct resource_win *win,
	 * primary side. Non-bridge devices must list 0 for all Address
	 * Translation offset bits.
	 */
	if (addr->producer_consumer == ACPI_PRODUCER) {
		res->start += attr->translation_offset;
		res->end += attr->translation_offset;
	} else if (attr->translation_offset) {
	if (addr->producer_consumer == ACPI_PRODUCER)
		offset = attr->translation_offset;
	else if (attr->translation_offset)
		pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n",
			 attr->translation_offset);
	start = attr->minimum + offset;
	end = attr->maximum + offset;

	win->offset = offset;
	res->start = start;
	res->end = end;
	if (sizeof(resource_size_t) < sizeof(u64) &&
	    (offset != win->offset || start != res->start || end != res->end)) {
		pr_warn("acpi resource window ([%#llx-%#llx] ignored, not CPU addressable)\n",
			attr->minimum, attr->maximum);
		return false;
	}

	switch (addr->resource_type) {
@@ -236,8 +244,6 @@ static bool acpi_decode_space(struct resource_win *win,
		return false;
	}

	win->offset = attr->translation_offset;

	if (addr->producer_consumer == ACPI_PRODUCER)
		res->flags |= IORESOURCE_WINDOW;

+10 −0
Original line number Diff line number Diff line
@@ -169,6 +169,15 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
}
EXPORT_SYMBOL_GPL(get_governor_parent_kobj);

struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
{
	struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);

	return policy && !policy_is_inactive(policy) ?
		policy->freq_table : NULL;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);

static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
{
	u64 idle_time;
@@ -1132,6 +1141,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)

		down_write(&policy->rwsem);
		policy->cpu = cpu;
		policy->governor = NULL;
		up_write(&policy->rwsem);
	}

+0 −9
Original line number Diff line number Diff line
@@ -297,15 +297,6 @@ int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
}
EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show);

struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu);

struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
{
	struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
	return policy ? policy->freq_table : NULL;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);

MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION("CPUfreq frequency table helpers");
MODULE_LICENSE("GPL");
+7 −2
Original line number Diff line number Diff line
@@ -112,7 +112,12 @@ int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
static void enter_freeze_proper(struct cpuidle_driver *drv,
				struct cpuidle_device *dev, int index)
{
	tick_freeze();
	/*
	 * trace_suspend_resume() called by tick_freeze() for the last CPU
	 * executing it contains RCU usage regarded as invalid in the idle
	 * context, so tell RCU about that.
	 */
	RCU_NONIDLE(tick_freeze());
	/*
	 * The state used here cannot be a "coupled" one, because the "coupled"
	 * cpuidle mechanism enables interrupts and doing that with timekeeping
@@ -122,7 +127,7 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,
	WARN_ON(!irqs_disabled());
	/*
	 * timekeeping_resume() that will be called by tick_unfreeze() for the
	 * last CPU executing it calls functions containing RCU read-side
	 * first CPU executing it calls functions containing RCU read-side
	 * critical sections, so tell RCU about that.
	 */
	RCU_NONIDLE(tick_unfreeze());