Skip to content

Commit fa31fc8

Browse files
committed
Merge tag 'pm-6.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power management updates from Rafael Wysocki: "These fix a hibernation test mode regression and clean up the intel_idle driver. Specifics: - Make test_resume work again after the changes that made hibernation open the snapshot device in exclusive mode (Chen Yu) - Clean up code in several places in intel_idle (Artem Bityutskiy)" * tag 'pm-6.4-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: intel_idle: mark few variables as __read_mostly intel_idle: do not sprinkle module parameter definitions around intel_idle: fix confusing message intel_idle: improve C-state flags handling robustness intel_idle: further intel_idle_init_cstates_icpu() cleanup intel_idle: clean up intel_idle_init_cstates_icpu() intel_idle: use pr_info() instead of printk() PM: hibernate: Do not get block device exclusively in test_resume mode PM: hibernate: Turn snapshot_test into global variable
2 parents 0153d8e + 57ea3ab commit fa31fc8

4 files changed

Lines changed: 56 additions & 27 deletions

File tree

drivers/idle/intel_idle.c

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ static struct cpuidle_driver intel_idle_driver = {
6666
};
6767
/* intel_idle.max_cstate=0 disables driver */
6868
static int max_cstate = CPUIDLE_STATE_MAX - 1;
69-
static unsigned int disabled_states_mask;
70-
static unsigned int preferred_states_mask;
69+
static unsigned int disabled_states_mask __read_mostly;
70+
static unsigned int preferred_states_mask __read_mostly;
71+
static bool force_irq_on __read_mostly;
7172

7273
static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
7374

@@ -1838,9 +1839,6 @@ static bool __init intel_idle_verify_cstate(unsigned int mwait_hint)
18381839
return true;
18391840
}
18401841

1841-
static bool force_irq_on __read_mostly;
1842-
module_param(force_irq_on, bool, 0444);
1843-
18441842
static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
18451843
{
18461844
int cstate;
@@ -1871,6 +1869,7 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
18711869
}
18721870

18731871
for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
1872+
struct cpuidle_state *state;
18741873
unsigned int mwait_hint;
18751874

18761875
if (intel_idle_max_cstate_reached(cstate))
@@ -1893,29 +1892,39 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
18931892

18941893
/* Structure copy. */
18951894
drv->states[drv->state_count] = cpuidle_state_table[cstate];
1896-
1897-
if ((cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE) || force_irq_on) {
1898-
printk("intel_idle: forced intel_idle_irq for state %d\n", cstate);
1899-
drv->states[drv->state_count].enter = intel_idle_irq;
1900-
}
1901-
1902-
if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) &&
1903-
cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IBRS) {
1904-
WARN_ON_ONCE(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE);
1905-
drv->states[drv->state_count].enter = intel_idle_ibrs;
1895+
state = &drv->states[drv->state_count];
1896+
1897+
if (state->flags & CPUIDLE_FLAG_INIT_XSTATE) {
1898+
/*
1899+
* Combining with XSTATE with IBRS or IRQ_ENABLE flags
1900+
* is not currently supported but this driver.
1901+
*/
1902+
WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IBRS);
1903+
WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IRQ_ENABLE);
1904+
state->enter = intel_idle_xstate;
1905+
} else if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) &&
1906+
state->flags & CPUIDLE_FLAG_IBRS) {
1907+
/*
1908+
* IBRS mitigation requires that C-states are entered
1909+
* with interrupts disabled.
1910+
*/
1911+
WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IRQ_ENABLE);
1912+
state->enter = intel_idle_ibrs;
1913+
} else if (state->flags & CPUIDLE_FLAG_IRQ_ENABLE) {
1914+
state->enter = intel_idle_irq;
1915+
} else if (force_irq_on) {
1916+
pr_info("forced intel_idle_irq for state %d\n", cstate);
1917+
state->enter = intel_idle_irq;
19061918
}
19071919

