cpufreq: governor: Get rid of governor events
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 2 Jun 2016 21:24:15 +0000 (23:24 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 2 Jun 2016 21:24:15 +0000 (23:24 +0200)
The design of the cpufreq governor API is not very straightforward,
as struct cpufreq_governor provides only one callback to be invoked
from different code paths for different purposes.  The purpose it is
invoked for is determined by its second "event" argument, causing it
to act as a "callback multiplexer" of sorts.

Unfortunately, that leads to extra complexity in governors, some of
which implement the ->governor() callback as a switch statement
that simply checks the event argument and invokes a separate function
to handle that specific event.

That extra complexity can be eliminated by replacing the all-purpose
->governor() callback with a family of callbacks to carry out specific
governor operations: initialization and exit, start and stop and policy
limits updates.  That also turns out to reduce the code size too, so
do it.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
arch/powerpc/platforms/cell/cpufreq_spudemand.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_performance.c
drivers/cpufreq/cpufreq_powersave.c
drivers/cpufreq/cpufreq_userspace.c
include/linux/cpufreq.h
kernel/sched/cpufreq_schedutil.c

index 82607d6..88301e5 100644 (file)
@@ -85,61 +85,57 @@ static void spu_gov_cancel_work(struct spu_gov_info_struct *info)
        cancel_delayed_work_sync(&info->work);
 }
 
-static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
+static int spu_gov_start(struct cpufreq_policy *policy)
 {
        unsigned int cpu = policy->cpu;
-       struct spu_gov_info_struct *info, *affected_info;
+       struct spu_gov_info_struct *info = &per_cpu(spu_gov_info, cpu);
+       struct spu_gov_info_struct *affected_info;
        int i;
-       int ret = 0;
 
-       info = &per_cpu(spu_gov_info, cpu);
-
-       switch (event) {
-       case CPUFREQ_GOV_START:
-               if (!cpu_online(cpu)) {
-                       printk(KERN_ERR "cpu %d is not online\n", cpu);
-                       ret = -EINVAL;
-                       break;
-               }
+       if (!cpu_online(cpu)) {
+               printk(KERN_ERR "cpu %d is not online\n", cpu);
+               return -EINVAL;
+       }
 
-               if (!policy->cur) {
-                       printk(KERN_ERR "no cpu specified in policy\n");
-                       ret = -EINVAL;
-                       break;
-               }
+       if (!policy->cur) {
+               printk(KERN_ERR "no cpu specified in policy\n");
+               return -EINVAL;
+       }
 
-               /* initialize spu_gov_info for all affected cpus */
-               for_each_cpu(i, policy->cpus) {
-                       affected_info = &per_cpu(spu_gov_info, i);
-                       affected_info->policy = policy;
-               }
+       /* initialize spu_gov_info for all affected cpus */
+       for_each_cpu(i, policy->cpus) {
+               affected_info = &per_cpu(spu_gov_info, i);
+               affected_info->policy = policy;
+       }
 
-               info->poll_int = POLL_TIME;
+       info->poll_int = POLL_TIME;
 
-               /* setup timer */
-               spu_gov_init_work(info);
+       /* setup timer */
+       spu_gov_init_work(info);
 
-               break;
+       return 0;
+}
 
-       case CPUFREQ_GOV_STOP:
-               /* cancel timer */
-               spu_gov_cancel_work(info);
+static void spu_gov_stop(struct cpufreq_policy *policy)
+{
+       unsigned int cpu = policy->cpu;
+       struct spu_gov_info_struct *info = &per_cpu(spu_gov_info, cpu);
+       int i;
 
-               /* clean spu_gov_info for all affected cpus */
-               for_each_cpu (i, policy->cpus) {
-                       info = &per_cpu(spu_gov_info, i);
-                       info->policy = NULL;
-               }
+       /* cancel timer */
+       spu_gov_cancel_work(info);
 
-               break;
+       /* clean spu_gov_info for all affected cpus */
+       for_each_cpu (i, policy->cpus) {
+               info = &per_cpu(spu_gov_info, i);
+               info->policy = NULL;
        }
-
-       return ret;
 }
 
 static struct cpufreq_governor spu_governor = {
        .name = "spudemand",
-       .governor = spu_gov_govern,
+       .start = spu_gov_start,
+       .stop = spu_gov_stop,
        .owner = THIS_MODULE,
 };
 
index 268566e..d98ff68 100644 (file)
@@ -2023,10 +2023,12 @@ static int cpufreq_init_governor(struct cpufreq_policy *policy)
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       ret = policy->governor->governor(policy, CPUFREQ_GOV_POLICY_INIT);
-       if (ret) {
-               module_put(policy->governor->owner);
-               return ret;
+       if (policy->governor->init) {
+               ret = policy->governor->init(policy);
+               if (ret) {
+                       module_put(policy->governor->owner);
+                       return ret;
+               }
        }
 
        policy->governor->initialized++;
@@ -2040,7 +2042,8 @@ static void cpufreq_exit_governor(struct cpufreq_policy *policy)
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_POLICY_EXIT);
+       if (policy->governor->exit)
+               policy->governor->exit(policy);
 
        policy->governor->initialized--;
        module_put(policy->governor->owner);
@@ -2061,11 +2064,15 @@ static int cpufreq_start_governor(struct cpufreq_policy *policy)
        if (cpufreq_driver->get && !cpufreq_driver->setpolicy)
                cpufreq_update_current_freq(policy);
 
-       ret = policy->governor->governor(policy, CPUFREQ_GOV_START);
-       if (ret)
-               return ret;
+       if (policy->governor->start) {
+               ret = policy->governor->start(policy);
+               if (ret)
+                       return ret;
+       }
+
+       if (policy->governor->limits)
+               policy->governor->limits(policy);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_LIMITS);
        return 0;
 }
 
