From 2ff8cb8e0cf3327483d68024ef9612782134cb47 Mon Sep 17 00:00:00 2001 From: queyanwen Date: Fri, 3 Nov 2023 10:57:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=9A=E8=BF=87=E5=85=B3?= =?UTF-8?q?=E9=94=AE=E5=AD=97=E6=9F=A5=E8=AF=A2=E8=BF=9B=E7=A8=8B=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2/?= =?UTF-8?q?=E8=AE=BE=E7=BD=AEsmart=5Fgrid=E8=B0=83=E9=A2=91=E5=99=A8?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/inc/pwrdata.h | 7 + common/inc/pwrerr.h | 6 +- common/inc/pwrmsg.h | 5 +- pwrapic/inc/powerapi.h | 3 + pwrapic/inc/pwrproc.h | 4 +- pwrapic/src/powerapi.c | 37 ++++- pwrapic/src/pwrproc.c | 66 ++++++++- pwrapic/test/procapitest.c | 31 +++++ pwrapis/inc/cpuservice.h | 2 + pwrapis/inc/procservice.h | 3 + pwrapis/inc/utils.h | 3 +- pwrapis/src/cpuservice.c | 31 +++-- pwrapis/src/procservice.c | 277 ++++++++++++++++++++++++++++++------- pwrapis/src/server.c | 5 +- pwrapis/src/utils.c | 8 +- 15 files changed, 413 insertions(+), 75 deletions(-) diff --git a/common/inc/pwrdata.h b/common/inc/pwrdata.h index 14f466c..01c64e0 100644 --- a/common/inc/pwrdata.h +++ b/common/inc/pwrdata.h @@ -273,4 +273,11 @@ typedef struct PWR_PROC_SmartGridProcs { int procNum; pid_t procs[0]; } PWR_PROC_SmartGridProcs; + +typedef struct PWR_PROC_SmartGridGov { + int sgAgentState; + char sgLevel0Gov[PWR_MAX_ELEMENT_NAME_LEN]; + char sgLevel1Gov[PWR_MAX_ELEMENT_NAME_LEN]; +} PWR_PROC_SmartGridGov; + #endif \ No newline at end of file diff --git a/common/inc/pwrerr.h b/common/inc/pwrerr.h index 12ba40d..c0a0d6d 100644 --- a/common/inc/pwrerr.h +++ b/common/inc/pwrerr.h @@ -33,8 +33,10 @@ enum PWR_RtnCode { PWR_ERR_PATH_VERIFY, PWR_ERR_NOT_REGISTED = 100, PWR_ERR_NOT_AUTHED, - PWR_ERR_WATT_SCHED_NOT_ENABLE, + PWR_ERR_WATT_SCHED_NOT_SURPPORTED, + PWR_ERR_WATT_SCHED_NEVER_ENABLED, PWR_ERR_SMART_GRID_NOT_SURPPORTED, + PWR_ERR_SMART_GRID_GOV_DISABLED, PWR_ERR_OVER_MAX_CONNECTION, PWR_ERR_DISCONNECTED = 300, PWR_ERR_WRONG_RESPONSE_FROM_SERVER, @@ -49,6 +51,6 @@ enum PWR_RtnCode { PWR_ERR_FILE_FPRINT_FAILED, PWR_ERR_FILE_FFLUSH_FAILED, PWR_ERR_FILE_OPEN_FAILED, - PWR_ERR_FILE_SPRINTF_FIILED, + PWR_ERR_FILE_SPRINTF_FAILED, }; #endif \ No newline at end of file diff --git a/common/inc/pwrmsg.h b/common/inc/pwrmsg.h index 36e0930..6218f5e 100644 --- a/common/inc/pwrmsg.h +++ b/common/inc/pwrmsg.h @@ -86,7 +86,8 @@ enum OperationType { NET_SET_SPEED_MOD, USB_GET_AUTO_SUSPEND = 500, USB_SET_AUTO_SUSPEND, - PROC_GET_WATT_STATE = 600, + PROC_QUERY_PROCS = 600, + PROC_GET_WATT_STATE, PROC_SET_WATT_STATE, PROC_GET_WATT_ARRTS, PROC_SET_WATT_ARRTS, @@ -97,6 +98,8 @@ enum OperationType { PROC_SET_SMART_GRID_STATE, PROC_GET_SMART_GRID_PROCS, PROC_SET_SMART_GRID_PROCS_LEVEL, + PROC_GET_SMART_GRID_GOV, + PROC_SET_SMART_GRID_GOV, }; enum DataFormat { FMT_BIN = 0, diff --git a/pwrapic/inc/powerapi.h b/pwrapic/inc/powerapi.h index b5af516..6176e83 100644 --- a/pwrapic/inc/powerapi.h +++ b/pwrapic/inc/powerapi.h @@ -83,6 +83,7 @@ PWR_API int PWR_USB_SetAutoSuspend(PWR_USB_AutoSuspend usbAts[], uint32_t len); // PROC +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_GetWattAttrs(PWR_PROC_WattAttrs *wattAttrs); @@ -94,6 +95,8 @@ PWR_API int PWR_PROC_GetSmartGridState(int *state); PWR_API int PWR_PROC_SetSmartGridState(int state); PWR_API int PWR_PROC_GetSmartGridProcs(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC_SmartGridProcs *sgProcs); PWR_API int PWR_PROC_SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs); +PWR_API int PWR_PROC_GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov); +PWR_API int PWR_PROC_SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov); #ifdef __cplusplus } diff --git a/pwrapic/inc/pwrproc.h b/pwrapic/inc/pwrproc.h index ff1c4ba..996824c 100644 --- a/pwrapic/inc/pwrproc.h +++ b/pwrapic/inc/pwrproc.h @@ -17,6 +17,7 @@ #include #include "pwrdata.h" +int QueryProcsByKeywords(const char *keywords, pid_t procs[], uint32_t *num); int GetProcWattState(int *state); int SetProcWattState(int state); int GetProcWattAttrs(PWR_PROC_WattAttrs *wattAttrs); @@ -28,5 +29,6 @@ int GetSmartGridState(int *state); int SetSmartGridState(int state); 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); +int SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov); #endif diff --git a/pwrapic/src/powerapi.c b/pwrapic/src/powerapi.c index 6e0e5ef..6f570ba 100644 --- a/pwrapic/src/powerapi.c +++ b/pwrapic/src/powerapi.c @@ -485,6 +485,20 @@ int PWR_USB_SetAutoSuspend(PWR_USB_AutoSuspend usbAts[], uint32_t len) } // PROC +int PWR_PROC_QueryProcs(const char *keywords, pid_t procs[], uint32_t *num) +{ + CHECK_STATUS(STATUS_REGISTERTED); + CHECK_NULL_POINTER(procs); + CHECK_NULL_POINTER(num); + if (*num == 0) { + return PWR_ERR_INVALIDE_PARAM; + } + if (keywords && strlen(keywords) >= PWR_MAX_STRING_LEN) { + return PWR_ERR_INVALIDE_PARAM; + } + return QueryProcsByKeywords(keywords, procs, num); +} + int PWR_PROC_GetWattState(int *state) { CHECK_STATUS(STATUS_REGISTERTED); @@ -535,7 +549,7 @@ int PWR_PROC_AddWattProcs(const pid_t wattProcs[], uint32_t num) { CHECK_STATUS(STATUS_AUTHED); CHECK_NULL_POINTER(wattProcs); - if (num == 0) { + if (num == 0 || num > PWR_MAX_PROC_NUM) { return PWR_ERR_INVALIDE_PARAM; } return AddWattProcs(wattProcs, num); @@ -545,7 +559,7 @@ int PWR_PROC_DelWattProcs(const pid_t wattProcs[], uint32_t num) { CHECK_STATUS(STATUS_AUTHED); CHECK_NULL_POINTER(wattProcs); - if (num == 0) { + if (num == 0 || num > PWR_MAX_PROC_NUM) { return PWR_ERR_INVALIDE_PARAM; } return DelWattProcs(wattProcs, num); @@ -581,8 +595,25 @@ int PWR_PROC_SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs) { CHECK_STATUS(STATUS_AUTHED); CHECK_NULL_POINTER(sgProcs); - if (sgProcs->procNum == 0) { + if (sgProcs->procNum == 0 || sgProcs->procNum > PWR_MAX_PROC_NUM) { return PWR_ERR_INVALIDE_PARAM; } return SetSmartGridLevel(sgProcs); +} + +int PWR_PROC_GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov) +{ + CHECK_STATUS(STATUS_REGISTERTED); + CHECK_NULL_POINTER(sgGov); + return GetSmartGridGov(sgGov); +} + +int PWR_PROC_SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov) +{ + CHECK_STATUS(STATUS_AUTHED); + CHECK_NULL_POINTER(sgGov); + if (sgGov->sgAgentState != PWR_ENABLE && sgGov->sgAgentState != PWR_DISABLE) { + return PWR_ERR_INVALIDE_PARAM; + } + return SetSmartGridGov(sgGov); } \ No newline at end of file diff --git a/pwrapic/src/pwrproc.c b/pwrapic/src/pwrproc.c index 3ac86f5..d14c24d 100644 --- a/pwrapic/src/pwrproc.c +++ b/pwrapic/src/pwrproc.c @@ -14,10 +14,33 @@ * **************************************************************************** */ #include "pwrproc.h" +#include #include "pwrlog.h" #include "pwrerr.h" #include "sockclient.h" +int QueryProcsByKeywords(const char *keywords, pid_t procs[], uint32_t *num) +{ + ReqInputParam input; + input.optType = PROC_QUERY_PROCS; + input.dataLen = strlen(keywords) + 1; + input.data = (char *)keywords; + + RspOutputParam output; + uint32_t size = (uint32_t)sizeof(pid_t) * (*num); + output.rspBuffSize = &size; + output.rspData = (char *)procs; + + int ret = SendReqAndWaitForRsp(input, output); + *num = (uint32_t)(size / sizeof(pid_t)); + if (ret != PWR_SUCCESS) { + PwrLog(ERROR, "QueryProcsByKeywords failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "QueryProcsByKeywords succeed."); + } + return ret; +} + int GetProcWattState(int *state) { ReqInputParam input; @@ -232,7 +255,7 @@ int SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs) ReqInputParam input; input.optType = PROC_SET_SMART_GRID_PROCS_LEVEL; input.dataLen = (uint32_t)(sizeof(PWR_PROC_SmartGridProcs) + sizeof(pid_t) * (sgProcs->procNum)); - input.data = (char *)&sgProcs; + input.data = (char *)sgProcs; RspOutputParam output; output.rspBuffSize = NULL; @@ -247,3 +270,44 @@ int SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs) return ret; } +int GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov) +{ + ReqInputParam input; + input.optType = PROC_GET_SMART_GRID_GOV; + input.dataLen = 0; + input.data = NULL; + + RspOutputParam output; + uint32_t size = (uint32_t)sizeof(PWR_PROC_SmartGridGov); + output.rspBuffSize = &size; + output.rspData = (char *)sgGov; + + int ret = SendReqAndWaitForRsp(input, output); + if (ret != PWR_SUCCESS) { + PwrLog(ERROR, "GetSmartGridGov failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "GetSmartGridGov succeed."); + } + return ret; +} + +int SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov) +{ + ReqInputParam input; + input.optType = PROC_SET_SMART_GRID_GOV; + uint32_t size = (uint32_t)sizeof(PWR_PROC_SmartGridGov); + input.dataLen = size; + input.data = (char *)sgGov; + + RspOutputParam output; + output.rspBuffSize = NULL; + output.rspData = NULL; + + int ret = SendReqAndWaitForRsp(input, output); + if (ret != PWR_SUCCESS) { + PwrLog(ERROR, "SetSmartGridGov failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "SetSmartGridGov succeed."); + } + return ret; +} diff --git a/pwrapic/test/procapitest.c b/pwrapic/test/procapitest.c index 3d5d8d5..5c6e51b 100644 --- a/pwrapic/test/procapitest.c +++ b/pwrapic/test/procapitest.c @@ -18,6 +18,16 @@ #include "powerapi.h" #define INVALIDE_STATE (-1) +#define TEST_MAX_PROC_NUM 100 +static void TEST_PWR_PROC_QueryProcs(void) +{ + const char keywords[] = "nginx|mysql"; + pid_t procs[TEST_MAX_PROC_NUM] = {0}; + uint32_t num = TEST_MAX_PROC_NUM; + int ret = PWR_PROC_QueryProcs(keywords, procs, &num); + printf("PWR_PROC_QueryProcs. ret: %d num:%d\n", ret, num); +} + static void TEST_PWR_PROC_SetAndGetWattState(void) { int state = INVALIDE_STATE; @@ -114,12 +124,33 @@ static void TEST_PWR_PROC_SetAndGetSmartGridProcs(void) free(sgp); } +static void TEST_PWR_PROC_SetAndGetSmartGridGov(void) +{ + PWR_PROC_SmartGridGov sgGov = {0}; + int ret = PWR_PROC_GetSmartGridGov(&sgGov); + printf("PWR_PROC_GetSmartGridGov: ret:%d sgAgentState:%d, sgLevel0Gov:%s sgLevel1Gov:%s\n", + ret, sgGov.sgAgentState, sgGov.sgLevel0Gov, sgGov.sgLevel1Gov); + + const char level0Gov[] = "performance"; + const char level1Gov[] = "conservative"; + sgGov.sgAgentState = PWR_ENABLE; + strncpy(sgGov.sgLevel0Gov, level0Gov, PWR_MAX_ELEMENT_NAME_LEN - 1); + strncpy(sgGov.sgLevel1Gov, level1Gov, PWR_MAX_ELEMENT_NAME_LEN - 1); + ret = PWR_PROC_SetSmartGridGov(&sgGov); + bzero(&sgGov, sizeof(PWR_PROC_SmartGridGov)); + PWR_PROC_GetSmartGridGov(&sgGov); + printf("PWR_PROC_SetSmartGridGov: ret:%d sgAgentState:%d, sgLevel0Gov:%s sgLevel1Gov:%s\n", + ret, sgGov.sgAgentState, sgGov.sgLevel0Gov, sgGov.sgLevel1Gov); +} + // public============================================================================== void TEST_PROC_AllFunc(void) { + TEST_PWR_PROC_QueryProcs(); TEST_PWR_PROC_SetAndGetWattState(); TEST_PWR_PROC_SetAndGetWattAttrs(); TEST_PWR_PROC_AddAndDelWattProcs(); TEST_PWR_PROC_SetAndGetSmartGridState(); TEST_PWR_PROC_SetAndGetSmartGridProcs(); + TEST_PWR_PROC_SetAndGetSmartGridGov(); } \ No newline at end of file diff --git a/pwrapis/inc/cpuservice.h b/pwrapis/inc/cpuservice.h index f9aa6c8..24612f7 100644 --- a/pwrapis/inc/cpuservice.h +++ b/pwrapis/inc/cpuservice.h @@ -25,6 +25,8 @@ void GetCpuFreq(PwrMsg *req); void SetCpuFreq(PwrMsg *req); int PerfDataRead(PWR_CPU_PerfData *perfData); int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum); +int CurrentGovernorRead(char *gov); +int SetGovernorForAllPcy(const char *gov); void GetCpuFreqGovernor(PwrMsg *req); void SetCpuFreqGovernor(PwrMsg *req); void GetCpuFreqGovAttrs(PwrMsg *req); diff --git a/pwrapis/inc/procservice.h b/pwrapis/inc/procservice.h index d6fc181..bb8ea3c 100644 --- a/pwrapis/inc/procservice.h +++ b/pwrapis/inc/procservice.h @@ -16,6 +16,7 @@ #define PAPIS_PROC_SERVICE_H__ #include "pwrmsg.h" +void ProcQueryProcs(PwrMsg *req); void ProcGetWattState(PwrMsg *req); void ProcSetWattState(PwrMsg *req); void procGetWattAttrs(PwrMsg *req); @@ -27,4 +28,6 @@ void ProcGetSmartGridState(PwrMsg *req); void ProcSetSmartGridState(PwrMsg *req); void ProcGetSmartGridProcs(PwrMsg *req); void ProcSetSmartGridProcsLevel(PwrMsg *req); +void ProcGetSmartGridGov(PwrMsg *req); +void ProcSetSmartGridGov(PwrMsg *req); #endif diff --git a/pwrapis/inc/utils.h b/pwrapis/inc/utils.h index 492c6c3..01ddacc 100644 --- a/pwrapis/inc/utils.h +++ b/pwrapis/inc/utils.h @@ -240,11 +240,10 @@ const char *StrReplace(const char *src, const char *old, const char *new, char * void DeleteChar(char str[], char a); char *StrMatch(char *str, char *want); int DeleteSubstr(char *str, char *substr); -char *StrMatch(char *str, char *want); void StrCopy(char *dest, const char *src, int destSize); int InIntRange(int *range, int len, int a); int ReadFile(const char *strInfo, char *buf, int bufLen); -int WriteFile(const char *strInfo, char *buf, int bufLen); +int WriteFile(const char *strInfo, const char *buf, int bufLen); int WriteFileAndCheck(const char *strInfo, char *buf, int bufLen); int WriteIntToFile(const char *path, int content); int GetMd5(const char *filename, char *md5); diff --git a/pwrapis/src/cpuservice.c b/pwrapis/src/cpuservice.c index f642fb5..2caec4c 100644 --- a/pwrapis/src/cpuservice.c +++ b/pwrapis/src/cpuservice.c @@ -412,7 +412,7 @@ static int AllGovernorsRead(char (*govList)[PWR_MAX_ELEMENT_NAME_LEN], int *govN return 0; } -static int CheckAvailableGovernor(char *gov, char *policys) +static int CheckAvailableGovernor(const char *gov, char *policys) { char *checkGovInfo = malloc(strlen(gov) + PWR_MAX_NAME_LEN); if (checkGovInfo == NULL) { @@ -444,7 +444,7 @@ static int CheckAvailableGovernor(char *gov, char *policys) return 1; } -static int CurrentGovernorRead(char *rstData) +int CurrentGovernorRead(char *gov) { char govInfo[] = "/sys/devices/system/cpu/cpufreq/policy0/scaling_governor"; char buf[PWR_MAX_STRING_LEN]; @@ -454,11 +454,11 @@ static int CurrentGovernorRead(char *rstData) } DeleteChar(buf, ' '); - StrCopy(rstData, buf, PWR_MAX_ELEMENT_NAME_LEN); + StrCopy(gov, buf, PWR_MAX_ELEMENT_NAME_LEN); return PWR_SUCCESS; } -static int GovernorSet(char *gov, char (*policys)[PWR_MAX_ELEMENT_NAME_LEN], int *poNum) +static int GovernorSet(const char *gov, char (*policys)[PWR_MAX_ELEMENT_NAME_LEN], int *poNum) { int i; for (i = 0; i < (*poNum); i++) { @@ -541,10 +541,10 @@ static int FreqSet(PWR_CPU_CurFreq *target, int num) StrCopy(setFreqInfo, s1, PWR_MAX_NAME_LEN); freq = (int)target[i].curFreq * THOUSAND; if (snprintf(bufFreq, PWR_MAX_ELEMENT_NAME_LEN - 1, "%d", freq) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } if (snprintf(bufPolicyId, PWR_MAX_ELEMENT_NAME_LEN - 1, "%d", target[i].policyId) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } strncat(setFreqInfo, bufPolicyId, strlen(bufPolicyId)); strncat(setFreqInfo, s2, strlen(s2)); @@ -674,7 +674,7 @@ static int FreqRangeSet(PWR_CPU_FreqRange *rstData) // set min freq if (snprintf(buf, PWR_MAX_ELEMENT_NAME_LEN - 1, "%d", rstData->minFreq * THOUSAND) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } char minFreqFile[PWR_MAX_NAME_LEN] = {0}; @@ -692,7 +692,7 @@ static int FreqRangeSet(PWR_CPU_FreqRange *rstData) // set max freq if (snprintf(buf, PWR_MAX_ELEMENT_NAME_LEN - 1, "%d", rstData->maxFreq * THOUSAND) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } char maxFreqFile[PWR_MAX_NAME_LEN] = {0}; const char max1[] = "/sys/devices/system/cpu/cpufreq/"; @@ -815,14 +815,21 @@ void GetCpuFreqGovernor(PwrMsg *req) SendRspToClient(req, rspCode, (char *)rstData, sizeof(char) * PWR_MAX_ELEMENT_NAME_LEN); } -void SetCpuFreqGovernor(PwrMsg *req) +int SetGovernorForAllPcy(const char *gov) { + if (!gov) { + return PWR_ERR_NULL_POINTER; + } char policys[PWR_MAX_CPU_LIST_LEN][PWR_MAX_ELEMENT_NAME_LEN]; bzero(policys, sizeof(policys)); - int poNum; + int poNum = 0; GetPolicys(policys, &poNum); - int rspCode = GovernorSet(req->data, policys, &poNum); - SendRspToClient(req, rspCode, NULL, 0); + return GovernorSet(gov, policys, &poNum); +} + +void SetCpuFreqGovernor(PwrMsg *req) +{ + SendRspToClient(req, SetGovernorForAllPcy(req->data), NULL, 0); } void GetCpuFreqGovAttrs(PwrMsg *req) diff --git a/pwrapis/src/procservice.c b/pwrapis/src/procservice.c index ec0eb6e..e33a2df 100644 --- a/pwrapis/src/procservice.c +++ b/pwrapis/src/procservice.c @@ -20,20 +20,81 @@ #include "server.h" #include "log.h" #include "utils.h" +#include "cpuservice.h" + +#define GET_US_PROCS_CMD "pstree -pn 1 | grep -o '([[:digit:]]*)' | grep -o '[[:digit:]]*'" +#define QUERY_PROCS_CMD "ps -ef | grep -E '%s' | grep -v grep | awk '{print $2}'" #define WATT_CGROUP_PATH "/sys/fs/cgroup/cpu/watt_sched" #define WATT_STATE_PATH "/sys/fs/cgroup/cpu/watt_sched/cpu.dynamic_affinity_mode" - #define WATT_ATTR_SCALE_THRESHOLD_PATH "/proc/sys/kernel/sched_util_low_pct" #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 ROOT_CGROUP_PROC_PATH "/sys/fs/cgroup/cpu/tasks" +#define ROOT_CGOUP_WATT_PATH "/sys/fs/cgroup/cpu/cpu.dynamic_affinity_mode" #define SMART_GRID_STATE_PATH "/proc/sys/kernel/smart_grid_strategy_ctrl" #define SMART_GRID_LEVEL_PATH_D "/proc/%d/smart_grid_level" #define SMART_GRID_LEVEL_PATH_S "/proc/%s/smart_grid_level" #define PROC_PATH "/proc" +#define SMART_GRID_GOV_PATH "/sys/devices/system/cpu/cpufreq/smart_grid_agent/current_governor" + +#define CHECK_SUPPORT_WATT_SCHED() \ + { \ + if (access(ROOT_CGOUP_WATT_PATH, F_OK) != 0) { \ + SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_SURPPORTED, NULL, 0); \ + return; \ + } \ + } + +#define CHECK_WATT_SCHED_EXIST() \ + { \ + if (access(WATT_PROC_PATH, F_OK) != 0) { \ + SendRspToClient(req, PWR_ERR_WATT_SCHED_NEVER_ENABLED, NULL, 0); \ + return; \ + } \ + } + +#define CHECK_SUPPORT_SMART_GRID() \ + { \ + if (access(SMART_GRID_STATE_PATH, F_OK) != 0) { \ + SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); \ + return; \ + } \ + } + +static int QueryProcs(const char *keyWords, pid_t procs[], int maxNum, int *procNum) +{ + char cmd[PWR_MAX_STRING_LEN] = GET_US_PROCS_CMD; + if (keyWords) { + if (sprintf(cmd, QUERY_PROCS_CMD, keyWords) < 0) { + return PWR_ERR_FILE_SPRINTF_FAILED; + } + } + FILE *fp = popen(cmd, "r"); + if (fp == NULL) { + return PWR_ERR_SYS_EXCEPTION; + } + char line[STR_LEN_FOR_INT] = {0}; + *procNum = 0; + while (fgets(line, STR_LEN_FOR_INT - 1, fp) != NULL && *procNum < maxNum) { + procs[*procNum] = atoi(line); + (*procNum)++; + } + pclose(fp); + return PWR_SUCCESS; +} + +static inline int ReadWattState(int *state) +{ + char buff[PWR_STATE_LEN] = {0}; + int ret = ReadFile(WATT_STATE_PATH, buff, PWR_STATE_LEN); + if (ret == PWR_SUCCESS) { + *state = atoi(buff); + } + return ret; +} static int ReadWattAttrs(PWR_PROC_WattAttrs *wattAttrs) { @@ -116,14 +177,6 @@ static int ReadWattProcs(pid_t *wattProcs, size_t size, int *procNum) return PWR_SUCCESS; } -static inline int SupportSmartGrid() -{ - if (access(SMART_GRID_STATE_PATH, F_OK) != 0) { - return PWR_FALSE; - } - return PWR_TRUE; -} - static int ReadSmartGridProcsByLevel(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC_SmartGridProcs *sgProcs, int maxNum) { @@ -141,7 +194,7 @@ static int ReadSmartGridProcsByLevel(PWR_PROC_SMART_GRID_LEVEL level, continue; } if (sprintf(procLevelPath, SMART_GRID_LEVEL_PATH_S, dt->d_name) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } if (ReadFile(procLevelPath, strLevel, STR_LEN_FOR_INT) != PWR_SUCCESS) { continue; @@ -158,36 +211,142 @@ static int WriteSmartGridProcsLevel(const PWR_PROC_SmartGridProcs *sgProcs) { char strLevel[STR_LEN_FOR_INT] = {0}; if (sprintf(strLevel, "%d", sgProcs->level) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } char procLevelPath[MAX_FULL_NAME] = {0}; for (int i = 0; i < sgProcs->procNum; i++) { if (sprintf(procLevelPath, SMART_GRID_LEVEL_PATH_D, sgProcs->procs[i]) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } (void)WriteFile(procLevelPath, strLevel, STR_LEN_FOR_INT); } return PWR_SUCCESS; } +static inline int SmartGridGovEnabled() +{ + // There is no path of SMART_GRID_GOV_PATH if smart_grid_agent governor is not configed. + if (access(SMART_GRID_GOV_PATH, F_OK) == 0) { + return PWR_TRUE; + } + return PWR_FALSE; +} + +#define LEVEL0_PREFIX "level-0:" +#define LEVEL1_PREFIX "level-1:" +static int ReadSmartGridGov(PWR_PROC_SmartGridGov *sgGov) +{ + if (!SmartGridGovEnabled()) { + bzero(sgGov, sizeof(PWR_PROC_SmartGridGov)); + sgGov->sgAgentState = PWR_DISABLE; + return PWR_SUCCESS; + } + sgGov->sgAgentState = PWR_ENABLE; + + FILE *fp = fopen(SMART_GRID_GOV_PATH, "r"); + if (fp == NULL) { + return PWR_ERR_SYS_EXCEPTION; + } + char line[PWR_MAX_STRING_LEN] = {0}; + while (fgets(line, PWR_MAX_STRING_LEN - 1, fp) != NULL) { + LRtrim(line); + if (strstr(line, LEVEL0_PREFIX) != NULL) { + DeleteSubstr(line, LEVEL0_PREFIX); + Ltrim(line); + StrCopy(sgGov->sgLevel0Gov, line, PWR_MAX_ELEMENT_NAME_LEN); + continue; + } + if (strstr(line, LEVEL1_PREFIX) != NULL) { + DeleteSubstr(line, LEVEL1_PREFIX); + Ltrim(line); + StrCopy(sgGov->sgLevel1Gov, line, PWR_MAX_ELEMENT_NAME_LEN); + continue; + } + } + return PWR_SUCCESS; +} + +#define SMART_GRID_GOV_NAME "smart_grid_agent" +#define EXT_GOV_NAME_LEN (PWR_MAX_ELEMENT_NAME_LEN + 2) +static char g_orgGov[PWR_MAX_ELEMENT_NAME_LEN] = "conservative"; +static int WriteSmartGridGov(PWR_PROC_SmartGridGov *sgGov) +{ + if (sgGov->sgAgentState == PWR_DISABLE) { + if (!SmartGridGovEnabled()) { + return PWR_SUCCESS; + } + return SetGovernorForAllPcy(g_orgGov); + } + // sgGov->sgAgentState == PWR_ENABLE + if (!SmartGridGovEnabled()) { + (void)CurrentGovernorRead(g_orgGov); + } + + int ret = SetGovernorForAllPcy(SMART_GRID_GOV_NAME); + if (ret != PWR_SUCCESS) { + return ret; + } + + char gov[EXT_GOV_NAME_LEN] = {0}; + if (strlen(sgGov->sgLevel0Gov) != 0) { + if (sprintf(gov, "0-%s", sgGov->sgLevel0Gov) < 0) { + return PWR_ERR_FILE_SPRINTF_FAILED; + } + int ret = WriteFile(SMART_GRID_GOV_PATH, gov, EXT_GOV_NAME_LEN); + if (ret != PWR_SUCCESS) { + return ret; + } + } + + if (strlen(sgGov->sgLevel1Gov) != 0) { + if (sprintf(gov, "1-%s", sgGov->sgLevel1Gov) < 0) { + return PWR_ERR_FILE_SPRINTF_FAILED; + } + return WriteFile(SMART_GRID_GOV_PATH, gov, EXT_GOV_NAME_LEN); + } + return PWR_SUCCESS; +} + // public=========================================================================================== +void ProcQueryProcs(PwrMsg *req) +{ + char *keyWords = NULL; + if (req->head.dataLen != 0 && !req->data && strlen(req->data) != 0) { + keyWords = req->data; + } + + size_t size = sizeof(pid_t) * PWR_MAX_PROC_NUM; + pid_t *procs = (pid_t *)malloc(size); + if (!procs) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + bzero(procs, size); + int procNum = 0; + int rspCode = QueryProcs(keyWords, procs, PWR_MAX_PROC_NUM, &procNum); + if (rspCode != PWR_SUCCESS) { + free(procs); + SendRspToClient(req, rspCode, NULL, 0); + } else { + SendRspToClient(req, rspCode, (char *)procs, procNum * sizeof(pid_t)); + } +} + void ProcGetWattState(PwrMsg *req) { + CHECK_SUPPORT_WATT_SCHED(); int *state = (int *)malloc(sizeof(int)); if (!state) { return; } *state = PWR_DISABLE; - char buff[PWR_STATE_LEN] = {0}; - int ret = ReadFile(WATT_STATE_PATH, buff, PWR_STATE_LEN); - if (ret == PWR_SUCCESS) { - *state = atoi(buff); - } - SendRspToClient(req, 0, (char *)state, sizeof(int)); + int ret = ReadWattState(state); + SendRspToClient(req, ret, (char *)state, sizeof(int)); } void ProcSetWattState(PwrMsg *req) { + CHECK_SUPPORT_WATT_SCHED(); if (req->head.dataLen != sizeof(int) || !req->data) { SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); return; @@ -207,6 +366,8 @@ void ProcSetWattState(PwrMsg *req) void procGetWattAttrs(PwrMsg *req) { + CHECK_SUPPORT_WATT_SCHED(); + CHECK_WATT_SCHED_EXIST(); size_t size = sizeof(PWR_PROC_WattAttrs); PWR_PROC_WattAttrs *wattAttrs = (PWR_PROC_WattAttrs *)malloc(size); if (!wattAttrs) { @@ -225,6 +386,8 @@ void procGetWattAttrs(PwrMsg *req) void ProcSetWattAttrs(PwrMsg *req) { + CHECK_SUPPORT_WATT_SCHED(); + CHECK_WATT_SCHED_EXIST(); if (req->head.dataLen != sizeof(PWR_PROC_WattAttrs) || !req->data) { SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); return; @@ -240,7 +403,7 @@ void ProcSetWattAttrs(PwrMsg *req) // previous value if some settings fails. PWR_PROC_WattAttrs orgAttrs = {0}; if (ReadWattAttrs(&orgAttrs) != PWR_SUCCESS) { - SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); + SendRspToClient(req, PWR_ERR_WATT_SCHED_NEVER_ENABLED, NULL, 0); return; } int rspCode = WriteWattAttrs(wattAttrs); @@ -252,10 +415,9 @@ void ProcSetWattAttrs(PwrMsg *req) void ProcGetWattProcs(PwrMsg *req) { - if (access(WATT_PROC_PATH, F_OK) != 0) { - SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); - return; - } + CHECK_SUPPORT_WATT_SCHED(); + CHECK_WATT_SCHED_EXIST(); + size_t size = sizeof(pid_t) * PWR_MAX_PROC_NUM; pid_t *wattProcs = (pid_t *)malloc(size); if (!wattProcs) { @@ -275,10 +437,9 @@ void ProcGetWattProcs(PwrMsg *req) void ProcAddWattProcs(PwrMsg *req) { - if (access(WATT_PROC_PATH, F_OK) != 0) { - SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); - return; - } + CHECK_SUPPORT_WATT_SCHED(); + CHECK_WATT_SCHED_EXIST(); + if (req->head.dataLen < sizeof(pid_t) || !req->data) { SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); return; @@ -294,10 +455,9 @@ void ProcAddWattProcs(PwrMsg *req) void ProcDelWattProcs(PwrMsg *req) { - if (access(WATT_PROC_PATH, F_OK) != 0) { - SendRspToClient(req, PWR_ERR_WATT_SCHED_NOT_ENABLE, NULL, 0); - return; - } + CHECK_SUPPORT_WATT_SCHED(); + CHECK_WATT_SCHED_EXIST(); + if (req->head.dataLen < sizeof(pid_t) || !req->data) { SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); return; @@ -312,12 +472,10 @@ void ProcDelWattProcs(PwrMsg *req) SendRspToClient(req, PWR_SUCCESS, NULL, 0); } +// smart grid void ProcGetSmartGridState(PwrMsg *req) { - if (!SupportSmartGrid()) { - SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); - return; - } + CHECK_SUPPORT_SMART_GRID(); int *state = (int *)malloc(sizeof(int)); if (!state) { return; @@ -336,10 +494,7 @@ void ProcGetSmartGridState(PwrMsg *req) void ProcSetSmartGridState(PwrMsg *req) { - if (!SupportSmartGrid()) { - SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); - return; - } + CHECK_SUPPORT_SMART_GRID(); int ret = PWR_SUCCESS; do { if (req->head.dataLen != sizeof(int) || !req->data) { @@ -364,10 +519,7 @@ void ProcSetSmartGridState(PwrMsg *req) void ProcGetSmartGridProcs(PwrMsg *req) { - if (!SupportSmartGrid()) { - SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); - return; - } + CHECK_SUPPORT_SMART_GRID(); if (req->head.dataLen < sizeof(PWR_PROC_SMART_GRID_LEVEL) || !req->data) { SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); return; @@ -393,10 +545,7 @@ void ProcGetSmartGridProcs(PwrMsg *req) void ProcSetSmartGridProcsLevel(PwrMsg *req) { - if (!SupportSmartGrid()) { - SendRspToClient(req, PWR_ERR_SMART_GRID_NOT_SURPPORTED, NULL, 0); - return; - } + CHECK_SUPPORT_SMART_GRID(); if (req->head.dataLen < sizeof(PWR_PROC_SmartGridProcs) || !req->data) { SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); return; @@ -404,3 +553,37 @@ void ProcSetSmartGridProcsLevel(PwrMsg *req) PWR_PROC_SmartGridProcs *sgProcs = (PWR_PROC_SmartGridProcs *)req->data; SendRspToClient(req, WriteSmartGridProcsLevel(sgProcs), NULL, 0); } + +void ProcGetSmartGridGov(PwrMsg *req) +{ + CHECK_SUPPORT_SMART_GRID(); + size_t size = sizeof(PWR_PROC_SmartGridGov); + PWR_PROC_SmartGridGov *sgGov = (PWR_PROC_SmartGridGov *)malloc(size); + if (!sgGov) { + SendRspToClient(req, PWR_ERR_SYS_EXCEPTION, NULL, 0); + return; + } + bzero(sgGov, size); + int ret = ReadSmartGridGov(sgGov); + if (ret != PWR_SUCCESS) { + free(sgGov); + SendRspToClient(req, ret, NULL, 0); + } else { + SendRspToClient(req, ret, (char *)sgGov, size); + } +} + +void ProcSetSmartGridGov(PwrMsg *req) +{ + CHECK_SUPPORT_SMART_GRID(); + if (req->head.dataLen < sizeof(PWR_PROC_SmartGridGov) || !req->data) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + PWR_PROC_SmartGridGov *sgGov = (PWR_PROC_SmartGridGov *)req->data; + if (sgGov->sgAgentState != PWR_ENABLE && sgGov->sgAgentState != PWR_DISABLE) { + SendRspToClient(req, PWR_ERR_INVALIDE_PARAM, NULL, 0); + return; + } + SendRspToClient(req, WriteSmartGridGov(sgGov), NULL, 0); +} diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index e321f65..eb79626 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -476,6 +476,7 @@ static OptToFunct g_optToFunct[] = { {CPU_GET_FREQ_ABILITY, GetCpuFreqAbility}, {CPU_GET_FREQ_RANGE, GetCpuFreqRange}, {CPU_SET_FREQ_RANGE, SetCpuFreqRange}, + {PROC_QUERY_PROCS, ProcQueryProcs}, {PROC_GET_WATT_STATE, ProcGetWattState}, {PROC_SET_WATT_STATE, ProcSetWattState}, {PROC_GET_WATT_ARRTS, procGetWattAttrs}, @@ -486,7 +487,9 @@ static OptToFunct g_optToFunct[] = { {PROC_GET_SMART_GRID_STATE, ProcGetSmartGridState}, {PROC_SET_SMART_GRID_STATE, ProcSetSmartGridState}, {PROC_GET_SMART_GRID_PROCS, ProcGetSmartGridProcs}, - {PROC_SET_SMART_GRID_PROCS_LEVEL, ProcSetSmartGridProcsLevel} + {PROC_SET_SMART_GRID_PROCS_LEVEL, ProcSetSmartGridProcsLevel}, + {PROC_GET_SMART_GRID_GOV, ProcGetSmartGridGov}, + {PROC_SET_SMART_GRID_GOV, ProcSetSmartGridGov}, }; static void ProcessReqMsg(PwrMsg *req) diff --git a/pwrapis/src/utils.c b/pwrapis/src/utils.c index 8d4001b..ec9f6d2 100644 --- a/pwrapis/src/utils.c +++ b/pwrapis/src/utils.c @@ -30,8 +30,6 @@ #include #include #include -#include -#include static struct timeval GetCurTv(void) { @@ -957,7 +955,7 @@ int ReadFile(const char *strInfo, char *buf, int bufLen) return 0; } -int WriteFile(const char *strInfo, char *buf, int bufLen) +int WriteFile(const char *strInfo, const char *buf, int bufLen) { char realPath[MAX_FULL_NAME] = {0}; int ret = NormalizeAndVerifyFilepath(strInfo, realPath); @@ -1003,7 +1001,7 @@ int WriteIntToFile(const char *path, int content) { char buff[STR_LEN_FOR_INT] = {0}; if (sprintf(buff, "%d", content) < 0) { - return PWR_ERR_FILE_SPRINTF_FIILED; + return PWR_ERR_FILE_SPRINTF_FAILED; } return WriteFile(path, buff, strlen(buff)); } @@ -1051,7 +1049,7 @@ int GetSockoptFromOS(const pid_t pid, UnixCredOS *credOS) { char credCmd[PWR_MAX_NAME_LEN]; const char s[] = "ps -eo pid,uid,gid,user | grep "; - if (sprintf(credCmd, "%s%d", s, pid) < 0) return PWR_ERR_FILE_SPRINTF_FIILED; + if (sprintf(credCmd, "%s%d", s, pid) < 0) return PWR_ERR_FILE_SPRINTF_FAILED; FILE *fp = popen(credCmd, "r"); if (fp == NULL) { return PWR_ERR_FILE_OPEN_FAILED; -- Gitee