History

Merge tag 'pm-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management updates from Rafael Wysocki: "These add support for 'artificial' Energy Models in which power numbers for different entities may be in different scales, add support for some new hardware, fix bugs and clean up code in multiple places. Specifics: - Update the Energy Model support code to allow the Energy Model to be artificial, which means that the power values may not be on a uniform scale with other devices providing power information, and update the cpufreq_cooling and devfreq_cooling thermal drivers to support artificial Energy Models (Lukasz Luba). - Make DTPM check the Energy Model type (Lukasz Luba). - Fix policy counter decrementation in cpufreq if Energy Model is in use (Pierre Gondois). - Add CPU-based scaling support to passive devfreq governor (Saravana Kannan, Chanwoo Choi). - Update the rk3399_dmc devfreq driver (Brian Norris). - Export dev_pm_ops instead of suspend() and resume() in the IIO chemical scd30 driver (Jonathan Cameron). - Add namespace variants of EXPORT[_GPL]_SIMPLE_DEV_PM_OPS and PM-runtime counterparts (Jonathan Cameron). - Move symbol exports in the IIO chemical scd30 driver into the IIO_SCD30 namespace (Jonathan Cameron). - Avoid device PM-runtime usage count underflows (Rafael Wysocki). - Allow dynamic debug to control printing of PM messages (David Cohen). - Fix some kernel-doc comments in hibernation code (Yang Li, Haowen Bai). - Preserve ACPI-table override during hibernation (Amadeusz Sławiński). - Improve support for suspend-to-RAM for PSCI OSI mode (Ulf Hansson). - Make Intel RAPL power capping driver support the RaptorLake and AlderLake N processors (Zhang Rui, Sumeet Pawnikar). - Remove redundant store to value after multiply in the RAPL power capping driver (Colin Ian King). - Add AlderLake processor support to the intel_idle driver (Zhang Rui). - Fix regression leading to no genpd governor in the PSCI cpuidle driver and fix the riscv-sbi cpuidle driver to allow a genpd governor to be used (Ulf Hansson). - Fix cpufreq governor clean up code to avoid using kfree() directly to free kobject-based items (Kevin Hao). - Prepare cpufreq for powerpc's asm/prom.h cleanup (Christophe Leroy). - Make intel_pstate notify frequency invariance code when no_turbo is turned on and off (Chen Yu). - Add Sapphire Rapids OOB mode support to intel_pstate (Srinivas Pandruvada). - Make cpufreq avoid unnecessary frequency updates due to mismatch between hardware and the frequency table (Viresh Kumar). - Make remove_cpu_dev_symlink() clear the real_cpus mask to simplify code (Viresh Kumar). - Rearrange cpufreq_offline() and cpufreq_remove_dev() to make the calling convention for some driver callbacks consistent (Rafael Wysocki). - Avoid accessing half-initialized cpufreq policies from the show() and store() sysfs functions (Schspa Shi). - Rearrange cpufreq_offline() to make the calling convention for some driver callbacks consistent (Schspa Shi). - Update CPPC handling in cpufreq (Pierre Gondois). - Extend dev_pm_domain_detach() doc (Krzysztof Kozlowski). - Move genpd's time-accounting to ktime_get_mono_fast_ns() (Ulf Hansson). - Improve the way genpd deals with its governors (Ulf Hansson). - Update the turbostat utility to version 2022.04.16 (Len Brown, Dan Merillat, Sumeet Pawnikar, Zephaniah E. Loss-Cutler-Hull, Chen Yu)" * tag 'pm-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (94 commits) PM: domains: Trust domain-idle-states from DT to be correct by genpd PM: domains: Measure power-on/off latencies in genpd based on a governor PM: domains: Allocate governor data dynamically based on a genpd governor PM: domains: Clean up some code in pm_genpd_init() and genpd_remove() PM: domains: Fix initialization of genpd's next_wakeup PM: domains: Fixup QoS latency measurements for IRQ safe devices in genpd PM: domains: Measure suspend/resume latencies in genpd based on governor PM: domains: Move the next_wakeup variable into the struct gpd_timing_data PM: domains: Allocate gpd_timing_data dynamically based on governor PM: domains: Skip another warning in irq_safe_dev_in_sleep_domain() PM: domains: Rename irq_safe_dev_in_no_sleep_domain() in genpd PM: domains: Don't check PM_QOS_FLAG_NO_POWER_OFF in genpd PM: domains: Drop redundant code for genpd always-on governor PM: domains: Add GENPD_FLAG_RPM_ALWAYS_ON for the always-on governor powercap: intel_rapl: remove redundant store to value after multiply cpufreq: CPPC: Enable dvfs_possible_from_any_cpu cpufreq: CPPC: Enable fast_switch ACPI: CPPC: Assume no transition latency if no PCCT ACPI: bus: Set CPPC _OSC bits for all and when CPPC_LIB is supported ACPI: CPPC: Check _OSC for flexible address space ...