@@ -2076,7 +2083,8 @@ static void cpufreq_stop_governor(struct cpufreq_policy *policy)
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_STOP);
+       if (policy->governor->stop)
+               policy->governor->stop(policy);
 }
 
 static void cpufreq_governor_limits(struct cpufreq_policy *policy)
@@ -2086,7 +2094,8 @@ static void cpufreq_governor_limits(struct cpufreq_policy *policy)
 
        pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
 
-       policy->governor->governor(policy, CPUFREQ_GOV_LIMITS);
+       if (policy->governor->limits)
+               policy->governor->limits(policy);
 }
 
 int cpufreq_register_governor(struct cpufreq_governor *governor)
index 316df24..2568508 100644 (file)
@@ -313,12 +313,7 @@ static void cs_start(struct cpufreq_policy *policy)
 }
 
 static struct dbs_governor cs_dbs_gov = {
-       .gov = {
-               .name = "conservative",
-               .governor = cpufreq_governor_dbs,
-               .max_transition_latency = TRANSITION_LATENCY_LIMIT,
-               .owner = THIS_MODULE,
-       },
+       .gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"),
        .kobj_type = { .default_attrs = cs_attributes },
        .gov_dbs_timer = cs_dbs_timer,
        .alloc = cs_alloc,
index be498d5..ca9927c 100644 (file)
@@ -389,7 +389,7 @@ static void free_policy_dbs_info(struct policy_dbs_info *policy_dbs,
        gov->free(policy_dbs);
 }
 
-static int cpufreq_governor_init(struct cpufreq_policy *policy)
+int cpufreq_dbs_governor_init(struct cpufreq_policy *policy)
 {
        struct dbs_governor *gov = dbs_governor_of(policy);
        struct dbs_data *dbs_data;
@@ -474,8 +474,9 @@ out:
        mutex_unlock(&gov_dbs_data_mutex);
        return ret;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_init);
 
-static int cpufreq_governor_exit(struct cpufreq_policy *policy)
+void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy)
 {
        struct dbs_governor *gov = dbs_governor_of(policy);
        struct policy_dbs_info *policy_dbs = policy->governor_data;
@@ -500,10 +501,10 @@ static int cpufreq_governor_exit(struct cpufreq_policy *policy)
        free_policy_dbs_info(policy_dbs, gov);
 
        mutex_unlock(&gov_dbs_data_mutex);
-       return 0;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_exit);
 
-static int cpufreq_governor_start(struct cpufreq_policy *policy)
+int cpufreq_dbs_governor_start(struct cpufreq_policy *policy)
 {
        struct dbs_governor *gov = dbs_governor_of(policy);
        struct policy_dbs_info *policy_dbs = policy->governor_data;
@@ -539,14 +540,15 @@ static int cpufreq_governor_start(struct cpufreq_policy *policy)
        gov_set_update_util(policy_dbs, sampling_rate);
        return 0;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_start);
 
-static int cpufreq_governor_stop(struct cpufreq_policy *policy)
+void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy)
 {
        gov_cancel_work(policy);
-       return 0;
 }
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_stop);
 
