Skip to content

Commit 4cdb2b3

Browse files
committed
Merge: update cpuidle to match Linux v6.12
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/5570 JIRA: https://issues.redhat.com/browse/RHEL-64032 Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com> Approved-by: Herton R. Krzesinski <herton@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Patrick Talbert <ptalbert@redhat.com>
2 parents 6d4d7d5 + 195eada commit 4cdb2b3

File tree

15 files changed

+116
-85
lines changed

15 files changed

+116
-85
lines changed

drivers/cpuidle/coupled.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -439,13 +439,8 @@ static int cpuidle_coupled_clear_pokes(int cpu)
439439

440440
static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled)
441441
{
442-
cpumask_t cpus;
443-
int ret;
444-
445-
cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus);
446-
ret = cpumask_and(&cpus, &cpuidle_coupled_poke_pending, &cpus);
447-
448-
return ret;
442+
return cpumask_first_and_and(cpu_online_mask, &coupled->coupled_cpus,
443+
&cpuidle_coupled_poke_pending) < nr_cpu_ids;
449444
}
450445

451446
/**
@@ -626,9 +621,7 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
626621

627622
static void cpuidle_coupled_update_online_cpus(struct cpuidle_coupled *coupled)
628623
{
629-
cpumask_t cpus;
630-
cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus);
631-
coupled->online_count = cpumask_weight(&cpus);
624+
coupled->online_count = cpumask_weight_and(cpu_online_mask, &coupled->coupled_cpus);
632625
}
633626

634627
/**

drivers/cpuidle/cpuidle-haltpoll.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ MODULE_PARM_DESC(force, "Load unconditionally");
2525
static struct cpuidle_device __percpu *haltpoll_cpuidle_devices;
2626
static enum cpuhp_state haltpoll_hp_state;
2727

28-
static int default_enter_idle(struct cpuidle_device *dev,
29-
struct cpuidle_driver *drv, int index)
28+
static __cpuidle int default_enter_idle(struct cpuidle_device *dev,
29+
struct cpuidle_driver *drv, int index)
3030
{
31-
if (current_clr_polling_and_test()) {
32-
local_irq_enable();
31+
if (current_clr_polling_and_test())
3332
return index;
34-
}
33+
3534
arch_cpu_idle();
3635
return index;
3736
}
@@ -142,5 +141,6 @@ static void __exit haltpoll_exit(void)
142141

143142
module_init(haltpoll_init);
144143
module_exit(haltpoll_exit);
144+
MODULE_DESCRIPTION("cpuidle driver for haltpoll governor");
145145
MODULE_LICENSE("GPL");
146146
MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>");

drivers/cpuidle/cpuidle-psci-domain.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/string.h>
2121

2222
#include "cpuidle-psci.h"
23+
#include "dt_idle_genpd.h"
2324

2425
struct psci_pd_provider {
2526
struct list_head link;
@@ -66,12 +67,16 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
6667

6768
/*
6869
* Allow power off when OSI has been successfully enabled.
69-
* PREEMPT_RT is not yet ready to enter domain idle states.
70+
* On a PREEMPT_RT based configuration the domain idle states are
71+
* supported, but only during system-wide suspend.
7072
*/
71-
if (use_osi && !IS_ENABLED(CONFIG_PREEMPT_RT))
73+
if (use_osi) {
7274
pd->power_off = psci_pd_power_off;
73-
else
75+
if (IS_ENABLED(CONFIG_PREEMPT_RT))
76+
pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
77+
} else {
7478
pd->flags |= GENPD_FLAG_ALWAYS_ON;
79+
}
7580

