cpu-sched: use cpu on/off events to create cpusets 64/236964/6
authorMaciej Słodczyk <m.slodczyk2@partner.samsung.com>
Tue, 23 Jun 2020 19:24:48 +0000 (21:24 +0200)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Tue, 21 Jul 2020 11:56:27 +0000 (11:56 +0000)
Change-Id: I158f2a8e26ae3334065717c06b16b9e161e3281e
Signed-off-by: Maciej Słodczyk <m.slodczyk2@partner.samsung.com>
src/cpu/cpu-sched.c

index 4a42c7e..a40d92b 100644 (file)
@@ -5,6 +5,8 @@
 #include "config-parser.h"
 #include "trace.h"
 #include "cgroup.h"
+#include "notifier.h"
+#include "cpu-hotplug.h"
 
 #define CPU_SCHED_CONF_FILE     RD_CONFIG_FILE(cpu-sched)
 #define CPU_SCHED_FG_NAME      "foreground"
@@ -220,6 +222,135 @@ static int cpu_sched_parse_config(struct cpu_sched *data)
        return RESOURCED_ERROR_NONE;
 }
 
+static int cpu_sched_write_coreset(struct coreset *set)
+{
+       GSList *i;
+       struct core *c;
+       char path[128], coreset[128];
+       int r;
+
+       assert(set);
+
+
+       r = snprintf(path, sizeof path, "%s/%s", CPUSET_CGROUP, set->name);
+       if (r < 0) {
+               _E("cpu-sched: failed to setup path for cpuset (%s)", set->name);
+               return r;
+       }
+
+       r = 0;
+       gslist_for_each_item(i, set->cores) {
+               c = (struct core *)i->data;
+               if (NULL == c || false == c->on)
+                       continue;
+
+               r += snprintf(coreset + r, sizeof coreset - r, "%d,", c->id);
+       }
+
+       if (r > 0)
+               coreset[--r] = '\0';
+
+       return cgroup_write_node_str(path, "cpuset.cpus", coreset);
+}
+
+static int cpu_sched_cpu_on_for_coreset(struct coreset *set, int core_id)
+{
+       GSList *i;
+       struct core *c;
+       bool refresh = false;
+
+       assert(set);
+       assert(core_id >= 0);
+
+       if (NULL == set->cores)
+               return 0;
+
+       gslist_for_each_item(i, set->cores) {
+               c = (struct core *)i->data;
+               if (NULL == c || c->id != core_id)
+                       continue;
+
+               _D("cpu-sched: core %d on for coreset %s", core_id, set->name);
+               c->on = true;
+               refresh = true;
+               break;
+       }
+
+       if (false == refresh)
+               return 0;
+
+       return cpu_sched_write_coreset(set);
+}
+
+static int cpu_sched_cpu_off_for_coreset(struct coreset *set, int core_id)
+{
+       GSList *i;
+       struct core *c;
+       bool refresh = false;
+
+       assert(set);
+       assert(core_id >= 0);
+
+       if (NULL == set->cores)
+               return 0;
+
+       gslist_for_each_item(i, set->cores) {
+               c = (struct core *)i->data;
+               if (NULL == c || c->id != core_id)
+                       continue;
+
+               _D("cpu-sched: core %d off for coreset %s", core_id, set->name);
+               c->on = false;
+               refresh = true;
+               break;
+       }
+
+       if (false == refresh)
+               return 0;
+
+       return cpu_sched_write_coreset(set);
+}
+
+static int cpu_sched_cpu_on(void *data)
+{
+       int id;
+
+       assert(data);
+
+       id = *(int*)(data);
+
+       _D("cpu-sched: core %d plugged in", id);
+       cpu_sched_cpu_on_for_coreset(&cs.fg, id);
+
+       return RESOURCED_ERROR_NONE;
+}
+
+static int cpu_sched_cpu_off(void *data)
+{
+       int id;
+
+       assert(data);
+
+       id = *(int*)(data);
+
+       _D("cpu-sched: core %d plugged out", id);
+       cpu_sched_cpu_off_for_coreset(&cs.fg, id);
+
+       return RESOURCED_ERROR_NONE;
+}
+
+static void register_notifiers()
+{
+       register_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
+       register_notifier(RESOURCED_NOTIFIER_CPU_OFF, cpu_sched_cpu_off);
+}
+
+static void unregister_notifiers()
+{
+       unregister_notifier(RESOURCED_NOTIFIER_CPU_ON, cpu_sched_cpu_on);
+       unregister_notifier(RESOURCED_NOTIFIER_CPU_OFF, cpu_sched_cpu_off);
+}
+
 static int cpu_sched_init(void *data)
 {
        int r;
@@ -234,10 +365,18 @@ static int cpu_sched_init(void *data)
        if (r < 0)
                goto init_failed;
 
+       register_notifiers();
+       if (cpu_hotplug_init() != 0) {
+               _E("cpu_sched: could not setup cpu hotplugging");
+               return RESOURCED_ERROR_FAIL;
+       }
+
        cs.is_initalized = true;
        return RESOURCED_ERROR_NONE;
 
 init_failed:
+       unregister_notifiers();
+       cpu_hotplug_finalize();
        cpu_sched_free_cpuset(&cs.fg);
        cs.is_initalized = false;
        return RESOURCED_ERROR_FAIL;
@@ -246,6 +385,8 @@ init_failed:
 static int cpu_sched_finalize(void *data)
 {
        _D("cpu-sched: deinit module");
+       unregister_notifiers();
+       cpu_hotplug_finalize();
        cpu_sched_free_cpuset(&cs.fg);
        cs.is_initalized = false;
        return RESOURCED_ERROR_NONE;