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.

Revert "ACPI: processor: idle: Optimize ACPI idle driver registration"

Revert commit 7a8c994cbb2d ("ACPI: processor: idle: Optimize ACPI idle
driver registration") because it is reported to introduce a cpuidle
regression leading to a kernel crash on a platform using the ACPI idle
driver.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reported-by: Borislav Petkov <bp@alien8.de>
Tested-by: Borislav Petkov (AMD) <bp@alien8.de>
Closes: https://lore.kernel.org/lkml/20251124200019.GIaSS5U9HhsWBotrQZ@fat_crate.local/

+23 -47
-3
drivers/acpi/processor_driver.c
··· 263 263 if (result < 0) 264 264 return result; 265 265 266 - acpi_processor_register_idle_driver(); 267 - 268 266 result = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, 269 267 "acpi/cpu-drv:online", 270 268 acpi_soft_cpu_online, NULL); ··· 301 303 302 304 cpuhp_remove_state_nocalls(hp_online); 303 305 cpuhp_remove_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD); 304 - acpi_processor_unregister_idle_driver(); 305 306 driver_unregister(&acpi_processor_driver); 306 307 } 307 308
+23 -42
drivers/acpi/processor_idle.c
··· 1357 1357 return 0; 1358 1358 } 1359 1359 1360 - void acpi_processor_register_idle_driver(void) 1361 - { 1362 - struct acpi_processor *pr; 1363 - int ret = -ENODEV; 1364 - int cpu; 1365 - 1366 - /* 1367 - * Acpi idle driver is used by all possible CPUs. 1368 - * Install the idle handler by the processor power info of one in them. 1369 - * Note that we use previously set idle handler will be used on 1370 - * platforms that only support C1. 1371 - */ 1372 - for_each_cpu(cpu, (struct cpumask *)cpu_possible_mask) { 1373 - pr = per_cpu(processors, cpu); 1374 - if (!pr) 1375 - continue; 1376 - 1377 - ret = acpi_processor_get_power_info(pr); 1378 - if (!ret) { 1379 - pr->flags.power_setup_done = 1; 1380 - acpi_processor_setup_cpuidle_states(pr); 1381 - break; 1382 - } 1383 - } 1384 - 1385 - if (ret) { 1386 - pr_debug("No ACPI power information from any CPUs.\n"); 1387 - return; 1388 - } 1389 - 1390 - ret = cpuidle_register_driver(&acpi_idle_driver); 1391 - if (ret) { 1392 - pr_debug("register %s failed.\n", acpi_idle_driver.name); 1393 - return; 1394 - } 1395 - pr_debug("%s registered with cpuidle.\n", acpi_idle_driver.name); 1396 - } 1397 - 1398 - void acpi_processor_unregister_idle_driver(void) 1399 - { 1400 - cpuidle_unregister_driver(&acpi_idle_driver); 1401 - } 1360 + static int acpi_processor_registered; 1402 1361 1403 1362 int acpi_processor_power_init(struct acpi_processor *pr) 1404 1363 { ··· 1372 1413 if (!acpi_processor_get_power_info(pr)) 1373 1414 pr->flags.power_setup_done = 1; 1374 1415 1416 + /* 1417 + * Install the idle handler if processor power management is supported. 1418 + * Note that we use previously set idle handler will be used on 1419 + * platforms that only support C1. 1420 + */ 1375 1421 if (pr->flags.power) { 1422 + /* Register acpi_idle_driver if not already registered */ 1423 + if (!acpi_processor_registered) { 1424 + acpi_processor_setup_cpuidle_states(pr); 1425 + retval = cpuidle_register_driver(&acpi_idle_driver); 1426 + if (retval) 1427 + return retval; 1428 + pr_debug("%s registered with cpuidle\n", 1429 + acpi_idle_driver.name); 1430 + } 1431 + 1376 1432 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1377 1433 if (!dev) 1378 1434 return -ENOMEM; ··· 1400 1426 */ 1401 1427 retval = cpuidle_register_device(dev); 1402 1428 if (retval) { 1429 + if (acpi_processor_registered == 0) 1430 + cpuidle_unregister_driver(&acpi_idle_driver); 1403 1431 1404 1432 per_cpu(acpi_cpuidle_device, pr->id) = NULL; 1405 1433 kfree(dev); 1406 1434 return retval; 1407 1435 } 1436 + acpi_processor_registered++; 1408 1437 } 1409 1438 return 0; 1410 1439 } ··· 1421 1444 1422 1445 if (pr->flags.power) { 1423 1446 cpuidle_unregister_device(dev); 1447 + acpi_processor_registered--; 1448 + if (acpi_processor_registered == 0) 1449 + cpuidle_unregister_driver(&acpi_idle_driver); 1450 + 1424 1451 kfree(dev); 1425 1452 } 1426 1453
-2
include/acpi/processor.h
··· 423 423 int acpi_processor_power_exit(struct acpi_processor *pr); 424 424 int acpi_processor_power_state_has_changed(struct acpi_processor *pr); 425 425 int acpi_processor_hotplug(struct acpi_processor *pr); 426 - void acpi_processor_register_idle_driver(void); 427 - void acpi_processor_unregister_idle_driver(void); 428 426 #else 429 427 static inline int acpi_processor_power_init(struct acpi_processor *pr) 430 428 {