-static int cpufreq_governor_limits(struct cpufreq_policy *policy)
+void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)
 {
        struct policy_dbs_info *policy_dbs = policy->governor_data;
 
@@ -560,26 +562,5 @@ static int cpufreq_governor_limits(struct cpufreq_policy *policy)
        gov_update_sample_delay(policy_dbs, 0);
 
        mutex_unlock(&policy_dbs->timer_mutex);
-
-       return 0;
-}
-
-int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event)
-{
-       if (event == CPUFREQ_GOV_POLICY_INIT) {
-               return cpufreq_governor_init(policy);
-       } else if (policy->governor_data) {
-               switch (event) {
-               case CPUFREQ_GOV_POLICY_EXIT:
-                       return cpufreq_governor_exit(policy);
-               case CPUFREQ_GOV_START:
-                       return cpufreq_governor_start(policy);
-               case CPUFREQ_GOV_STOP:
-                       return cpufreq_governor_stop(policy);
-               case CPUFREQ_GOV_LIMITS:
-                       return cpufreq_governor_limits(policy);
-               }
-       }
-       return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(cpufreq_governor_dbs);
+EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_limits);
index 34eb214..36f0d19 100644 (file)
@@ -148,6 +148,25 @@ static inline struct dbs_governor *dbs_governor_of(struct cpufreq_policy *policy
        return container_of(policy->governor, struct dbs_governor, gov);
 }
 
+/* Governor callback routines */
+int cpufreq_dbs_governor_init(struct cpufreq_policy *policy);
+void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy);
+int cpufreq_dbs_governor_start(struct cpufreq_policy *policy);
+void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy);
+void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy);
+
+#define CPUFREQ_DBS_GOVERNOR_INITIALIZER(_name_)                       \
+       {                                                               \
+               .name = _name_,                                         \
+               .max_transition_latency = TRANSITION_LATENCY_LIMIT,     \
+               .owner = THIS_MODULE,                                   \
+               .init = cpufreq_dbs_governor_init,                      \
+               .exit = cpufreq_dbs_governor_exit,                      \
+               .start = cpufreq_dbs_governor_start,                    \
+               .stop = cpufreq_dbs_governor_stop,                      \
+               .limits = cpufreq_dbs_governor_limits,                  \
+       }
+
 /* Governor specific operations */
 struct od_ops {
        unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,
@@ -155,7 +174,6 @@ struct od_ops {
 };
 
 unsigned int dbs_update(struct cpufreq_policy *policy);
-int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event);
 void od_register_powersave_bias_handler(unsigned int (*f)
                (struct cpufreq_policy *, unsigned int, unsigned int),
                unsigned int powersave_bias);
index 3001634..09d6c0c 100644 (file)
@@ -420,12 +420,7 @@ static struct od_ops od_ops = {
 };
 
 static struct dbs_governor od_dbs_gov = {
-       .gov = {
-               .name = "ondemand",
-               .governor = cpufreq_governor_dbs,
-               .max_transition_latency = TRANSITION_LATENCY_LIMIT,
-               .owner = THIS_MODULE,
-       },
+       .gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("ondemand"),
        .kobj_type = { .default_attrs = od_attributes },
        .gov_dbs_timer = od_dbs_timer,
        .alloc = od_alloc,
index dd4dca3..dafb679 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 
-static int cpufreq_governor_performance(struct cpufreq_policy *policy,
-                                       unsigned int event)
+static void cpufreq_gov_performance_limits(struct cpufreq_policy *policy)
 {
-       switch (event) {
-       case CPUFREQ_GOV_LIMITS:
-               pr_debug("setting to %u kHz\n", policy->max);
-               __cpufreq_driver_target(policy, policy->max,
-                                               CPUFREQ_RELATION_H);
-               break;
-       default:
-               break;
-       }
-       return 0;
+       pr_debug("setting to %u kHz\n", policy->max);
+       __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
 }
 
 static struct cpufreq_governor cpufreq_gov_performance = {
        .name           = "performance",
-       .governor       = cpufreq_governor_performance,
        .owner          = THIS_MODULE,
+       .limits         = cpufreq_gov_performance_limits,
 };
 
 static int __init cpufreq_gov_performance_init(void)
index 691e573..78a6510 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 
-static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
-                                       unsigned int event)
+static void cpufreq_gov_powersave_limits(struct cpufreq_policy *policy)
 {
-       switch (event) {
-       case CPUFREQ_GOV_LIMITS:
-               pr_debug("setting to %u kHz\n", policy->min);
-               __cpufreq_driver_target(policy, policy->min,
-                                               CPUFREQ_RELATION_L);
-               break;
-       default:
-               break;
-       }
-       return 0;
+       pr_debug("setting to %u kHz\n", policy->min);
+       __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
 }
 
 static struct cpufreq_governor cpufreq_gov_powersave = {
        .name           = "powersave",
-       .governor       = cpufreq_governor_powersave,
+       .limits         = cpufreq_gov_powersave_limits,
        .owner          = THIS_MODULE,
 };
 
