Skip to content

Commit 21bdb58

Browse files
committed
Merge tag 'pm+acpi-4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
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()
2 parents 3e87ee0 + 17ffc8b commit 21bdb58

File tree

4 files changed

+32
-20
lines changed

4 files changed

+32
-20
lines changed

drivers/acpi/resource.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ static bool acpi_decode_space(struct resource_win *win,
193193
u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16;
194194
bool wp = addr->info.mem.write_protect;
195195
u64 len = attr->address_length;
196+
u64 start, end, offset = 0;
196197
struct resource *res = &win->res;
197198

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

207-
res->start = attr->minimum;
208-
res->end = attr->maximum;
209-
210208
/*
211209
* For bridges that translate addresses across the bridge,
212210
* translation_offset is the offset that must be added to the
213211
* address on the secondary side to obtain the address on the
214212
* primary side. Non-bridge devices must list 0 for all Address
215213
* Translation offset bits.
216214
*/
217-
if (addr->producer_consumer == ACPI_PRODUCER) {
218-
res->start += attr->translation_offset;
219-
res->end += attr->translation_offset;
220-
} else if (attr->translation_offset) {
215+
if (addr->producer_consumer == ACPI_PRODUCER)
216+
offset = attr->translation_offset;
217+
else if (attr->translation_offset)
221218
pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n",
222219
attr->translation_offset);
220+
start = attr->minimum + offset;
221+
end = attr->maximum + offset;
222+
223+
win->offset = offset;
224+
res->start = start;
225+
res->end = end;
226+
if (sizeof(resource_size_t) < sizeof(u64) &&
227+
(offset != win->offset || start != res->start || end != res->end)) {
228+
pr_warn("acpi resource window ([%#llx-%#llx] ignored, not CPU addressable)\n",
229+
attr->minimum, attr->maximum);
230+
return false;
223231
}
224232

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

239-
win->offset = attr->translation_offset;
240-
241247
if (addr->producer_consumer == ACPI_PRODUCER)
242248
res->flags |= IORESOURCE_WINDOW;
243249

drivers/cpufreq/cpufreq.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,15 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
169169
}
170170
EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
171171

172+
struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
173+
{
174+
struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
175+
176+
return policy && !policy_is_inactive(policy) ?
177+
policy->freq_table : NULL;
178+
}
179+
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
180+
172181
static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
173182
{
174183
u64 idle_time;
@@ -1132,6 +1141,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
11321141

11331142
down_write(&policy->rwsem);
11341143
policy->cpu = cpu;
1144+
policy->governor = NULL;
11351145
up_write(&policy->rwsem);
11361146
}
11371147

drivers/cpufreq/freq_table.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,6 @@ int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
297297
}
298298
EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show);
299299

300-
struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu);
301-
302-
struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
303-
{
304-
struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
305-
return policy ? policy->freq_table : NULL;
306-
}
307-
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
308-
309300
MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
310301
MODULE_DESCRIPTION("CPUfreq frequency table helpers");
311302
MODULE_LICENSE("GPL");

drivers/cpuidle/cpuidle.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,12 @@ int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
112112
static void enter_freeze_proper(struct cpuidle_driver *drv,
113113
struct cpuidle_device *dev, int index)
114114
{
115-
tick_freeze();
115+
/*
116+
* trace_suspend_resume() called by tick_freeze() for the last CPU
117+
* executing it contains RCU usage regarded as invalid in the idle
118+
* context, so tell RCU about that.
119+
*/
120+
RCU_NONIDLE(tick_freeze());
116121
/*
117122
* The state used here cannot be a "coupled" one, because the "coupled"
118123
* cpuidle mechanism enables interrupts and doing that with timekeeping
@@ -122,7 +127,7 @@ static void enter_freeze_proper(struct cpuidle_driver *drv,
122127
WARN_ON(!irqs_disabled());
123128
/*
124129
* timekeeping_resume() that will be called by tick_unfreeze() for the
125-
* last CPU executing it calls functions containing RCU read-side
130+
* first CPU executing it calls functions containing RCU read-side
126131
* critical sections, so tell RCU about that.
127132
*/
128133
RCU_NONIDLE(tick_unfreeze());

0 commit comments

Comments
 (0)