From 0a5dd385084921685809cc92f02cea131d80c24f Mon Sep 17 00:00:00 2001 From: wuhaotian <694496640@qq.com> Date: Fri, 25 Nov 2022 17:15:15 +0800 Subject: [PATCH] Add cpufreq ability get function --- common/inc/pwrdata.h | 3 +- pwrapic/test/demo_main.c | 6 +- pwrapis/inc/cpuservice.h | 1 + pwrapis/inc/utils.h | 1 + pwrapis/src/cpuservice.c | 130 +++++++++++++++++++++++++++++++++++++-- pwrapis/src/server.c | 3 + 6 files changed, 136 insertions(+), 8 deletions(-) diff --git a/common/inc/pwrdata.h b/common/inc/pwrdata.h index 087a8a2..a3b9e6e 100644 --- a/common/inc/pwrdata.h +++ b/common/inc/pwrdata.h @@ -31,6 +31,7 @@ #define CPU_IDLE_COLUMN 4 #define DECIMAL 10 #define CONVERSION 1000 +#define MAX_CPU_ID_WIDTH 5 #define MAX_CPU_DMA_LATENCY 2000000000 #define MAX_DISK_LIST_LEN 128 @@ -139,7 +140,7 @@ typedef enum PWR_CPU_FREQ_GOV { typedef struct PWR_CPU_FreqAbility { char curDriver[MAX_ELEMENT_NAME_LEN]; int avGovNum; - int avGovList[MAX_GOV_NUM][MAX_ELEMENT_NAME_LEN]; + char avGovList[MAX_GOV_NUM][MAX_ELEMENT_NAME_LEN]; int freqDomainNum; int freqDomainStep; char freqDomain[0]; diff --git a/pwrapic/test/demo_main.c b/pwrapic/test/demo_main.c index 5811283..adefd7b 100644 --- a/pwrapic/test/demo_main.c +++ b/pwrapic/test/demo_main.c @@ -21,7 +21,7 @@ #define MAIN_LOOP_INTERVAL 5 #define TEST_FREQ 2400 -#define TEST_CORE_NUM 96 +#define TEST_CORE_NUM 128 #define AVG_LEN_PER_CORE 5 #define TEST_CPU_DMA_LATENCY 2000 #define TASK_INTERVAL 1000 @@ -177,7 +177,7 @@ static void TEST_PWR_CPU_GetPerfData(void) static void TEST_PWR_CPU_GetFreqAbility(void) { int ret = 0; - int len = sizeof(PWR_CPU_FreqAbility) + AVG_LEN_PER_CORE * TEST_CORE_NUM; + int len = sizeof(PWR_CPU_FreqAbility) + AVG_LEN_PER_CORE * TEST_CORE_NUM * sizeof(int); PWR_CPU_FreqAbility *freqAbi = (PWR_CPU_FreqAbility *)malloc(len); if (!freqAbi) { return; @@ -299,7 +299,7 @@ int main(int argc, const char *args[]) TEST_PWR_CPU_GetPerfData(); // PWR_CPU_GetFreqAbility - // TEST_PWR_CPU_GetFreqAbility(); + TEST_PWR_CPU_GetFreqAbility(); // PWR_CPU_GetFreqGovernor PWR_CPU_SetFreqGovernor TEST_PWR_CPU_SetAndGetFreqGov(); diff --git a/pwrapis/inc/cpuservice.h b/pwrapis/inc/cpuservice.h index adac368..c767c8e 100644 --- a/pwrapis/inc/cpuservice.h +++ b/pwrapis/inc/cpuservice.h @@ -27,5 +27,6 @@ int PerfDataRead(PWR_CPU_PerfData *perfData); int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum); void GetCpuFreqGovernor(PwrMsg *req); void SetCpuFreqGovernor(PwrMsg *req); +void GetCpuFreqAbility(PwrMsg *req); int GetCpuCoreNumber(void); #endif diff --git a/pwrapis/inc/utils.h b/pwrapis/inc/utils.h index 7af85bd..e74b506 100644 --- a/pwrapis/inc/utils.h +++ b/pwrapis/inc/utils.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "config.h" #define DIR_ENTRY 4 diff --git a/pwrapis/src/cpuservice.c b/pwrapis/src/cpuservice.c index e0d9b27..fbfc7c8 100644 --- a/pwrapis/src/cpuservice.c +++ b/pwrapis/src/cpuservice.c @@ -193,9 +193,13 @@ int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum) const char usage[] = "cat /proc/stat"; unsigned long paras[2][CPU_USAGE_COLUMN]; FILE *fp1 = popen(usage, "r"); + if (fp1 == NULL) { + return ERR_COMMON; + } usleep(LATENCY); FILE *fp2 = popen(usage, "r"); - if (fp1 == NULL || fp2 == NULL) { + if (fp2 == NULL) { + pclose(fp1); return ERR_COMMON; } char buf1[MAX_STRING_LEN] = {0}; @@ -204,9 +208,13 @@ int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum) rstData->coreNum = coreNum; while (i < coreNum + 1) { if (fgets(buf1, sizeof(buf1) - 1, fp1) == NULL) { + pclose(fp1); + pclose(fp2); return ERR_COMMON; } if (fgets(buf2, sizeof(buf2) - 1, fp2) == NULL) { + pclose(fp1); + pclose(fp2); return ERR_COMMON; } if (UsageToLong(buf1, paras[0], i) != UsageToLong(buf2, paras[1], i)) { @@ -310,6 +318,30 @@ static int CheckPolicys(PWR_CPU_CurFreq *target, int len) return ERR_COMMON; } +static int AllGovernorsRead(char (*govList)[MAX_ELEMENT_NAME_LEN], int *govNum) +{ + char buf[MAX_ELEMENT_NAME_LEN * MAX_GOV_NUM] = {0}; + const char govInfo[] = "/sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors"; + int fd = open(govInfo, O_RDONLY); + if (fd == -1) { + return 1; + } + if (read(fd, buf, MAX_ELEMENT_NAME_LEN * MAX_GOV_NUM - 1) <= 0) { + close(fd); + return 1; + } + close(fd); + DeleteChar(buf, '\n'); + char *temp = strtok(buf, " "); + *govNum = 0; + while (temp != NULL) { + DeleteChar(temp, ' '); + StrCopy(govList[(*govNum)++], temp, MAX_ELEMENT_NAME_LEN); + temp = strtok(NULL, " "); + } + return 0; +} + static int CheckAvailableGovernor(char *gov, char *policys) { char *checkGovInfo = malloc(strlen(gov) + MAX_NAME_LEN); @@ -348,7 +380,7 @@ static int CheckAvailableGovernor(char *gov, char *policys) return 1; } -int GovernorRead(char *rstData) +int CurrentGovernorRead(char *rstData) { FILE *fp = NULL; char govInfo[] = "cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor"; @@ -472,6 +504,69 @@ static int FreqSet(PWR_CPU_CurFreq *target, int len) return SUCCESS; } +static int FreqDriverRead(char *buf, int bufLen) +{ + const char driverInfo[] = "/sys/devices/system/cpu/cpufreq/policy0/scaling_driver"; + int fd = open(driverInfo, O_RDONLY); + if (fd == -1) { + return 1; + } + if (read(fd, buf, bufLen - 1) <= 0) { + close(fd); + return 1; + } + close(fd); + DeleteChar(buf, '\n'); + buf[strlen(buf) - 1] = '\0'; + return 0; +} + +static int FreqDomainRead(char *buf, char (*policys)[MAX_ELEMENT_NAME_LEN], int domainNum, int step) +{ + char domainInfo[MAX_NAME_LEN] = {0}; + char domainbuf[MAX_CPU_LIST_LEN] = {0}; + char temp[MAX_ELEMENT_NAME_LEN] = {0}; + char s1[] = "/sys/devices/system/cpu/cpufreq/"; + char s2[] = "/affected_cpus"; + int i; + for (i = 0; i < domainNum; i++) { + StrCopy(domainInfo, s1, MAX_NAME_LEN); + strncat(domainInfo, policys[i], strlen(policys[i])); + strncat(domainInfo, s2, strlen(s2)); + int fd = open(domainInfo, O_RDONLY); + if (fd == -1) { + close(fd); + return 1; + } + if (read(fd, domainbuf, MAX_CPU_LIST_LEN - 1) <= 0) { + close(fd); + return 1; + } + close(fd); + DeleteChar(domainbuf, '\n'); + // convert policys to int + StrCopy(temp, policys[i], MAX_ELEMENT_NAME_LEN); + DeleteSubstr(temp, "policy"); + buf[i * step] = atoi(temp); + StrCopy(buf + i * step + sizeof(int), domainbuf, step - sizeof(int)); + } + return 0; +} + + +static int FreqAbilityRead(PWR_CPU_FreqAbility *rstData, char (*policys)[MAX_ELEMENT_NAME_LEN]) +{ + if (FreqDriverRead(rstData->curDriver, MAX_ELEMENT_NAME_LEN) != SUCCESS) { + return ERR_COMMON; + } + if (AllGovernorsRead(rstData->avGovList, &(rstData->avGovNum)) != SUCCESS) { + return ERR_COMMON; + } + if (FreqDomainRead(rstData->freqDomain, policys, rstData->freqDomainNum, rstData->freqDomainStep) != SUCCESS) { + return ERR_COMMON; + } +} + void GetCpuinfo(PwrMsg *req) { if (!req) { @@ -526,7 +621,7 @@ void GetCpuFreqGovernor(PwrMsg *req) if (!rstData) { return; } - int rspCode = GovernorRead(rstData); + int rspCode = CurrentGovernorRead(rstData); SendRspToClient(req, rspCode, (char *)rstData, sizeof(char) * MAX_ELEMENT_NAME_LEN); } @@ -572,7 +667,7 @@ void SetCpuFreq(PwrMsg *req) char currentGov[MAX_ELEMENT_NAME_LEN]; PWR_CPU_CurFreq *target = (PWR_CPU_CurFreq *)req->data; int rspCode = 0; - if (GovernorRead(currentGov) == 1) { + if (CurrentGovernorRead(currentGov) != SUCCESS) { rspCode = ERR_COMMON; } else if (CheckPolicys(target, len) == 1 || strcmp(currentGov, "userspace") != 0) { rspCode = ERR_INVALIDE_PARAM; @@ -585,6 +680,33 @@ void SetCpuFreq(PwrMsg *req) } } +void GetCpuFreqAbility(PwrMsg *req) +{ + if (!req) { + return; + } + Logger(DEBUG, MD_NM_SVR_CPU, "Get GetCpuFreqAbility Req. seqId:%u, sysId:%d", req->head.seqId, req->head.sysId); + int coreNum = GetCpuCoreNumber(); + char policys[MAX_CPU_LIST_LEN][MAX_ELEMENT_NAME_LEN]; + bzero(policys, sizeof(policys)); + int poNum; + if (GetPolicys(policys, &poNum) != SUCCESS) { + int rspCode = ERR_COMMON; + SendRspToClient(req, rspCode, NULL, 0); + return; + } + int step = (coreNum / poNum) * MAX_CPU_ID_WIDTH + sizeof(int); + PWR_CPU_FreqAbility *rstData = malloc(sizeof(PWR_CPU_FreqAbility) + step * poNum); + if (!rstData) { + return; + } + bzero(rstData, sizeof(PWR_CPU_FreqAbility) + step * poNum); + rstData->freqDomainNum = poNum; + rstData->freqDomainStep = step; + int rspCode = FreqAbilityRead(rstData, policys); + SendRspToClient(req, rspCode, (char *)rstData, sizeof(PWR_CPU_FreqAbility) + step * poNum); +} + // 总CPU核数 int GetCpuCoreNumber(void) { diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index dc54714..88ec849 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -375,6 +375,9 @@ static void ProcessReqMsg(PwrMsg *req) case CPU_SET_CUR_FREQ: SetCpuFreq(req); break; + case CPU_GET_FREQ_ABILITY: + GetCpuFreqAbility(req); + break; default: break; } -- Gitee