7681
/* Use governor for CPU PM domains if it has some states to manage. */
7782
pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
@@ -137,7 +142,6 @@ static const struct of_device_id psci_of_match[] = {
137142
static int psci_cpuidle_domain_probe(struct platform_device *pdev)
138143
{
139144
struct device_node *np = pdev->dev.of_node;
140-
struct device_node *node;
141145
bool use_osi = psci_has_osi_support();
142146
int ret = 0, pd_count = 0;
143147

@@ -148,15 +152,13 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev)
148152
* Parse child nodes for the "#power-domain-cells" property and
149153
* initialize a genpd/genpd-of-provider pair when it's found.
150154
*/
151-
for_each_child_of_node(np, node) {
155+
for_each_child_of_node_scoped(np, node) {
152156
if (!of_property_present(node, "#power-domain-cells"))
153157
continue;
154158

155159
ret = psci_pd_init(node, use_osi);
156-
if (ret) {
157-
of_node_put(node);
160+
if (ret)
158161
goto exit;
159-
}
160162

161163
pd_count++;
162164
}
@@ -200,4 +202,4 @@ static int __init psci_idle_init_domains(void)
200202
{
201203
return platform_driver_register(&psci_cpuidle_domain_driver);
202204
}
203-
subsys_initcall(psci_idle_init_domains);
205+
core_initcall(psci_idle_init_domains);

drivers/cpuidle/cpuidle-psci.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include "cpuidle-psci.h"
3030
#include "dt_idle_states.h"
31+
#include "dt_idle_genpd.h"
3132

3233
struct psci_cpuidle_data {
3334
u32 *psci_states;
@@ -36,6 +37,7 @@ struct psci_cpuidle_data {
3637

3738
static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data);
3839
static DEFINE_PER_CPU(u32, domain_state);
40+
static bool psci_cpuidle_use_syscore;
3941
static bool psci_cpuidle_use_cpuhp;
4042

4143
void psci_set_domain_state(u32 state)
@@ -165,15 +167,19 @@ static struct syscore_ops psci_idle_syscore_ops = {
165167
.resume = psci_idle_syscore_resume,
166168
};
167169

170+
static void psci_idle_init_syscore(void)
171+
{
172+
if (psci_cpuidle_use_syscore)
173+
register_syscore_ops(&psci_idle_syscore_ops);
174+
}
175+
168176
static void psci_idle_init_cpuhp(void)
169177
{
170178
int err;
171179

172180
if (!psci_cpuidle_use_cpuhp)
173181
return;
174182

175-
register_syscore_ops(&psci_idle_syscore_ops);
176-
177183
err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
178184
"cpuidle/psci:online",
179185
psci_idle_cpuhp_up,
@@ -221,22 +227,23 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
221227
if (!psci_has_osi_support())
222228
return 0;
223229

224-
if (IS_ENABLED(CONFIG_PREEMPT_RT))
225-
return 0;
226-
227-
data->dev = psci_dt_attach_cpu(cpu);
230+
data->dev = dt_idle_attach_cpu(cpu, "psci");
228231
if (IS_ERR_OR_NULL(data->dev))
229232
return PTR_ERR_OR_ZERO(data->dev);
230233

234+
psci_cpuidle_use_syscore = true;
235+
231236
/*
232237
* Using the deepest state for the CPU to trigger a potential selection
233238
* of a shared state for the domain, assumes the domain states are all
234-
* deeper states.
239+
* deeper states. On PREEMPT_RT the hierarchical topology is limited to
240+
* s2ram and s2idle.
235241
*/
236-
drv->states[state_count - 1].flags |= CPUIDLE_FLAG_RCU_IDLE;
237-
drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
238242
drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
239-
psci_cpuidle_use_cpuhp = true;
243+
if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
244+
drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
245+
psci_cpuidle_use_cpuhp = true;
246+
}
240247

241248
return 0;
242249
}
@@ -311,7 +318,8 @@ static void psci_cpu_deinit_idle(int cpu)
311318
{
312319
struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
313320

314-
psci_dt_detach_cpu(data->dev);
321+
dt_idle_detach_cpu(data->dev);
322+
psci_cpuidle_use_syscore = false;
315323
psci_cpuidle_use_cpuhp = false;
316324
}
317325

@@ -408,6 +416,7 @@ static int psci_cpuidle_probe(struct platform_device *pdev)
408416
goto out_fail;
409417
}
410418

419+
psci_idle_init_syscore();
411420
psci_idle_init_cpuhp();
412421
return 0;
413422

drivers/cpuidle/cpuidle-psci.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,9 @@
33
#ifndef __CPUIDLE_PSCI_H
44
#define __CPUIDLE_PSCI_H
55

6-
struct device;
76
struct device_node;
87

98
void psci_set_domain_state(u32 state);
109
int psci_dt_parse_state_node(struct device_node *np, u32 *state);
1110

12-
#ifdef CONFIG_ARM_PSCI_CPUIDLE_DOMAIN
13-
14-
#include "dt_idle_genpd.h"
15-
16-
static inline struct device *psci_dt_attach_cpu(int cpu)
17-
{
18-
return dt_idle_attach_cpu(cpu, "psci");
19-
}
20-
21-
static inline void psci_dt_detach_cpu(struct device *dev)
22-
{
23-
dt_idle_detach_cpu(dev);
24-
}
25-
26-
#else
27-
static inline struct device *psci_dt_attach_cpu(int cpu) { return NULL; }
28-
static inline void psci_dt_detach_cpu(struct device *dev) { }
29-
#endif
30-
3111
#endif /* __CPUIDLE_PSCI_H */

drivers/cpuidle/cpuidle-pseries.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ static void __init fixup_cede0_latency(void)
407407
* pseries_idle_probe()
408408
* Choose state table for shared versus dedicated partition
409409
*/
410-
static int pseries_idle_probe(void)
410+
static int __init pseries_idle_probe(void)
411411
{
412412

413413
if (cpuidle_disable != IDLE_NO_OVERRIDE)

drivers/cpuidle/cpuidle.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,7 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
228228
if (broadcast && tick_broadcast_enter()) {
229229
index = find_deepest_state(drv, dev, target_state->exit_latency_ns,
230230
CPUIDLE_FLAG_TIMER_STOP, false);
231-
if (index < 0) {
232-
default_idle_call();
233-
return -EBUSY;
234-
}
231+
235232
target_state = &drv->states[index];
236233
broadcast = false;
237234
}

drivers/cpuidle/driver.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/cpumask.h>
1717
#include <linux/tick.h>
1818
#include <linux/cpu.h>
19+
#include <linux/math64.h>
1920

2021
#include "cpuidle.h"
2122

@@ -187,7 +188,7 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
187188
s->target_residency = div_u64(s->target_residency_ns, NSEC_PER_USEC);
188189

189190
if (s->exit_latency > 0)
190-
s->exit_latency_ns = s->exit_latency * NSEC_PER_USEC;
191+
s->exit_latency_ns = mul_u32_u32(s->exit_latency, NSEC_PER_USEC);
191192
else if (s->exit_latency_ns < 0)
192193
s->exit_latency_ns = 0;
193194
else

drivers/cpuidle/dt_idle_genpd.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,10 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np,
130130

131131
int dt_idle_pd_init_topology(struct device_node *np)
132132
{
133-
struct device_node *node;
134133
struct of_phandle_args child, parent;
135134
int ret;
136135

137-
for_each_child_of_node(np, node) {
136+
for_each_child_of_node_scoped(np, node) {
138137
if (of_parse_phandle_with_args(node, "power-domains",
139138
"#power-domain-cells", 0, &parent))
140139
continue;
@@ -143,22 +142,19 @@ int dt_idle_pd_init_topology(struct device_node *np)
143142
child.args_count = 0;
144143
ret = of_genpd_add_subdomain(&parent, &child);
145144
of_node_put(parent.np);
146-
if (ret) {
147-
of_node_put(node);
145+
if (ret)
148146
return ret;
149-
}
150147
}
151148

152149
return 0;
153150
}
154151

155152
int dt_idle_pd_remove_topology(struct device_node *np)
156153
{
157-
struct device_node *node;
158154
struct of_phandle_args child, parent;
159155
int ret;
160156

161-
for_each_child_of_node(np, node) {
157+
for_each_child_of_node_scoped(np, node) {
162158
if (of_parse_phandle_with_args(node, "power-domains",
163159
"#power-domain-cells", 0, &parent))
164160
continue;
@@ -167,10 +163,8 @@ int dt_idle_pd_remove_topology(struct device_node *np)
167163
child.args_count = 0;
168164
ret = of_genpd_remove_subdomain(&parent, &child);
169165
of_node_put(parent.np);
170-
if (ret) {
171-
of_node_put(node);
166+
if (ret)
172167
return ret;
173-
}
174168
}
175169

176170
return 0;

drivers/cpuidle/governors/haltpoll.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,15 @@ static void adjust_poll_limit(struct cpuidle_device *dev, u64 block_ns)
9898
unsigned int shrink = guest_halt_poll_shrink;
9999

100100
val = dev->poll_limit_ns;
101-
if (shrink == 0)
101+
if (shrink == 0) {
102102
val = 0;
103-
else
103+
} else {
104104
val /= shrink;
105+
/* Reset value to 0 if shrunk below grow_start */
106+
if (val < guest_halt_poll_grow_start)
107+
val = 0;
108+
}
109+
105110
trace_guest_halt_poll_ns_shrink(val, dev->poll_limit_ns);
106111
dev->poll_limit_ns = val;
107112
}

0 commit comments

Comments
 (0)