Linus Torvalds committed 4 years ago

Commit 09583df2 parents 1961b06 0d6448260 files · +2463 −1005Browse files

Showing the changes to kernel (5 of 60 files). Show all

Unified · Split

5 files
  1. kernel/power/Makefile +5 −1
  2. kernel/power/energy_model.c +36 −29
  3. kernel/power/main.c +0 −29
  4. kernel/power/process.c +0 −3
  5. kernel/power/snapshot.c +8 −4
kernel/power/Makefile+5−1
@@ -1,6 +1,10 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2 2
3ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG3ifeq ($(CONFIG_DYNAMIC_DEBUG), y)
4CFLAGS_swap.o := -DDEBUG
5CFLAGS_snapshot.o := -DDEBUG
6CFLAGS_energy_model.o := -DDEBUG
7endif
4 8
5KASAN_SANITIZE_snapshot.o := n9KASAN_SANITIZE_snapshot.o := n
6 10
kernel/power/energy_model.c+36−29
@@ -54,28 +54,15 @@ static int em_debug_cpus_show(struct seq_file *s, void *unused) · 53 unmodified lines
54}54}
55DEFINE_SHOW_ATTRIBUTE(em_debug_cpus);55DEFINE_SHOW_ATTRIBUTE(em_debug_cpus);
56 56
57static int em_debug_units_show(struct seq_file *s, void *unused)57static int em_debug_flags_show(struct seq_file *s, void *unused)
58{58{
59 struct em_perf_domain *pd = s->private;59 struct em_perf_domain *pd = s->private;
60 char *units = (pd->flags & EM_PERF_DOMAIN_MILLIWATTS) ?
61 "milliWatts" : "bogoWatts";
62 60
63 seq_printf(s, "%s\n", units);61 seq_printf(s, "%#lx\n", pd->flags);
64 62
65 return 0;63 return 0;
66}64}
67DEFINE_SHOW_ATTRIBUTE(em_debug_units);65DEFINE_SHOW_ATTRIBUTE(em_debug_flags);
68
69static int em_debug_skip_inefficiencies_show(struct seq_file *s, void *unused)
70{
71 struct em_perf_domain *pd = s->private;
72 int enabled = (pd->flags & EM_PERF_DOMAIN_SKIP_INEFFICIENCIES) ? 1 : 0;
73
74 seq_printf(s, "%d\n", enabled);
75
76 return 0;
77}
78DEFINE_SHOW_ATTRIBUTE(em_debug_skip_inefficiencies);
79 66
80static void em_debug_create_pd(struct device *dev)67static void em_debug_create_pd(struct device *dev)
81{68{
@@ -89,9 +76,8 @@ static void em_debug_create_pd(struct device *dev) · 7 unmodified lines
89 debugfs_create_file("cpus", 0444, d, dev->em_pd->cpus,76 debugfs_create_file("cpus", 0444, d, dev->em_pd->cpus,
90 &em_debug_cpus_fops);77 &em_debug_cpus_fops);
91 78
92 debugfs_create_file("units", 0444, d, dev->em_pd, &em_debug_units_fops);79 debugfs_create_file("flags", 0444, d, dev->em_pd,
93 debugfs_create_file("skip-inefficiencies", 0444, d, dev->em_pd,80 &em_debug_flags_fops);
94 &em_debug_skip_inefficiencies_fops);
95 81
96 /* Create a sub-directory for each performance state */82 /* Create a sub-directory for each performance state */
97 for (i = 0; i < dev->em_pd->nr_perf_states; i++)83 for (i = 0; i < dev->em_pd->nr_perf_states; i++)
@@ -121,7 +107,8 @@ static void em_debug_remove_pd(struct device *dev) {} · 23 unmodified lines
121#endif107#endif
122 108
123static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,109static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
124 int nr_states, struct em_data_callback *cb)110 int nr_states, struct em_data_callback *cb,
111 unsigned long flags)
125{112{
126 unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;113 unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX;
127 struct em_perf_state *table;114 struct em_perf_state *table;
@@ -139,7 +126,7 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, · 11 unmodified lines
139 * lowest performance state of 'dev' above 'freq' and updates126 * lowest performance state of 'dev' above 'freq' and updates
140 * 'power' and 'freq' accordingly.127 * 'power' and 'freq' accordingly.
141 */128 */
142 ret = cb->active_power(&power, &freq, dev);129 ret = cb->active_power(dev, &power, &freq);
143 if (ret) {130 if (ret) {
144 dev_err(dev, "EM: invalid perf. state: %d\n",131 dev_err(dev, "EM: invalid perf. state: %d\n",
145 ret);132 ret);
@@ -173,10 +160,22 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, · 27 unmodified lines
173 /* Compute the cost of each performance state. */160 /* Compute the cost of each performance state. */
174 fmax = (u64) table[nr_states - 1].frequency;161 fmax = (u64) table[nr_states - 1].frequency;
175 for (i = nr_states - 1; i >= 0; i--) {162 for (i = nr_states - 1; i >= 0; i--) {
176 unsigned long power_res = em_scale_power(table[i].power);163 unsigned long power_res, cost;
164
165 if (flags & EM_PERF_DOMAIN_ARTIFICIAL) {
166 ret = cb->get_cost(dev, table[i].frequency, &cost);
167 if (ret || !cost || cost > EM_MAX_POWER) {
168 dev_err(dev, "EM: invalid cost %lu %d\n",
169 cost, ret);
170 goto free_ps_table;
171 }
172 } else {
173 power_res = em_scale_power(table[i].power);
174 cost = div64_u64(fmax * power_res, table[i].frequency);
175 }
176
177 table[i].cost = cost;
177 178
178 table[i].cost = div64_u64(fmax * power_res,
179 table[i].frequency);
180 if (table[i].cost >= prev_cost) {179 if (table[i].cost >= prev_cost) {
181 table[i].flags = EM_PERF_STATE_INEFFICIENT;180 table[i].flags = EM_PERF_STATE_INEFFICIENT;
182 dev_dbg(dev, "EM: OPP:%lu is inefficient\n",181 dev_dbg(dev, "EM: OPP:%lu is inefficient\n",
@@ -197,7 +196,8 @@ free_ps_table: · 14 unmodified lines
197}196}
198 197
199static int em_create_pd(struct device *dev, int nr_states,198static int em_create_pd(struct device *dev, int nr_states,
200 struct em_data_callback *cb, cpumask_t *cpus)199 struct em_data_callback *cb, cpumask_t *cpus,
200 unsigned long flags)
201{201{
202 struct em_perf_domain *pd;202 struct em_perf_domain *pd;
203 struct device *cpu_dev;203 struct device *cpu_dev;
@@ -215,7 +215,7 @@ static int em_create_pd(struct device *dev, int nr_states, · 11 unmodified lines
215 return -ENOMEM;215 return -ENOMEM;
216 }216 }
217 217
218 ret = em_create_perf_table(dev, pd, nr_states, cb);218 ret = em_create_perf_table(dev, pd, nr_states, cb, flags);
219 if (ret) {219 if (ret) {
220 kfree(pd);220 kfree(pd);
221 return ret;221 return ret;
@@ -259,6 +259,8 @@ static void em_cpufreq_update_efficiencies(struct device *dev) · 37 unmodified lines
259 found++;259 found++;
260 }260 }
261 261
262 cpufreq_cpu_put(policy);
263
262 if (!found)264 if (!found)
263 return;265 return;
264 266
@@ -332,6 +334,7 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, · 67 unmodified lines
332 bool milliwatts)334 bool milliwatts)
333{335{
334 unsigned long cap, prev_cap = 0;336 unsigned long cap, prev_cap = 0;
337 unsigned long flags = 0;
335 int cpu, ret;338 int cpu, ret;
336 339
337 if (!dev || !nr_states || !cb)340 if (!dev || !nr_states || !cb)
@@ -378,12 +381,16 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, · 40 unmodified lines
378 }381 }
379 }382 }
380 383
381 ret = em_create_pd(dev, nr_states, cb, cpus);384 if (milliwatts)
385 flags |= EM_PERF_DOMAIN_MILLIWATTS;
386 else if (cb->get_cost)
387 flags |= EM_PERF_DOMAIN_ARTIFICIAL;
388
389 ret = em_create_pd(dev, nr_states, cb, cpus, flags);
382 if (ret)390 if (ret)
383 goto unlock;391 goto unlock;
384 392
385 if (milliwatts)393 dev->em_pd->flags |= flags;
386 dev->em_pd->flags |= EM_PERF_DOMAIN_MILLIWATTS;
387 394
388 em_cpufreq_update_efficiencies(dev);395 em_cpufreq_update_efficiencies(dev);
389 396
kernel/power/main.c+0−29
@@ -545,35 +545,6 @@ static int __init pm_debug_messages_setup(char *str) · 544 unmodified lines
545}545}
546__setup("pm_debug_messages", pm_debug_messages_setup);546__setup("pm_debug_messages", pm_debug_messages_setup);
547 547
548/**
549 * __pm_pr_dbg - Print a suspend debug message to the kernel log.
550 * @defer: Whether or not to use printk_deferred() to print the message.
551 * @fmt: Message format.
552 *
553 * The message will be emitted if enabled through the pm_debug_messages
554 * sysfs attribute.
555 */
556void __pm_pr_dbg(bool defer, const char *fmt, ...)
557{
558 struct va_format vaf;
559 va_list args;
560
561 if (!pm_debug_messages_on)
562 return;
563
564 va_start(args, fmt);
565
566 vaf.fmt = fmt;
567 vaf.va = &args;
568
569 if (defer)
570 printk_deferred(KERN_DEBUG "PM: %pV", &vaf);
571 else
572 printk(KERN_DEBUG "PM: %pV", &vaf);
573
574 va_end(args);
575}
576
577#else /* !CONFIG_PM_SLEEP_DEBUG */548#else /* !CONFIG_PM_SLEEP_DEBUG */
578static inline void pm_print_times_init(void) {}549static inline void pm_print_times_init(void) {}
579#endif /* CONFIG_PM_SLEEP_DEBUG */550#endif /* CONFIG_PM_SLEEP_DEBUG */
kernel/power/process.c+0−3
@@ -6,9 +6,6 @@ · 5 unmodified lines
6 * Originally from swsusp.6 * Originally from swsusp.
7 */7 */
8 8
9
10#undef DEBUG
11
12#include <linux/interrupt.h>9#include <linux/interrupt.h>
13#include <linux/oom.h>10#include <linux/oom.h>
14#include <linux/suspend.h>11#include <linux/suspend.h>
kernel/power/snapshot.c+8−4
@@ -326,7 +326,7 @@ static void *chain_alloc(struct chain_allocator *ca, unsigned int size) · 325 unmodified lines
326 return ret;326 return ret;
327}327}
328 328
329/**329/*
330 * Data types related to memory bitmaps.330 * Data types related to memory bitmaps.
331 *331 *
332 * Memory bitmap is a structure consisting of many linked lists of332 * Memory bitmap is a structure consisting of many linked lists of
@@ -427,6 +427,10 @@ struct memory_bitmap { · 94 unmodified lines
427 427
428/**428/**
429 * alloc_rtree_node - Allocate a new node and add it to the radix tree.429 * alloc_rtree_node - Allocate a new node and add it to the radix tree.
430 * @gfp_mask: GFP mask for the allocation.
431 * @safe_needed: Get pages not used before hibernation (restore only)
432 * @ca: Pointer to a linked list of pages ("a chain") to allocate from
433 * @list: Radix Tree node to add.
430 *434 *
431 * This function is used to allocate inner nodes as well as the435 * This function is used to allocate inner nodes as well as the
432 * leave nodes of the radix tree. It also adds the node to the436 * leave nodes of the radix tree. It also adds the node to the
@@ -902,7 +906,7 @@ static bool rtree_next_node(struct memory_bitmap *bm) · 469 unmodified lines
902}906}
903 907
904/**908/**
905 * memory_bm_rtree_next_pfn - Find the next set bit in a memory bitmap.909 * memory_bm_next_pfn - Find the next set bit in a memory bitmap.
906 * @bm: Memory bitmap.910 * @bm: Memory bitmap.
907 *911 *
908 * Starting from the last returned position this function searches for the next912 * Starting from the last returned position this function searches for the next
@@ -1937,7 +1941,7 @@ static inline int get_highmem_buffer(int safe_needed) · 1028 unmodified lines
1937}1941}
1938 1942
1939/**1943/**
1940 * alloc_highmem_image_pages - Allocate some highmem pages for the image.1944 * alloc_highmem_pages - Allocate some highmem pages for the image.
1941 *1945 *
1942 * Try to allocate as many pages as needed, but if the number of free highmem1946 * Try to allocate as many pages as needed, but if the number of free highmem
1943 * pages is less than that, allocate them all.1947 * pages is less than that, allocate them all.
@@ -2224,7 +2228,7 @@ static int check_header(struct swsusp_info *info) · 280 unmodified lines
2224}2228}
2225 2229
2226/**2230/**
2227 * load header - Check the image header and copy the data from it.2231 * load_header - Check the image header and copy the data from it.
2228 */2232 */
2229static int load_header(struct swsusp_info *info)2233static int load_header(struct swsusp_info *info)
2230{2234{