added 2 changesets to branch 'refs/remotes/yongcong-github/master' old head: 7c63b96007b1bcbd34ab3ce91ce255b3d73e0ce3 new head: 25ac8429946f4402dde90189d661fa44bc0e563f ---------------------------------------------------------------------------- 3871265: cpuidle: add stats reporting support 25ac842: cpuidle: we should exit when cStateCount is less than 3 If only C0, C1 are available, it doesn't make any sense to enable cpuidle [ Yongcong Du <ycdu.vmcore@xxxxxxxxx> ] ---------------------------------------------------------------------------- 4 files changed, 79 insertions(+), 8 deletions(-) headers/os/drivers/cpuidle.h | 9 +++++ src/add-ons/kernel/drivers/cpuidle/Jamfile | 2 + src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp | 39 ++++++++++++++++++-- src/add-ons/kernel/idle/generic/cpuidle.cpp | 37 ++++++++++++++++--- ############################################################################ Commit: 3871265a377dbb0b4ddb5fcf4478397a35f6b8ac Author: Yongcong Du <ycdu.vmcore@xxxxxxxxx> Date: Sat Jul 7 13:52:56 2012 UTC cpuidle: add stats reporting support ---------------------------------------------------------------------------- diff --git a/headers/os/drivers/cpuidle.h b/headers/os/drivers/cpuidle.h index 7234429..ed79be9 100644 --- a/headers/os/drivers/cpuidle.h +++ b/headers/os/drivers/cpuidle.h @@ -44,6 +44,15 @@ struct CpuidleModuleInfo { }; +struct GenCpuidle { + module_info info; + int32 (*GetIdleStateCount)(void); + char * (*GetIdleStateName)(int32 state); + void (*GetIdleStateInfo)(int32 cpu, int32 state, + CpuidleStat *stat); +}; + + #ifdef __cplusplus } #endif diff --git a/src/add-ons/kernel/drivers/cpuidle/Jamfile b/src/add-ons/kernel/drivers/cpuidle/Jamfile index 50b9290..ce5f450 100644 --- a/src/add-ons/kernel/drivers/cpuidle/Jamfile +++ b/src/add-ons/kernel/drivers/cpuidle/Jamfile @@ -1,5 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel drivers cpuidle ; +UsePrivateKernelHeaders ; + KernelAddon <driver>cpuidle : cpuidle.cpp ; diff --git a/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp b/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp index 9440358..82110c9 100644 --- a/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp +++ b/src/add-ons/kernel/drivers/cpuidle/cpuidle.cpp @@ -6,6 +6,10 @@ * Yongcong Du <ycdu.vmcore@xxxxxxxxx> */ +#include <stdio.h> +#include <string.h> +#include <smp.h> + #include <Drivers.h> #include <KernelExport.h> @@ -15,7 +19,7 @@ int32 api_version = B_CUR_DRIVER_API_VERSION; -CpuidleModuleInfo *sCpuidleModule; +static GenCpuidle *sGenCpuidle; static status_t cpuidle_open(const char *name, uint32 flags, void **cookie) @@ -49,7 +53,36 @@ cpuidle_ioctl(void *cookie, uint32 op, void *buffer, size_t length) static status_t cpuidle_read(void *cookie, off_t pos, void *buffer, size_t *length) { - *length = 0; + if (pos != 0) { + *length = 0; + return B_OK; + } + char *str = (char *)buffer; + size_t max_len = *length; + int32 stateCount = sGenCpuidle->GetIdleStateCount(); + int32 bytes = snprintf(str, max_len, "C-STATE COUNT: %"B_PRId32"\n", stateCount); + max_len-= bytes; + str += bytes; + int32 cpu = smp_get_num_cpus(); + + for (int32 i = 0; i < cpu; i++) { + bytes = snprintf(str, max_len, "CPU%"B_PRId32"\n", i); + max_len-= bytes; + str += bytes; + for (int32 j = 1; j < stateCount; j++) { + CpuidleStat stat; + bytes = snprintf(str, max_len, "%s\n", sGenCpuidle->GetIdleStateName(j)); + max_len-= bytes; + str += bytes; + sGenCpuidle->GetIdleStateInfo(i, j, &stat); + bytes = snprintf(str, max_len, "%lld %lldus\n", + stat.usageCount, stat.usageTime); + max_len-= bytes; + str += bytes; + } + } + *length = strlen((char *)buffer); + return B_OK; } @@ -102,7 +135,7 @@ init_driver(void) { status_t err; - err = get_module(B_CPUIDLE_MODULE_NAME, (module_info **)&sCpuidleModule); + err = get_module(B_CPUIDLE_MODULE_NAME, (module_info **)&sGenCpuidle); if (err != B_OK) { dprintf("can't load "B_CPUIDLE_MODULE_NAME"\n"); } diff --git a/src/add-ons/kernel/idle/generic/cpuidle.cpp b/src/add-ons/kernel/idle/generic/cpuidle.cpp index 4338a16..041b729 100644 --- a/src/add-ons/kernel/idle/generic/cpuidle.cpp +++ b/src/add-ons/kernel/idle/generic/cpuidle.cpp @@ -106,10 +106,37 @@ std_ops(int32 op, ...) } -static module_info sModule = { - B_CPUIDLE_MODULE_NAME, - 0, - std_ops +static char * +GetIdleStateName(int32 state) +{ + return sCpuidleModule->cStates[state].name; +} + + +static int32 +GetIdleStateCount(void) +{ + return sCpuidleModule->cStateCount; +} + + +static void +GetIdleStateInfo(int32 cpu, int32 state, CpuidleStat *stat) +{ + memcpy(stat, &sPerCPU[cpu].stats[state], sizeof(CpuidleStat)); +} + + +static GenCpuidle sModule = { + { + B_CPUIDLE_MODULE_NAME, + 0, + std_ops + }, + + GetIdleStateCount, + GetIdleStateName, + GetIdleStateInfo }; ############################################################################ Commit: 25ac8429946f4402dde90189d661fa44bc0e563f Author: Yongcong Du <ycdu.vmcore@xxxxxxxxx> Date: Thu Jul 5 02:42:55 2012 UTC cpuidle: we should exit when cStateCount is less than 3 If only C0, C1 are available, it doesn't make any sense to enable cpuidle ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/idle/generic/cpuidle.cpp b/src/add-ons/kernel/idle/generic/cpuidle.cpp index 041b729..0ce9851 100644 --- a/src/add-ons/kernel/idle/generic/cpuidle.cpp +++ b/src/add-ons/kernel/idle/generic/cpuidle.cpp @@ -86,7 +86,7 @@ std_ops(int32 op, ...) } close_module_list(cookie); - if (sCpuidleModule->cStateCount < 2) { + if (sCpuidleModule->cStateCount < 3) { dprintf("no enough available cstates, exiting...\n"); put_module(sCpuidleModule->info.name); return B_ERROR;