]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cpuidle: Fail cpuidle device registration if there is one already
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 19 Sep 2025 11:22:20 +0000 (13:22 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sat, 20 Sep 2025 11:08:54 +0000 (13:08 +0200)
Refuse to register a cpuidle device if the given CPU has a cpuidle
device already and print a message regarding it.

Without this, an attempt to register a new cpuidle device without
unregistering the existing one leads to the removal of the existing
cpuidle device without removing its sysfs interface.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpuidle/cpuidle.c

index 0835da449db8b4209f0686aef4818dfa3d1a308a..56132e843c99192d4e48ea3d1378326aebcf95cb 100644 (file)
@@ -635,8 +635,14 @@ static void __cpuidle_device_init(struct cpuidle_device *dev)
 static int __cpuidle_register_device(struct cpuidle_device *dev)
 {
        struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+       unsigned int cpu = dev->cpu;
        int i, ret;
 
+       if (per_cpu(cpuidle_devices, cpu)) {
+               pr_info("CPU%d: cpuidle device already registered\n", cpu);
+               return -EEXIST;
+       }
+
        if (!try_module_get(drv->owner))
                return -EINVAL;
 
@@ -648,7 +654,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
                        dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_USER;
        }
 
-       per_cpu(cpuidle_devices, dev->cpu) = dev;
+       per_cpu(cpuidle_devices, cpu) = dev;
        list_add(&dev->device_list, &cpuidle_detected_devices);
 
        ret = cpuidle_coupled_register_device(dev);