Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull power management fixes from Rafael Wysocki:
"Fix three issues introduced into device suspend/resume error paths in
the PM core by some of the recent updates.

First off, replace list_splice() with list_splice_init() in three
places in device suspend error paths to avoid attempting to use an
uninitialized list head going forward.

Second, rearrange device_resume() to avoid leaking the
power.is_suspended device PM flag to the next system suspend/resume
cycle where it can confuse rolling back after an error or early
wakeup.

Finally, add synchronization to dpm_async_resume_children() to avoid
resetting the async state mistakenly for devices whose resume
callbacks have already been queued up for asynchronous execution in
the given device resume phase, which fortunately can happen only if
the preceding system suspend transition has been aborted"

* tag 'pm-6.16-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM: sleep: Add locking to dpm_async_resume_children()
PM: sleep: Fix power.is_suspended cleanup for direct-complete devices
PM: sleep: Fix list splicing in device suspend error paths

+12 -4
+12 -4
drivers/base/power/main.c
··· 638 638 static void dpm_async_resume_children(struct device *dev, async_func_t func) 639 639 { 640 640 /* 641 + * Prevent racing with dpm_clear_async_state() during initial list 642 + * walks in dpm_noirq_resume_devices(), dpm_resume_early(), and 643 + * dpm_resume(). 644 + */ 645 + guard(mutex)(&dpm_list_mtx); 646 + 647 + /* 641 648 * Start processing "async" children of the device unless it's been 642 649 * started already for them. 643 650 * ··· 992 985 if (!dev->power.is_suspended) 993 986 goto Complete; 994 987 988 + dev->power.is_suspended = false; 989 + 995 990 if (dev->power.direct_complete) { 996 991 /* 997 992 * Allow new children to be added under the device after this ··· 1056 1047 1057 1048 End: 1058 1049 error = dpm_run_callback(callback, dev, state, info); 1059 - dev->power.is_suspended = false; 1060 1050 1061 1051 device_unlock(dev); 1062 1052 dpm_watchdog_clear(&wd); ··· 1459 1451 * Move all devices to the target list to resume them 1460 1452 * properly. 1461 1453 */ 1462 - list_splice(&dpm_late_early_list, &dpm_noirq_list); 1454 + list_splice_init(&dpm_late_early_list, &dpm_noirq_list); 1463 1455 break; 1464 1456 } 1465 1457 } ··· 1661 1653 * Move all devices to the target list to resume them 1662 1654 * properly. 1663 1655 */ 1664 - list_splice(&dpm_suspended_list, &dpm_late_early_list); 1656 + list_splice_init(&dpm_suspended_list, &dpm_late_early_list); 1665 1657 break; 1666 1658 } 1667 1659 } ··· 1954 1946 * Move all devices to the target list to resume them 1955 1947 * properly. 1956 1948 */ 1957 - list_splice(&dpm_prepared_list, &dpm_suspended_list); 1949 + list_splice_init(&dpm_prepared_list, &dpm_suspended_list); 1958 1950 break; 1959 1951 } 1960 1952 }