[PATCH 3/5] cpuidle: governor: Make possible to unregister a governor
From: Daniel Lezcano
Date: Thu Oct 15 2020 - 10:44:58 EST
This patch allows to unregister a governor. If the unregistered
governor is the current one, it will be replaced by the governor with
the highest rating. If it is the last governor, the cpuidle framework
will be switched off.
Signed-off-by: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx>
---
drivers/cpuidle/governor.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/cpuidle.h | 1 +
2 files changed, 38 insertions(+)
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index d46ab8ec2dd7..6ec27ef096f5 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -84,6 +84,43 @@ int cpuidle_switch_governor(struct cpuidle_governor *gov)
return 0;
}
+/**
+ * cpuidle_unregister_governor - unregister a governor
+ * @gov: a pointer to a cpuidle governor structure
+ *
+ * Unregister the governor specified in parameter. If it is the
+ * current one, replace by another one in the list with the highest
+ * rating. If it is the last one, then switch off cpuidle.
+ */
+void cpuidle_unregister_governor(struct cpuidle_governor *gov)
+{
+ int rating = 0;
+ struct cpuidle_governor *new_gov = NULL;
+
+ mutex_lock(&cpuidle_lock);
+
+ list_del(&gov->governor_list);
+
+ /*
+ * The governor is currently in use, switch to the one with
+ * the best rating.
+ */
+ if (cpuidle_curr_governor == gov) {
+
+ list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+ if (gov->rating > rating)
+ new_gov = gov;
+ }
+
+ if (new_gov)
+ cpuidle_switch_governor(new_gov);
+ else
+ cpuidle_switch_off();
+ }
+
+ mutex_unlock(&cpuidle_lock);
+}
+
/**
* cpuidle_register_governor - registers a governor
* @gov: the governor
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 74fdcc6106b1..457e0786b4f9 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -271,6 +271,7 @@ struct cpuidle_governor {
};
extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
extern s64 cpuidle_governor_latency_req(unsigned int cpu);
#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, \
--
2.17.1