1908-
if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_INIT_XSTATE)
1909-
drv->states[drv->state_count].enter = intel_idle_xstate;
1910-
19111920
if ((disabled_states_mask & BIT(drv->state_count)) ||
19121921
((icpu->use_acpi || force_use_acpi) &&
19131922
intel_idle_off_by_default(mwait_hint) &&
1914-
!(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
1915-
drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF;
1923+
!(state->flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
1924+
state->flags |= CPUIDLE_FLAG_OFF;
19161925

1917-
if (intel_idle_state_needs_timer_stop(&drv->states[drv->state_count]))
1918-
drv->states[drv->state_count].flags |= CPUIDLE_FLAG_TIMER_STOP;
1926+
if (intel_idle_state_needs_timer_stop(state))
1927+
state->flags |= CPUIDLE_FLAG_TIMER_STOP;
19191928

19201929
drv->state_count++;
19211930
}
@@ -2146,3 +2155,9 @@ MODULE_PARM_DESC(states_off, "Mask of disabled idle states");
21462155
*/
21472156
module_param_named(preferred_cstates, preferred_states_mask, uint, 0444);
21482157
MODULE_PARM_DESC(preferred_cstates, "Mask of preferred idle states");
2158+
/*
2159+
* Debugging option that forces the driver to enter all C-states with
2160+
* interrupts enabled. Does not apply to C-states with
2161+
* 'CPUIDLE_FLAG_INIT_XSTATE' and 'CPUIDLE_FLAG_IBRS' flags.
2162+
*/
2163+
module_param(force_irq_on, bool, 0444);

kernel/power/hibernate.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ enum {
6464
static int hibernation_mode = HIBERNATION_SHUTDOWN;
6565

6666
bool freezer_test_done;
67+
bool snapshot_test;
6768

6869
static const struct platform_hibernation_ops *hibernation_ops;
6970

@@ -687,18 +688,22 @@ static int load_image_and_restore(void)
687688
{
688689
int error;
689690
unsigned int flags;
691+
fmode_t mode = FMODE_READ;
692+
693+
if (snapshot_test)
694+
mode |= FMODE_EXCL;
690695

691696
pm_pr_dbg("Loading hibernation image.\n");
692697

693698
lock_device_hotplug();
694699
error = create_basic_memory_bitmaps();
695700
if (error) {
696-
swsusp_close(FMODE_READ | FMODE_EXCL);
701+
swsusp_close(mode);
697702
goto Unlock;
698703
}
699704

700705
error = swsusp_read(&flags);
701-
swsusp_close(FMODE_READ | FMODE_EXCL);
706+
swsusp_close(mode);
702707
if (!error)
703708
error = hibernation_restore(flags & SF_PLATFORM_MODE);
704709

@@ -716,7 +721,6 @@ static int load_image_and_restore(void)
716721
*/
717722
int hibernate(void)
718723
{
719-
bool snapshot_test = false;
720724
unsigned int sleep_flags;
721725
int error;
722726

@@ -744,6 +748,9 @@ int hibernate(void)
744748
if (error)
745749
goto Exit;
746750

751+
/* protected by system_transition_mutex */
752+
snapshot_test = false;
753+
747754
lock_device_hotplug();
748755
/* Allocate memory management structures */
749756
error = create_basic_memory_bitmaps();
@@ -940,6 +947,8 @@ static int software_resume(void)
940947
*/
941948
mutex_lock_nested(&system_transition_mutex, SINGLE_DEPTH_NESTING);
942949

950+
snapshot_test = false;
951+
943952
if (swsusp_resume_device)
944953
goto Check_image;
945954

kernel/power/power.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ asmlinkage int swsusp_save(void);
5959

6060
/* kernel/power/hibernate.c */
6161
extern bool freezer_test_done;
62+
extern bool snapshot_test;
6263

6364
extern int hibernation_snapshot(int platform_mode);
6465
extern int hibernation_restore(int platform_mode);

kernel/power/swap.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,9 +1518,13 @@ int swsusp_check(void)
15181518
{
15191519
int error;
15201520
void *holder;
1521+
fmode_t mode = FMODE_READ;
1522+
1523+
if (snapshot_test)
1524+
mode |= FMODE_EXCL;
15211525

15221526
hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
1523-
FMODE_READ | FMODE_EXCL, &holder);
1527+
mode, &holder);
15241528
if (!IS_ERR(hib_resume_bdev)) {
15251529
set_blocksize(hib_resume_bdev, PAGE_SIZE);
15261530
clear_page(swsusp_header);
@@ -1547,7 +1551,7 @@ int swsusp_check(void)
15471551

15481552
put:
15491553
if (error)
1550-
blkdev_put(hib_resume_bdev, FMODE_READ | FMODE_EXCL);
1554+
blkdev_put(hib_resume_bdev, mode);
15511555
else
15521556
pr_debug("Image signature found, resuming\n");
15531557
} else {

0 commit comments

Comments
 (0)