index 9f3dec9..bd897e3 100644 (file)
@@ -65,66 +65,66 @@ static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy)
        return 0;
 }
 
-static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
-                                  unsigned int event)
+static void cpufreq_userspace_policy_exit(struct cpufreq_policy *policy)
+{
+       mutex_lock(&userspace_mutex);
+       kfree(policy->governor_data);
+       policy->governor_data = NULL;
+       mutex_unlock(&userspace_mutex);
+}
+
+static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy)
 {
        unsigned int *setspeed = policy->governor_data;
-       unsigned int cpu = policy->cpu;
-       int rc = 0;
 
-       if (event == CPUFREQ_GOV_POLICY_INIT)
-               return cpufreq_userspace_policy_init(policy);
+       BUG_ON(!policy->cur);
+       pr_debug("started managing cpu %u\n", policy->cpu);
 
-       if (!setspeed)
-               return -EINVAL;
-
-       switch (event) {
-       case CPUFREQ_GOV_POLICY_EXIT:
-               mutex_lock(&userspace_mutex);
-               policy->governor_data = NULL;
-               kfree(setspeed);
-               mutex_unlock(&userspace_mutex);
-               break;
-       case CPUFREQ_GOV_START:
-               BUG_ON(!policy->cur);
-               pr_debug("started managing cpu %u\n", cpu);
-
-               mutex_lock(&userspace_mutex);
-               per_cpu(cpu_is_managed, cpu) = 1;
-               *setspeed = policy->cur;
-               mutex_unlock(&userspace_mutex);
-               break;
-       case CPUFREQ_GOV_STOP:
-               pr_debug("managing cpu %u stopped\n", cpu);
-
-               mutex_lock(&userspace_mutex);
-               per_cpu(cpu_is_managed, cpu) = 0;
-               *setspeed = 0;
-               mutex_unlock(&userspace_mutex);
-               break;
-       case CPUFREQ_GOV_LIMITS:
-               mutex_lock(&userspace_mutex);
-               pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
-                       cpu, policy->min, policy->max, policy->cur, *setspeed);
-
-               if (policy->max < *setspeed)
-                       __cpufreq_driver_target(policy, policy->max,
-                                               CPUFREQ_RELATION_H);
-               else if (policy->min > *setspeed)
-                       __cpufreq_driver_target(policy, policy->min,
-                                               CPUFREQ_RELATION_L);
-               else
-                       __cpufreq_driver_target(policy, *setspeed,
-                                               CPUFREQ_RELATION_L);
-               mutex_unlock(&userspace_mutex);
-               break;
-       }
-       return rc;
+       mutex_lock(&userspace_mutex);
+       per_cpu(cpu_is_managed, policy->cpu) = 1;
+       *setspeed = policy->cur;
+       mutex_unlock(&userspace_mutex);
+       return 0;
+}
+
+static void cpufreq_userspace_policy_stop(struct cpufreq_policy *policy)
+{
+       unsigned int *setspeed = policy->governor_data;
+
+       pr_debug("managing cpu %u stopped\n", policy->cpu);
+
+       mutex_lock(&userspace_mutex);
+       per_cpu(cpu_is_managed, policy->cpu) = 0;
+       *setspeed = 0;
+       mutex_unlock(&userspace_mutex);
+}
+
+static void cpufreq_userspace_policy_limits(struct cpufreq_policy *policy)
+{
+       unsigned int *setspeed = policy->governor_data;
+
+       mutex_lock(&userspace_mutex);
+
+       pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n",
+                policy->cpu, policy->min, policy->max, policy->cur, *setspeed);
+
+       if (policy->max < *setspeed)
+               __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
+       else if (policy->min > *setspeed)
+               __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
+       else
+               __cpufreq_driver_target(policy, *setspeed, CPUFREQ_RELATION_L);
+
+       mutex_unlock(&userspace_mutex);
 }
 
 static struct cpufreq_governor cpufreq_gov_userspace = {
        .name           = "userspace",
-       .governor       = cpufreq_governor_userspace,
+       .init           = cpufreq_userspace_policy_init,
+       .exit           = cpufreq_userspace_policy_exit,
+       .start          = cpufreq_userspace_policy_start,
+       .stop           = cpufreq_userspace_policy_stop,
+       .limits         = cpufreq_userspace_policy_limits,
        .store_setspeed = cpufreq_set,
        .show_setspeed  = show_speed,
        .owner          = THIS_MODULE,
index 4e81e08..5bcda3e 100644 (file)
@@ -455,18 +455,14 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
 #define MIN_LATENCY_MULTIPLIER         (20)
 #define TRANSITION_LATENCY_LIMIT       (10 * 1000 * 1000)
 
-/* Governor Events */
-#define CPUFREQ_GOV_START      1
-#define CPUFREQ_GOV_STOP       2
-#define CPUFREQ_GOV_LIMITS     3
-#define CPUFREQ_GOV_POLICY_INIT        4
-#define CPUFREQ_GOV_POLICY_EXIT        5
-
 struct cpufreq_governor {
        char    name[CPUFREQ_NAME_LEN];
        int     initialized;
-       int     (*governor)     (struct cpufreq_policy *policy,
-                                unsigned int event);
+       int     (*init)(struct cpufreq_policy *policy);
+       void    (*exit)(struct cpufreq_policy *policy);
+       int     (*start)(struct cpufreq_policy *policy);
+       void    (*stop)(struct cpufreq_policy *policy);
+       void    (*limits)(struct cpufreq_policy *policy);
        ssize_t (*show_setspeed)        (struct cpufreq_policy *policy,
                                         char *buf);
        int     (*store_setspeed)       (struct cpufreq_policy *policy,
index 14c4aa2..fdcee3c 100644 (file)
@@ -394,7 +394,7 @@ static int sugov_init(struct cpufreq_policy *policy)
        return ret;
 }
 
-static int sugov_exit(struct cpufreq_policy *policy)
+static void sugov_exit(struct cpufreq_policy *policy)
 {
        struct sugov_policy *sg_policy = policy->governor_data;
        struct sugov_tunables *tunables = sg_policy->tunables;
@@ -412,7 +412,6 @@ static int sugov_exit(struct cpufreq_policy *policy)
        mutex_unlock(&global_tunables_lock);
 
        sugov_policy_free(sg_policy);
-       return 0;
 }
 
 static int sugov_start(struct cpufreq_policy *policy)
@@ -444,7 +443,7 @@ static int sugov_start(struct cpufreq_policy *policy)
        return 0;
 }
 
-static int sugov_stop(struct cpufreq_policy *policy)
+static void sugov_stop(struct cpufreq_policy *policy)
 {
        struct sugov_policy *sg_policy = policy->governor_data;
        unsigned int cpu;
@@ -456,10 +455,9 @@ static int sugov_stop(struct cpufreq_policy *policy)
 
        irq_work_sync(&sg_policy->irq_work);
        cancel_work_sync(&sg_policy->work);
-       return 0;
 }
 
-static int sugov_limits(struct cpufreq_policy *policy)
+static void sugov_limits(struct cpufreq_policy *policy)
 {
        struct sugov_policy *sg_policy = policy->governor_data;
 
@@ -477,32 +475,16 @@ static int sugov_limits(struct cpufreq_policy *policy)
        }
 
        sg_policy->need_freq_update = true;
-       return 0;
-}
-
-int sugov_governor(struct cpufreq_policy *policy, unsigned int event)
-{
-       if (event == CPUFREQ_GOV_POLICY_INIT) {
-               return sugov_init(policy);
-       } else if (policy->governor_data) {
-               switch (event) {
-               case CPUFREQ_GOV_POLICY_EXIT:
-                       return sugov_exit(policy);
-               case CPUFREQ_GOV_START:
-                       return sugov_start(policy);
-               case CPUFREQ_GOV_STOP:
-                       return sugov_stop(policy);
-               case CPUFREQ_GOV_LIMITS:
-                       return sugov_limits(policy);
-               }
-       }
-       return -EINVAL;
 }
 
 static struct cpufreq_governor schedutil_gov = {
        .name = "schedutil",
-       .governor = sugov_governor,
        .owner = THIS_MODULE,
+       .init = sugov_init,
+       .exit = sugov_exit,
+       .start = sugov_start,
+       .stop = sugov_stop,
+       .limits = sugov_limits,
 };
 
 static int __init sugov_module_init(void)