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.

cpuidle: Extract and export no-lock variants of cpuidle_unregister_device()

The cpuidle_unregister_device() function always acquires the internal
cpuidle_lock (or pause/resume idle) during their execution.

However, in some power notification scenarios (e.g., when old idle
states may become unavailable), it is necessary to efficiently disable
cpuidle first, then remove and re-create all cpuidle devices for all
CPUs. To avoid frequent lock overhead and ensure atomicity across the
entire batch operation, the caller needs to hold the cpuidle_lock once
outside the loop.

To address this, extract the core logic into the new function
cpuidle_unregister_device_no_lock() and export it.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
[ rjw: Added missing "inline", subject and changelog tweaks ]
Link: https://patch.msgid.link/20260407081141.2493581-2-lihuisong@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Huisong Li and committed by
Rafael J. Wysocki
a4c6c18e 47e6a863

+20 -10
+18 -10
drivers/cpuidle/cpuidle.c
··· 714 714 715 715 EXPORT_SYMBOL_GPL(cpuidle_register_device); 716 716 717 + void cpuidle_unregister_device_no_lock(struct cpuidle_device *dev) 718 + { 719 + if (!dev || dev->registered == 0) 720 + return; 721 + 722 + lockdep_assert_held(&cpuidle_lock); 723 + 724 + cpuidle_disable_device(dev); 725 + 726 + cpuidle_remove_sysfs(dev); 727 + 728 + __cpuidle_unregister_device(dev); 729 + 730 + cpuidle_coupled_unregister_device(dev); 731 + } 732 + EXPORT_SYMBOL_GPL(cpuidle_unregister_device_no_lock); 733 + 717 734 /** 718 735 * cpuidle_unregister_device - unregisters a CPU's idle PM feature 719 736 * @dev: the cpu ··· 741 724 return; 742 725 743 726 cpuidle_pause_and_lock(); 744 - 745 - cpuidle_disable_device(dev); 746 - 747 - cpuidle_remove_sysfs(dev); 748 - 749 - __cpuidle_unregister_device(dev); 750 - 751 - cpuidle_coupled_unregister_device(dev); 752 - 727 + cpuidle_unregister_device_no_lock(dev); 753 728 cpuidle_resume_and_unlock(); 754 729 } 755 - 756 730 EXPORT_SYMBOL_GPL(cpuidle_unregister_device); 757 731 758 732 /**
+2
include/linux/cpuidle.h
··· 188 188 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 189 189 extern int cpuidle_register_device(struct cpuidle_device *dev); 190 190 extern void cpuidle_unregister_device(struct cpuidle_device *dev); 191 + extern void cpuidle_unregister_device_no_lock(struct cpuidle_device *dev); 191 192 extern int cpuidle_register(struct cpuidle_driver *drv, 192 193 const struct cpumask *const coupled_cpus); 193 194 extern void cpuidle_unregister(struct cpuidle_driver *drv); ··· 227 226 static inline int cpuidle_register_device(struct cpuidle_device *dev) 228 227 {return -ENODEV; } 229 228 static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } 229 + static inline void cpuidle_unregister_device_no_lock(struct cpuidle_device *dev) {} 230 230 static inline int cpuidle_register(struct cpuidle_driver *drv, 231 231 const struct cpumask *const coupled_cpus) 232 232 {return -ENODEV; }