diff --git a/common/inc/pwrerr.h b/common/inc/pwrerr.h index 4de333e457f4d53b33affebe924c8ec58b3edf2c..5a6116219af55065742355db7a1895d9af8d7bbe 100644 --- a/common/inc/pwrerr.h +++ b/common/inc/pwrerr.h @@ -41,6 +41,8 @@ enum PWR_RtnCode { PWR_ERR_WATT_SCHED_NEVER_ENABLED, PWR_ERR_SMART_GRID_NOT_SURPPORTED, PWR_ERR_SMART_GRID_GOV_DISABLED, + PWR_ERR_WATT_NOT_SUPPORT_SET_DOMAIN, + PWR_ERR_WATT_NEED_DISABLE_TO_SET_DOMAIN, PWR_ERR_DISCONNECTED = 300, PWR_ERR_WRONG_RESPONSE_FROM_SERVER, PWR_ERR_ANSWER_LONGER_THAN_SIZE, diff --git a/common/inc/pwrmsg.h b/common/inc/pwrmsg.h index 19a2e37c994804375b11460bcddd0382ff58c417..9df17fc88ff631ccd755d0008566826e36fcd93d 100644 --- a/common/inc/pwrmsg.h +++ b/common/inc/pwrmsg.h @@ -103,6 +103,7 @@ enum OperationType { PROC_SET_SMART_GRID_PROCS_LEVEL, PROC_GET_SMART_GRID_GOV, PROC_SET_SMART_GRID_GOV, + PROC_SET_WATT_FIRST_DOMAIN, HBM_GET_SYS_STATE = 700, HBM_SET_ALL_POWER_STATE, }; diff --git a/pwrapic/inc/powerapi.h b/pwrapic/inc/powerapi.h index 6eacb409198d4e0e290e79571f2b0b8a698f3aac..7063709764b6a17f9600fb2ef8ea58b588ab1d90 100644 --- a/pwrapic/inc/powerapi.h +++ b/pwrapic/inc/powerapi.h @@ -91,6 +91,7 @@ PWR_API int PWR_USB_SetAutoSuspend(PWR_USB_AutoSuspend usbAts[], uint32_t len); PWR_API int PWR_PROC_QueryProcs(const char *keywords, pid_t procs[], uint32_t *num); PWR_API int PWR_PROC_GetWattState(int *state); PWR_API int PWR_PROC_SetWattState(int state); +PWR_API int PWR_PROC_SetWattFirstDomain(int cpuId); PWR_API int PWR_PROC_GetWattAttrs(PWR_PROC_WattAttrs *wattAttrs); PWR_API int PWR_PROC_SetWattAttrs(const PWR_PROC_WattAttrs *wattAttrs); PWR_API int PWR_PROC_GetWattProcs(pid_t wattProcs[], uint32_t *num); diff --git a/pwrapic/inc/pwrproc.h b/pwrapic/inc/pwrproc.h index 996824cf24aac61f85c2d6fb399377d093ef878b..aab42a0380efa09bead6ffdbe4f1bc6aad3bb395 100644 --- a/pwrapic/inc/pwrproc.h +++ b/pwrapic/inc/pwrproc.h @@ -27,6 +27,7 @@ int AddWattProcs(const pid_t wattProcs[], uint32_t num); int DelWattProcs(const pid_t wattProcs[], uint32_t num); int GetSmartGridState(int *state); int SetSmartGridState(int state); +int SetWattFirstDomain(int cpuId); int GetSmartGridProcs(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC_SmartGridProcs *sgProcs); int SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs); int GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov); diff --git a/pwrapic/src/powerapi.c b/pwrapic/src/powerapi.c index 1eb4eadeb8a687fa4374c61fb440fadaae3a75c9..cf67e0816565fffadd2d210f6a729779e5d024dc 100644 --- a/pwrapic/src/powerapi.c +++ b/pwrapic/src/powerapi.c @@ -580,6 +580,17 @@ int PWR_PROC_GetWattState(int *state) return GetProcWattState(state); } +int PWR_PROC_SetWattFirstDomain(int cpuId) +{ + CHECK_STATUS(STATUS_AUTHED); + + if (cpuId < 0) { + return PWR_ERR_INVALIDE_PARAM; + } + + return SetWattFirstDomain(cpuId); +} + int PWR_PROC_SetWattState(int state) { CHECK_STATUS(STATUS_AUTHED); diff --git a/pwrapic/src/pwrproc.c b/pwrapic/src/pwrproc.c index d14c24d274bb83af5d7ea93bc84fa8653d93f7f6..d0a81a9899ba25a6a1844ee3b8221a16e79c64a8 100644 --- a/pwrapic/src/pwrproc.c +++ b/pwrapic/src/pwrproc.c @@ -82,6 +82,26 @@ int SetProcWattState(int state) return ret; } +int SetWattFirstDomain(int cpuId) +{ + ReqInputParam input; + input.optType = PROC_SET_WATT_FIRST_DOMAIN; + input.dataLen = (uint32_t)sizeof(cpuId); + input.data = (char *)&cpuId; + + RspOutputParam output; + output.rspBuffSize = NULL; + output.rspData = NULL; + + int ret = SendReqAndWaitForRsp(input, output); + if (ret != PWR_SUCCESS) { + PwrLog(ERROR, "SetWattFirstDomain failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "SetWattFirstDomain succeed."); + } + return ret; +} + int GetProcWattAttrs(PWR_PROC_WattAttrs *wattAttrs) { ReqInputParam input; diff --git a/pwrapic/test/procapitest.c b/pwrapic/test/procapitest.c index 5c6e51baf02c193c3e466dec8ea4cd2b51f5f225..0ae3a5a368599bf1e6aa4c8728313144e5c8b298 100644 --- a/pwrapic/test/procapitest.c +++ b/pwrapic/test/procapitest.c @@ -36,6 +36,8 @@ static void TEST_PWR_PROC_SetAndGetWattState(void) printf("PWR_PROC_GetWattState. ret: %d state:%d\n", ret, state); ret = PWR_PROC_SetWattState(PWR_ENABLE); printf("PWR_PROC_SetWattState. ret: %d state:%d\n", ret, PWR_ENABLE); + ret = PWR_PROC_SetWattState(PWR_DISABLE); + printf("PWR_PROC_SetWattState. ret: %d state:%d\n", ret, PWR_DISABLE); } #define TEST_WATT_TH 60 @@ -143,6 +145,25 @@ static void TEST_PWR_PROC_SetAndGetSmartGridGov(void) ret, sgGov.sgAgentState, sgGov.sgLevel0Gov, sgGov.sgLevel1Gov); } +static void TEST_PWR_PROC_RebuildAffinityDomain(void) +{ + int cpuId = 0; + int ret = PWR_PROC_SetWattFirstDomain(cpuId); + printf("PWR_PROC_SetWattFirstDomain: ret:%d\n", ret); + + cpuId = 1234; + ret = PWR_PROC_SetWattFirstDomain(cpuId); + printf("PWR_PROC_SetWattFirstDomain: ret:%d\n", ret); + + cpuId = 23; + ret = PWR_PROC_SetWattFirstDomain(cpuId); + printf("PWR_PROC_SetWattFirstDomain: ret:%d\n", ret); + + ret = PWR_PROC_SetWattState(PWR_ENABLE); + ret = PWR_PROC_SetWattFirstDomain(cpuId); + printf("PWR_PROC_SetWattFirstDomain: ret:%d\n", ret); +} + // public============================================================================== void TEST_PROC_AllFunc(void) { @@ -153,4 +174,5 @@ void TEST_PROC_AllFunc(void) TEST_PWR_PROC_SetAndGetSmartGridState(); TEST_PWR_PROC_SetAndGetSmartGridProcs(); TEST_PWR_PROC_SetAndGetSmartGridGov(); + TEST_PWR_PROC_RebuildAffinityDomain(); } \ No newline at end of file diff --git a/pwrapis/inc/procservice.h b/pwrapis/inc/procservice.h index bb8ea3c4638901076c27bb812ce5d20419d19b66..9210a5ca405654a2fc16cfec87c564111c5fee42 100644 --- a/pwrapis/inc/procservice.h +++ b/pwrapis/inc/procservice.h @@ -20,6 +20,7 @@ void ProcQueryProcs(PwrMsg *req); void ProcGetWattState(PwrMsg *req); void ProcSetWattState(PwrMsg *req); void procGetWattAttrs(PwrMsg *req); +void ProcSetWattFirstDomain(PwrMsg *req); void ProcSetWattAttrs(PwrMsg *req); void ProcGetWattProcs(PwrMsg *req); void ProcAddWattProcs(PwrMsg *req); diff --git a/pwrapis/src/procservice.c b/pwrapis/src/procservice.c index a231f04a95638a8b63dc16f567c44738baf7da50..40c5bfd61c843719d2fc068ad69d60f62dc78fc8 100644 --- a/pwrapis/src/procservice.c +++ b/pwrapis/src/procservice.c @@ -31,8 +31,10 @@ #define WATT_ATTR_DOMAIN_MASK_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.affinity_domain_mask" #define WATT_ATTR_SCALE_INTERVAL_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.affinity_period_ms" #define WATT_PROC_PATH "/sys/fs/cgroup/cpu/watt_sched/tasks" +#define WATT_REBUILD_AFFINITY_DOMAIN_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.rebuild_affinity_domain" #define ROOT_CGROUP_PROC_PATH "/sys/fs/cgroup/cpu/tasks" #define ROOT_CGOUP_WATT_PATH "/sys/fs/cgroup/cpu/cpu.dynamic_affinity_mode" +#define ROOT_CGROUP_WATT_SET_DOMAIN_PATH "/sys/fs/cgroup/cpu/cpu.rebuild_affinity_domain" #define SMART_GRID_STATE_PATH "/proc/sys/kernel/smart_grid_strategy_ctrl" #define SMART_GRID_LEVEL_PATH_D "/proc/%d/smart_grid_level" @@ -378,6 +380,56 @@ void ProcSetWattState(PwrMsg *req) SendRspToClient(req, rspCode, NULL, 0); } +#define CPUINFO_FILE "/sys/devices/system/cpu/cpu%d/online" +static int checkIfCpuOnline(int cpuId) +{ + char fileName[MAX_FULL_NAME]; + + snprintf(fileName, sizeof(fileName), CPUINFO_FILE, cpuId); + + // CPU0 is always online on some systems. + if (cpuId == 0 && access(fileName, F_OK) != 0) { + return PWR_TRUE; + } + + int isOnline = PWR_FALSE; + if (ReadIntFromFile(fileName, &isOnline) != PWR_SUCCESS) { + return PWR_FALSE; + } + return isOnline; +} + +void ProcSetWattFirstDomain(PwrMsg *req) +{ + CHECK_SUPPORT_WATT_SCHED(); + if (req->head.dataLen != sizeof(int) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + + int *cpuId = (int *)req->data; + if (*cpuId < 0 || GetCpuCoreNumber() <= *cpuId || !checkIfCpuOnline(*cpuId)) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + + if (access(ROOT_CGROUP_WATT_SET_DOMAIN_PATH, F_OK) != 0) { + SendRspToClient(req, PWR_ERR_WATT_NOT_SUPPORT_SET_DOMAIN, NULL, 0); + return; + } + + int state = PWR_DISABLE; + int ret = ReadWattState(&state); + if (ret != PWR_SUCCESS) { + return SendRspToClient(req, ret, NULL, 0); + } else if (state == PWR_ENABLE) { // could set watt first domain only when watt is disabled + return SendRspToClient(req, PWR_ERR_WATT_NEED_DISABLE_TO_SET_DOMAIN, NULL, 0); + } + + ret = WriteIntToFile(WATT_REBUILD_AFFINITY_DOMAIN_PATH, *cpuId); + SendRspToClient(req, ret, NULL, 0); +} + void procGetWattAttrs(PwrMsg *req) { CHECK_SUPPORT_WATT_SCHED(); diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index 95decc1e0d030ff6a56a802ad524594f09ae0e6d..797a4de15a4818602f18f6a88f89d96a67ebd37f 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -510,6 +510,7 @@ static OptToFunct g_optToFunct[] = { {PROC_QUERY_PROCS, ProcQueryProcs}, {PROC_GET_WATT_STATE, ProcGetWattState}, {PROC_SET_WATT_STATE, ProcSetWattState}, + {PROC_SET_WATT_FIRST_DOMAIN, ProcSetWattFirstDomain}, {PROC_GET_WATT_ARRTS, procGetWattAttrs}, {PROC_SET_WATT_ARRTS, ProcSetWattAttrs}, {PROC_GET_WATT_PROCS, ProcGetWattProcs},