Skip to content

Commit a4c6c18

Browse files
LiHuiSong1rafaeljw
authored andcommitted
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>
1 parent 47e6a86 commit a4c6c18

2 files changed

Lines changed: 17 additions & 7 deletions

File tree

drivers/cpuidle/cpuidle.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -714,16 +714,12 @@ int cpuidle_register_device(struct cpuidle_device *dev)
714714

715715
EXPORT_SYMBOL_GPL(cpuidle_register_device);
716716

717-
/**
718-
* cpuidle_unregister_device - unregisters a CPU's idle PM feature
719-
* @dev: the cpu
720-
*/
721-
void cpuidle_unregister_device(struct cpuidle_device *dev)
717+
void cpuidle_unregister_device_no_lock(struct cpuidle_device *dev)
722718
{
723719
if (!dev || dev->registered == 0)
724720
return;
725721

726-
cpuidle_pause_and_lock();
722+
lockdep_assert_held(&cpuidle_lock);
727723

728724
cpuidle_disable_device(dev);
729725

@@ -732,10 +728,22 @@ void cpuidle_unregister_device(struct cpuidle_device *dev)
732728
__cpuidle_unregister_device(dev);
733729

734730
cpuidle_coupled_unregister_device(dev);
731+
}
732+
EXPORT_SYMBOL_GPL(cpuidle_unregister_device_no_lock);
733+
734+
/**
735+
* cpuidle_unregister_device - unregisters a CPU's idle PM feature
736+
* @dev: the cpu
737+
*/
738+
void cpuidle_unregister_device(struct cpuidle_device *dev)
739+
{
740+
if (!dev || dev->registered == 0)
741+
return;
735742

743+
cpuidle_pause_and_lock();
744+
cpuidle_unregister_device_no_lock(dev);
736745
cpuidle_resume_and_unlock();
737746
}
738-
739747
EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
740748

741749
/**

include/linux/cpuidle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ extern void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
188188
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
189189
extern int cpuidle_register_device(struct cpuidle_device *dev);
190190
extern void cpuidle_unregister_device(struct cpuidle_device *dev);
191+
extern void cpuidle_unregister_device_no_lock(struct cpuidle_device *dev);
191192
extern int cpuidle_register(struct cpuidle_driver *drv,
192193
const struct cpumask *const coupled_cpus);
193194
extern void cpuidle_unregister(struct cpuidle_driver *drv);
@@ -226,6 +227,7 @@ static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
226227
static inline int cpuidle_register_device(struct cpuidle_device *dev)
227228
{return -ENODEV; }
228229
static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
230+
static inline void cpuidle_unregister_device_no_lock(struct cpuidle_device *dev) {}
229231
static inline int cpuidle_register(struct cpuidle_driver *drv,
230232
const struct cpumask *const coupled_cpus)
231233
{return -ENODEV; }

0 commit comments

Comments
 (0)