[haiku-commits] BRANCH pdziepak-github.scheduler [7ce234b] src/add-ons/kernel/power/cpuidle/intel_cstates src/system/kernel src/system/kernel/scheduler src/add-ons/kernel/power/cpufreq/intel_pstates headers/os/drivers

  • From: pdziepak-github.scheduler <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 18 Dec 2013 01:15:30 +0100 (CET)

added 3 changesets to branch 'refs/remotes/pdziepak-github/scheduler'
old head: b3723fdada15080f9d8cad90d57c7689bb029bed
new head: 7ce234bf2444831f6340230e9e42900ce25c0173
overview: https://github.com/pdziepak/Haiku/compare/b3723fd...7ce234b

----------------------------------------------------------------------------

cb3f258: kernel: Make get_cpu_topology() return a pointer to const
  
  The client code is not supposed to change the topology info.
  It would be also nice if cpu_topology_node::children was an array of
  pointers to const but that would require several const_casts in the
  topology tree generation code so it's probably not worth it.

23bf5fe: kernel: Propagate scheduler modes to cpu{freq, idle} modules

7ce234b: scheduler: Fix unassigning threads from core being disabled

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

10 files changed, 94 insertions(+), 42 deletions(-)
headers/os/drivers/cpufreq.h                     |  8 +++-
headers/os/drivers/cpuidle.h                     |  8 +++-
headers/private/kernel/cpu.h                     |  8 +++-
headers/private/kernel/kscheduler.h              |  6 ---
.../cpufreq/intel_pstates/intel_pstates.cpp      | 25 +++++++++---
.../cpuidle/intel_cstates/intel_cstates.cpp      | 41 +++++++++++++++-----
src/system/kernel/cpu.cpp                        | 22 ++++++++---
src/system/kernel/int.cpp                        |  2 +-
src/system/kernel/scheduler/scheduler.cpp        | 12 ++++--
src/system/kernel/scheduler/scheduler_cpu.cpp    |  4 +-

############################################################################

Commit:      cb3f258a7eb27f8e2d1e64499091139bfc7ff431
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Dec 17 21:08:18 2013 UTC

kernel: Make get_cpu_topology() return a pointer to const

The client code is not supposed to change the topology info.
It would be also nice if cpu_topology_node::children was an array of
pointers to const but that would require several const_casts in the
topology tree generation code so it's probably not worth it.

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/cpu.h b/headers/private/kernel/cpu.h
index 7b4d51f..73614ab 100644
--- a/headers/private/kernel/cpu.h
+++ b/headers/private/kernel/cpu.h
@@ -105,7 +105,7 @@ cpu_ent *get_cpu_struct(void);
 extern inline cpu_ent *get_cpu_struct(void) { return 
&gCPU[smp_get_current_cpu()]; }
 
 status_t cpu_build_topology_tree(void);
-cpu_topology_node* get_cpu_topology(void);
+const cpu_topology_node* get_cpu_topology(void);
 
 status_t increase_cpu_performance(int delta, bool allowBoost);
 status_t decrease_cpu_performance(int delta);
diff --git a/src/system/kernel/cpu.cpp b/src/system/kernel/cpu.cpp
index 3a3df3a..2adc443 100644
--- a/src/system/kernel/cpu.cpp
+++ b/src/system/kernel/cpu.cpp
@@ -274,7 +274,7 @@ cpu_build_topology_tree(void)
 }
 
 
