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-5.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"Revert two problematic commits.

Specifics:

- Revert ACPI PM commit that attempted to improve reboot handling on
some systems, but it caused other systems to panic() during reboot
(Josef Bacik)

- Revert PM-runtime commit that attempted to improve the handling of
suppliers during PM-runtime suspend of a consumer device, but it
introduced a race condition potentially leading to unexpected
behavior (Rafael Wysocki)"

* tag 'pm-5.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Revert "PM: runtime: Update device status before letting suppliers suspend"
Revert "PM: ACPI: reboot: Use S5 for reboot"

+25 -39
+25 -37
drivers/base/power/runtime.c
··· 325 325 static int __rpm_callback(int (*cb)(struct device *), struct device *dev) 326 326 __releases(&dev->power.lock) __acquires(&dev->power.lock) 327 327 { 328 - bool use_links = dev->power.links_count > 0; 329 - bool get = false; 330 328 int retval, idx; 331 - bool put; 329 + bool use_links = dev->power.links_count > 0; 332 330 333 331 if (dev->power.irq_safe) { 334 332 spin_unlock(&dev->power.lock); 335 - } else if (!use_links) { 336 - spin_unlock_irq(&dev->power.lock); 337 333 } else { 338 - get = dev->power.runtime_status == RPM_RESUMING; 339 - 340 334 spin_unlock_irq(&dev->power.lock); 341 335 342 - /* Resume suppliers if necessary. */ 343 - if (get) { 336 + /* 337 + * Resume suppliers if necessary. 338 + * 339 + * The device's runtime PM status cannot change until this 340 + * routine returns, so it is safe to read the status outside of 341 + * the lock. 342 + */ 343 + if (use_links && dev->power.runtime_status == RPM_RESUMING) { 344 344 idx = device_links_read_lock(); 345 345 346 346 retval = rpm_get_suppliers(dev); ··· 355 355 356 356 if (dev->power.irq_safe) { 357 357 spin_lock(&dev->power.lock); 358 - return retval; 359 - } 358 + } else { 359 + /* 360 + * If the device is suspending and the callback has returned 361 + * success, drop the usage counters of the suppliers that have 362 + * been reference counted on its resume. 363 + * 364 + * Do that if resume fails too. 365 + */ 366 + if (use_links 367 + && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) 368 + || (dev->power.runtime_status == RPM_RESUMING && retval))) { 369 + idx = device_links_read_lock(); 360 370 361 - spin_lock_irq(&dev->power.lock); 371 + fail: 372 + rpm_put_suppliers(dev); 362 373 363 - if (!use_links) 364 - return retval; 365 - 366 - /* 367 - * If the device is suspending and the callback has returned success, 368 - * drop the usage counters of the suppliers that have been reference 369 - * counted on its resume. 370 - * 371 - * Do that if the resume fails too. 372 - */ 373 - put = dev->power.runtime_status == RPM_SUSPENDING && !retval; 374 - if (put) 375 - __update_runtime_status(dev, RPM_SUSPENDED); 376 - else 377 - put = get && retval; 378 - 379 - if (put) { 380 - spin_unlock_irq(&dev->power.lock); 381 - 382 - idx = device_links_read_lock(); 383 - 384 - fail: 385 - rpm_put_suppliers(dev); 386 - 387 - device_links_read_unlock(idx); 374 + device_links_read_unlock(idx); 375 + } 388 376 389 377 spin_lock_irq(&dev->power.lock); 390 378 }
-2
kernel/reboot.c
··· 244 244 void kernel_restart(char *cmd) 245 245 { 246 246 kernel_restart_prepare(cmd); 247 - if (pm_power_off_prepare) 248 - pm_power_off_prepare(); 249 247 migrate_to_reboot_cpu(); 250 248 syscore_shutdown(); 251 249 if (!cmd)