-cpu_topology_node*
+const cpu_topology_node*
 get_cpu_topology(void)
 {
        return &sCPUTopology;
diff --git a/src/system/kernel/int.cpp b/src/system/kernel/int.cpp
index 9fd6d2e..6601f3a 100644
--- a/src/system/kernel/int.cpp
+++ b/src/system/kernel/int.cpp
@@ -391,7 +391,7 @@ restore_interrupts(cpu_status status)
 static
 uint32 assign_cpu(void)
 {
-       cpu_topology_node* node;
+       const cpu_topology_node* node;
        do {
                int32 nextID = atomic_add(&sLastCPU, 1);
                node = get_cpu_topology();
diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index 18c8784..4801cde 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -751,7 +751,7 @@ scheduler_set_cpu_enabled(int32 cpuID, bool enabled)
 
 
 static void
-traverse_topology_tree(cpu_topology_node* node, int packageID, int coreID)
+traverse_topology_tree(const cpu_topology_node* node, int packageID, int 
coreID)
 {
        switch (node->level) {
                case CPU_TOPOLOGY_SMT:
@@ -805,7 +805,7 @@ build_topology_mappings(int32& cpuCount, int32& coreCount, 
int32& packageCount)
                }
        }
 
-       cpu_topology_node* root = get_cpu_topology();
+       const cpu_topology_node* root = get_cpu_topology();
        traverse_topology_tree(root, 0, 0);
 
        cpuToCoreDeleter.Detach();

############################################################################

Commit:      23bf5fe778cc85fe6bd5ed5a262be27414c3ff8d
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Dec 17 22:26:37 2013 UTC

kernel: Propagate scheduler modes to cpu{freq, idle} modules

----------------------------------------------------------------------------

diff --git a/headers/os/drivers/cpufreq.h b/headers/os/drivers/cpufreq.h
index ad36f99..3eb04b7 100644
--- a/headers/os/drivers/cpufreq.h
+++ b/headers/os/drivers/cpufreq.h
@@ -8,6 +8,8 @@
 
 #include <module.h>
 
+#include <scheduler.h>
+
 
 #define CPUFREQ_MODULES_PREFIX "power/cpufreq"
 
@@ -19,8 +21,10 @@ typedef struct cpufreq_module_info {
 
        float                   rank;
 
-       status_t                (*increase_performance)(int delta, bool 
allowBoost);
-       status_t                (*decrease_performance)(int delta);
+       void                    (*cpufreq_set_scheduler_mode)(enum 
scheduler_mode mode);
+
+       status_t                (*cpufreq_increase_performance)(int delta);
+       status_t                (*cpufreq_decrease_performance)(int delta);
 } cpufreq_module_info;
 
 
diff --git a/headers/os/drivers/cpuidle.h b/headers/os/drivers/cpuidle.h
index c22b3e6..2373978 100644
--- a/headers/os/drivers/cpuidle.h
+++ b/headers/os/drivers/cpuidle.h
@@ -8,6 +8,8 @@
 
 #include <module.h>
 
+#include <scheduler.h>
+
 
 #define CPUIDLE_MODULES_PREFIX "power/cpuidle"
 
@@ -17,8 +19,10 @@ typedef struct cpuidle_module_info {
 
        float                   rank;
 
-       void                    (*idle)(void);
-       void                    (*wait)(int32* variable, int32 test);
+       void                    (*cpuidle_set_scheduler_mode)(enum 
scheduler_mode mode);
+
+       void                    (*cpuidle_idle)(void);
+       void                    (*cpuidle_wait)(int32* variable, int32 test);
 } cpuidle_module_info;
 
 
diff --git a/headers/private/kernel/cpu.h b/headers/private/kernel/cpu.h
index 73614ab..17b056a 100644
--- a/headers/private/kernel/cpu.h
+++ b/headers/private/kernel/cpu.h
@@ -16,6 +16,8 @@
 #include <timer.h>
 #include <arch/cpu.h>
 
+#include <scheduler.h>
+
 
 struct kernel_args;
 
@@ -107,7 +109,9 @@ extern inline cpu_ent *get_cpu_struct(void) { return 
&gCPU[smp_get_current_cpu()
 status_t cpu_build_topology_tree(void);
 const cpu_topology_node* get_cpu_topology(void);
 
-status_t increase_cpu_performance(int delta, bool allowBoost);
+void cpu_set_scheduler_mode(enum scheduler_mode mode);
+
+status_t increase_cpu_performance(int delta);
 status_t decrease_cpu_performance(int delta);
 
 void cpu_idle(void);
diff --git a/headers/private/kernel/kscheduler.h 
b/headers/private/kernel/kscheduler.h
index 16316e8..bfc6e02 100644
--- a/headers/private/kernel/kscheduler.h
+++ b/headers/private/kernel/kscheduler.h
@@ -18,12 +18,6 @@ struct scheduling_analysis;
 struct SchedulerListener;
 
 
-enum scheduler_mode {
-       SCHEDULER_MODE_LOW_LATENCY,
-       SCHEDULER_MODE_POWER_SAVING,
-};
-
-
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/add-ons/kernel/power/cpufreq/intel_pstates/intel_pstates.cpp 
b/src/add-ons/kernel/power/cpufreq/intel_pstates/intel_pstates.cpp
index f7f7fe1..5b545fc 100644
--- a/src/add-ons/kernel/power/cpufreq/intel_pstates/intel_pstates.cpp
+++ b/src/add-ons/kernel/power/cpufreq/intel_pstates/intel_pstates.cpp
@@ -25,6 +25,8 @@ static uint16 sMinPState;
 static uint16 sMaxPState;
 static uint16 sBoostPState;
 
+static bool sAvoidBoost;
+
 
 struct CPUEntry {
                                CPUEntry();
@@ -32,7 +34,7 @@ struct CPUEntry {
        uint16          fCurrentPState;
 
        bigtime_t       fLastUpdate;
-};
+} CACHE_LINE_ALIGN;
 static CPUEntry* sCPUEntries;
 
 
@@ -44,6 +46,13 @@ CPUEntry::CPUEntry()
 }
 
 
+static void
+pstates_set_scheduler_mode(scheduler_mode mode)
+{
+       sAvoidBoost = mode == SCHEDULER_MODE_POWER_SAVING;
+}
+
+
 static int
 measure_pstate(CPUEntry* entry)
 {
@@ -83,7 +92,7 @@ set_pstate(uint16 pstate)
 
 
 static status_t
-increase_performance(int delta, bool allowBoost)
+pstates_increase_performance(int delta)
 {
        CPUEntry* entry = &sCPUEntries[smp_get_current_cpu()];
 
@@ -93,7 +102,7 @@ increase_performance(int delta, bool allowBoost)
        int pState = measure_pstate(entry);
        pState += (sBoostPState - pState) * delta / kCPUPerformanceScaleMax;
 
-       if (!allowBoost)
+       if (sAvoidBoost && pState < (sMaxPState + sBoostPState) / 2)
                pState = min_c(pState, sMaxPState);
 
        set_pstate(pState);
@@ -102,7 +111,7 @@ increase_performance(int delta, bool allowBoost)
 
 
 static status_t
-decrease_performance(int delta)
+pstates_decrease_performance(int delta)
 {
        CPUEntry* entry = &sCPUEntries[smp_get_current_cpu()];
 
@@ -184,6 +193,8 @@ init_pstates()
        if (sCPUEntries == NULL)
                return B_NO_MEMORY;
 
+       pstates_set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY);
+
        call_all_cpus_sync(set_normal_pstate, NULL);
        return B_OK;
 }
@@ -224,8 +235,10 @@ static cpufreq_module_info sIntelPStates = {
 
        1.0f,
 
-       increase_performance,
-       decrease_performance,
+       pstates_set_scheduler_mode,
+
+       pstates_increase_performance,
+       pstates_decrease_performance,
 };
 
 
diff --git a/src/add-ons/kernel/power/cpuidle/intel_cstates/intel_cstates.cpp 
b/src/add-ons/kernel/power/cpuidle/intel_cstates/intel_cstates.cpp
index d401b45..c90b010 100644
--- a/src/add-ons/kernel/power/cpuidle/intel_cstates/intel_cstates.cpp
+++ b/src/add-ons/kernel/power/cpuidle/intel_cstates/intel_cstates.cpp
@@ -27,17 +27,19 @@
 
 #define INTEL_CSTATES_MODULE_NAME      CPUIDLE_MODULES_PREFIX 
"/intel_cstates/v1"
 
-#define TIME_STEP                                      250
+#define BASE_TIME_STEP                         500
 
 struct CState {
        uint32  fCode;
        int             fSubStatesCount;
-       int             fSubStatesStep;
 };
 
 static CState sCStates[CPUIDLE_CSTATE_MAX];
 static int sCStateCount;
 
+static int sTimeStep = BASE_TIME_STEP;
+static bool sEnableWait = false;
+
 static bigtime_t* sIdleTime;
 
 
@@ -56,18 +58,31 @@ x86_mwait(uint32 eax, uint32 ecx)
 
 
 static void
-idle(void)
+cstates_set_scheduler_mode(scheduler_mode mode)
+{
+       if (mode == SCHEDULER_MODE_POWER_SAVING) {
+               sTimeStep = BASE_TIME_STEP / 4;
+               sEnableWait = true;
+       } else {
+               sTimeStep = BASE_TIME_STEP;
+               sEnableWait = false;
+       }
+}
+
+
+static void
+cstates_idle(void)
 {
        ASSERT(thread_get_current_thread()->pinned_to_cpu > 0);
        int32 cpu = smp_get_current_cpu();
 
        bigtime_t idleTime = sIdleTime[cpu];
-       int state = min_c(idleTime / TIME_STEP, sCStateCount - 1);
+       int state = min_c(idleTime / sTimeStep, sCStateCount - 1);
 
        ASSERT(state >= 0 && state < sCStateCount);
 
-       int subState = idleTime % TIME_STEP;
-       subState /= sCStates[state].fSubStatesStep;
+       int subState = idleTime % sTimeStep;
+       subState /= sTimeStep / sCStates[state].fSubStatesCount;
 
        ASSERT(subState >= 0 && subState < sCStates[state].fSubStatesCount);
 
@@ -84,8 +99,11 @@ idle(void)
 
 
 static void
-wait(int32* variable, int32 test)
+cstates_wait(int32* variable, int32 test)
 {
+       if (!sEnableWait)
+               return;
+
        InterruptsLocker _;
        x86_monitor(variable, 0, 0);
        if (*variable != test)
@@ -133,7 +151,6 @@ init_cstates()
 
                sCStates[sCStateCount].fCode = sCStateCount * 0x10;
                sCStates[sCStateCount].fSubStatesCount = subStates;
-               sCStates[sCStateCount].fSubStatesStep = TIME_STEP / subStates;
                sCStateCount++;
        }
 
@@ -145,6 +162,8 @@ init_cstates()
                return B_NO_MEMORY;
        memset(sIdleTime, 0, sizeof(bigtime_t) * smp_get_num_cpus());
 
+       cstates_set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY);
+
        dprintf("using Intel C-States: C0%s\n", cStates);
        return B_OK;
 }
@@ -183,8 +202,10 @@ static cpuidle_module_info sIntelCStates = {
 
        0.8f,
 
-       idle,
-       wait
+       cstates_set_scheduler_mode,
+
+       cstates_idle,
+       cstates_wait
 };
 
 
diff --git a/src/system/kernel/cpu.cpp b/src/system/kernel/cpu.cpp
index 2adc443..a0ffcaf 100644
--- a/src/system/kernel/cpu.cpp
+++ b/src/system/kernel/cpu.cpp
@@ -281,11 +281,21 @@ get_cpu_topology(void)
 }
 
 
+void
+cpu_set_scheduler_mode(enum scheduler_mode mode)
+{
+       if (sCPUPerformanceModule != NULL)
+               sCPUPerformanceModule->cpufreq_set_scheduler_mode(mode);
+       if (sCPUIdleModule != NULL)
+               sCPUIdleModule->cpuidle_set_scheduler_mode(mode);
+}
+
+
 status_t
-increase_cpu_performance(int delta, bool allowBoost)
+increase_cpu_performance(int delta)
 {
        if (sCPUPerformanceModule != NULL)
-               return sCPUPerformanceModule->increase_performance(delta, 
allowBoost);
+               return 
sCPUPerformanceModule->cpufreq_increase_performance(delta);
        return B_NOT_SUPPORTED;
 }
 
@@ -294,7 +304,7 @@ status_t
 decrease_cpu_performance(int delta)
 {
        if (sCPUPerformanceModule != NULL)
-               return sCPUPerformanceModule->decrease_performance(delta);
+               return 
sCPUPerformanceModule->cpufreq_decrease_performance(delta);
        return B_NOT_SUPPORTED;
 }
 
@@ -308,7 +318,7 @@ cpu_idle(void)
 #endif
 
        if (sCPUIdleModule != NULL)
-               sCPUIdleModule->idle();
+               sCPUIdleModule->cpuidle_idle();
        else
                arch_cpu_idle();
 }
@@ -318,7 +328,7 @@ void
 cpu_wait(int32* variable, int32 test)
 {
        if (sCPUIdleModule != NULL)
-               sCPUIdleModule->wait(variable, test);
+               sCPUIdleModule->cpuidle_wait(variable, test);
        else
                arch_cpu_pause();
 }
diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index 4801cde..5484b45 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -996,7 +996,11 @@ _user_estimate_max_scheduling_latency(thread_id id)
 status_t
 _user_set_scheduler_mode(int32 mode)
 {
-       return scheduler_set_operation_mode(static_cast<scheduler_mode>(mode));
+       scheduler_mode schedulerMode = static_cast<scheduler_mode>(mode);
+       status_t error = scheduler_set_operation_mode(schedulerMode);
+       if (error == B_OK)
+               cpu_set_scheduler_mode(schedulerMode);
+       return error;
 }
 
 
diff --git a/src/system/kernel/scheduler/scheduler_cpu.cpp 
b/src/system/kernel/scheduler/scheduler_cpu.cpp
index c78d62a..3c8203a 100644
--- a/src/system/kernel/scheduler/scheduler_cpu.cpp
+++ b/src/system/kernel/scheduler/scheduler_cpu.cpp
@@ -215,13 +215,11 @@ CPUEntry::_RequestPerformanceLevel(ThreadData* threadData)
 
                decrease_cpu_performance(delta);
        } else {
-               bool allowBoost = !gCurrentMode->avoid_boost;
-
                int32 delta = load - kTargetLoad;
                delta *= kMaxLoad - kTargetLoad;
                delta /= kCPUPerformanceScaleMax;
 
-               increase_cpu_performance(delta, allowBoost);
+               increase_cpu_performance(delta);
        }
 }
 

############################################################################

Commit:      7ce234bf2444831f6340230e9e42900ce25c0173
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Dec 17 23:03:56 2013 UTC

scheduler: Fix unassigning threads from core being disabled

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler.cpp 
b/src/system/kernel/scheduler/scheduler.cpp
index 5484b45..b6d303b 100644
--- a/src/system/kernel/scheduler/scheduler.cpp
+++ b/src/system/kernel/scheduler/scheduler.cpp
@@ -677,7 +677,7 @@ scheduler_set_cpu_enabled(int32 cpuID, bool enabled)
                        gIdlePackageList.Remove(package);
 
                // get rid of threads
-               thread_map(unassign_thread, &core->fCoreID);
+               thread_map(unassign_thread, core);
 
                core->fThreadCount = 0;
                while (core->fRunQueue.PeekMaximum() != NULL) {


Other related posts:

  • » [haiku-commits] BRANCH pdziepak-github.scheduler [7ce234b] src/add-ons/kernel/power/cpuidle/intel_cstates src/system/kernel src/system/kernel/scheduler src/add-ons/kernel/power/cpufreq/intel_pstates headers/os/drivers - pdziepak-github . scheduler