使用powerapi进行开发

下载源码(可选)

源码下载:https://gitee.com/openeuler/powerapi

源码中部分接口还处于实验阶段,并未发布,代码中使用 RELEASE_MODE 对接口是否正式发布进行了隔离。

当前已发布接口参考源码库中的 API 文档。

安装软件包

使用以下命令安装 powerapi-devel 软件包,使用提供的接口进行开发。

sh
yum install powerapi-devel

基本流程

查询类接口调用只需要注册,设置类接口调用前除了注册还需要请求控制权。按业务场景分,业务流程如下:
离散型感知类业务场景:设置日志回调 -> 注册 -> 查询接口调用 -> 注销
配置类业务场景:设置日志回调 -> 注册 -> 请求控制权 -> 配置接口调用 -> 释放控制权 -> 注销

powerapi接口

通用接口

设置日志回调函数

接口定义:PWR_API int PWR_SetLogCallback(void(LogCallback)(int level, const char *fmt, va_list vl))
接口描述:设置日志打印回调,设置后,powerapi库将回调LogCallBack函数打印日志。如不设置,默认打印到控制台。该接口可在注册前调用。

参数描述:

参数类型描述
LogCallBackvoid(*)日志打印回调函数指针

返回值:

类型描述
int返回码
0:成功
4:失败,回调函数指针为空

设置服务端信息

接口定义:PWR_API int PWR_SetServerInfo(const char* socketPath)
接口描述:该接口用于设置unix domain socket通信服务端地址信息。
参数描述:

参数类型描述
socketPathconst char*服务端地址路径信息

返回值:

类型描述
int返回码
0:成功
4:失败,回调函数指针为空

注:
服务端sock文件默认路径为/etc/sysconfig/pwrapis/pwrserver.sock,若在pwrapis配置文件中修改默认路径,则需要保证目录权限为755,而文件权限为722。 修改路径后需要在注册前通过该接口来告知so修改后的路径,否则连接将失败。


注册

接口定义:PWR_API int PWR_Register(void)
接口描述:用于注册到powerapi service。
参数描述:无参数
返回值:

类型描述
int返回码
0:成功
1:失败,初始化sock客户端失败

注销

接口定义:PWR_API int PWR_UnRegister(void)
接口描述:用于从服务端注销。
参数描述:无参数
返回值:

类型描述
int返回码
0:注销成功

请求接管能效控制权

接口定义:PWR_API int PWR_RequestControlAuth(void)
接口描述:该接口用于请求对系统能效控制权进行接管。上层应用接管后,系统不会自动进行能效调控,否则会自动进行能效调控。
参数描述:无参数
返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

放弃能效控制权

接口定义:PWR_API int PWR_ReleaseControlAuth(void)
接口描述:该接口用于释放对系统能效的控制权。
参数描述:无参数
返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置PowerAPI客户端的socket文件路径

接口定义:int PWR_SetClientSockPath(const char* socketPath)

接口描述:该接口用于设置PowerAPI客户端的socket文件路径。 客户端sock文件默认路径为程序当前用户所在home目录(如/home/user/pwrclient.sock)。

参数描述:

参数类型描述
socketPathconst char*客户端socket文件路径

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 该接口必须在注册前调用才能让新设置的socket文件路径生效。
  2. 调用该接口设置的路径必须是存在并且当前用户有读写权限的路径。

设置数据采集任务的回调函数

接口定义:int PWR_SetMetaDataCallback(void(MetaDataCallback)(const PWR_COM_CallbackData *callbackData))

接口描述:Powerapi目前支持部分功耗相关数据采集,此接口用户可设置回调函数,在回调函数中处理这些数据。

参数描述:

参数类型描述
MetaDataCallbackvoid(*)采集数据的回调函数指针

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 该接口必须在启动采集任务前进行设置,否则不处理数据。
  2. 回调函数中应该尽量轻量化,不宜做过多逻辑处理,尤其是比较费时的逻辑处理。

创建数据采集任务

接口定义:int PWR_CreateDcTask(const PWR_COM_BasicDcTaskInfo *basicDcTaskInfo)

接口描述:该接口用于创建周期性数据采集任务,目前暂时只支持两种类型的数据采集:CPU使用率和CPU性能数据。

参数描述:

参数类型描述
basicDcTaskInfoPWR_COM_BasicDcTaskInfo*数据采集任务基础信息,包含采集的周期、采集数据类型
PWR_COM_BasicDcTaskInfo 结构体具体定义,可以查看头文件pwrdata.h中具体定义

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 创建的采集任务是以数据类型为单位,多次创建同一数据类型的采集任务,内部是只有一个这个数据类型的采集任务。

删除数据采集任务

接口定义:int PWR_DeleteDcTask(PWR_COM_COL_DATATYPE dataType)

接口描述:该接口根据数据类型删除数据采集任务。

参数描述:

参数类型描述
dataTypePWR_COM_COL_DATATYPE数据采集的数据类型

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置事件回调函数

接口定义:int PWR_SetEventCallback(void(EventCallback)(const PWR_COM_EventInfo* eventInfo))

接口描述:PowerAPI内部定义了一些事件,用户可以设置回调函数,在回调函数中处理这些事件。目前支持认证失败和控制权被抢占两个事件。

参数描述:

参数类型描述
EventCallbackvoid(*)事件回调函数指针

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 回调函数的实现应轻量化,不宜做过多逻辑处理,尤其是比较费时的逻辑处理,否则可能导致由于数据拥塞而丢失数据。

CPU

获取CPU信息

接口定义:PWR_API int PWR_CPU_GetInfo(PWR_CPU_Info *cpuInfo)
接口描述:获取CPU信息,包含CPU基础信息,NUMA信息。
参数描述:

参数类型描述
cpuinfoPWR_CPU_Info*CPU信息

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU使用率

接口定义:int PWR_CPU_GetUsage(PWR_CPU_Usage *usage, uint32_t bufferSize)

接口描述:获取CPU全部核心的平均使用率,以及每个核心分别的使用率。

参数描述:

参数类型描述
UsagePWR_CPU_Usage*CPU使用率信息
bufferSizeuint32_tCPU使用率信息内存块大小

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 该接口会阻塞当前线程500ms,如果是比较频繁的获取CPU使用率,建议采用任务方式,参见创建数据采集任务

获取CPU性能数据

接口定义:int PWR_CPU_GetPerfData(PWR_CPU_PerfData *perfData)

接口描述:获取CPU性能数据,实时获取CPU单指令平均LLC miss数和IPC(统计时长100ms)

参数描述:

参数类型描述
perfDataPWR_CPU_PerfData*CPU性能数据信息

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 该接口会阻塞当前线程100ms,如果是比较频繁的获取CPU性能数据,建议采用任务方式,参见创建数据采集任务

获取CPU Frequency能力

接口定义:PWR_API int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize)
参数描述:查询可用的CPUFreq调频域信息,可用governor和当前使用的CPUFreq驱动。

参数类型描述
freqAbiPWR_CPU_FreqAbility*CPUFreq能力信息
bufferSizeuint32_tfreqAbi内存块大小。
该内存块建议大小:
sizeof(PWR_CPU_FreqAbility)+CPU核心数*(sizeof(int)+5)
内存块太小,则只返回能容纳的调频域数据。

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU Frequency governor

接口定义:PWR_API int PWR_CPU_GetFreqGovernor(char gov[], uint32_t size)
接口描述:获取系统当前使用的CPUFreq调频器(默认获取第一个调频域的governor)。
参数描述:

参数类型描述
govchar[]governor的名称,最大长度31。
sizeuint32_t给定gov数组空间大小,需大于等于PWR_MAX_ELEMENT_NAME_LEN(32)。

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置CPU Frequency governor

接口定义:PWR_API int PWR_CPU_SetFreqGovernor(const char gov[])
接口描述:设置系统当前使用的CPUFreq调频器(设置时将所有调频域设置为输入的governor)。
参数描述:

参数类型描述
govchar[]governor的名称,最大长度31。
取值如:
conservative
ondemand
userspace
powersave
performance
schedutil
seep

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU Frequency governor所有属性值

接口定义:PWR_API int PWR_CPU_GetFreqGovAttrs(PWR_CPU_FreqGovAttrs *govAttrs)
接口描述:获取当前所使用的CPUFreq调频器的所有属性信息。
参数描述:

参数类型描述
govAttrsPWR_CPU_FreqGovAttrs*调频器属性信息

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU Frequency governor属性

接口定义:PWR_API int PWR_CPU_GetFreqGovAttr(PWR_CPU_FreqGovAttr *govAttr)
接口描述:获取当前使用的CPUFreq属性(系统将获取第一个调频域(policy0)当前使用的governor对应的属性)。
参数描述:

参数类型描述
govAttrsPWR_CPU_FreqGovAttrs*调频器属性信息

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置CPU Frequency governor属性

接口定义:PWR_API int PWR_CPU_SetFreqGovAttr(const PWR_CPU_FreqGovAttr *govAttr)
接口描述:设置当前使用的CPUFreq属性(系统将设置第一个调频域(policy0)当前使用的governor对应的属性)。
参数描述:

参数类型描述
govAttrsPWR_CPU_FreqGovAttrs*调频器属性信息。
需指定要设置的attr名称及其value。

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注:
不同的governor所支持的属性有所差异,governor所支持的属性一般在以下路径:/sys/devices/system/cpu/cpufreq/{gov}/,其中{gov}为当前使用的调频器名称。


获取CPU工作频率范围

接口定义:PWR_API int PWR_CPU_GetFreqRange(PWR_CPU_FreqRange *freqRange)
接口描述:获取CPU工作频率范围(默认获取第一个调频域的工作频率范围)。
参数描述:

参数类型描述
freqRangePWR_CPU_FreqRange*所获取的工作频率范围

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置CPU工作频率范围

接口定义:PWR_API int PWR_CPU_SetFreqRange(const PWR_CPU_FreqRange *freqRange)
接口描述:设置CPU工作频率范围(把所有调频域设置成指定的频率范围)。
参数描述:

参数类型描述
freqRangePWR_CPU_FreqRange*设置的工作频率范围

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU当前频率

接口定义:PWR_API int PWR_CPU_GetFreq(PWR_CPU_CurFreq curFreq[], uint32_t *num, int spec)
接口描述:获取调频域的当前频率。
参数描述:

参数类型描述
curFreqPWR_CPU_CurFreq[]表示要查询的policy当前调频域的频率信息。
spec=1时需要设置对应成员的policyId。
输出调频域的当前频率。
numuint32_t *curFreq数组空间长度,代表要查询的policy的个数。
输出时为系统实际返回的有效数据长度(表现为实际policy的个数与输入num的较小值)。
specint释放获取特定某个或某几个调频域的信息。
0:否
1:是,此时需要在curFreq成员中设定具体的调频域所对应的policyId,如32,64等。

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置CPU当前频率

接口定义:PWR_API int PWR_CPU_SetFreq(const PWR_CPU_CurFreq curFreq[], uint32_t num)
接口描述:设置调频域的工作频率(CPUFreq governor为userspace时才可设置)。
参数描述:

参数类型描述
curFreqPWR_CPU_CurFreq[]要设置的调频域及其频率列表。
numuint32_tcurFreq数组空间长度,即调整policy的个数。

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU休眠能力和状态信息

接口定义:PWR_API int PWR_CPU_GetIdleInfo(PWR_CPU_IdleInfo *idleInfo)
接口描述:获取CPUIdele能力和状态信息。
参数描述:

参数类型描述
idleInfoPWR_CPU_IdleInfo*CPUIdle能力和状态信息

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU休眠governor

接口定义:PWR_API int PWR_CPU_GetIdleGovernor(char idleGov[], uint32_t size)
接口描述:获取CPU休眠模式。
参数描述:

参数类型描述
idleGovchar[]governor名称
sizeuint32_tidleGov缓存区大小,最小值PWR_MAX_ELEMENT_NAME_LEN(32)

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置CPU休眠governor

接口定义:PWR_API int PWR_CPU_SetIdleGovernor(const char idleGov[])
接口描述:设置CPU休眠模式。
参数描述:

参数类型描述
idleGovchar[]governor名称,如:
ladder
menu
teo
haltpoll

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取CPU&DMA时延

接口定义:PWR_API int PWR_CPU_DmaGetLatency(int *latency)
接口描述:获取CPU&DMA可忍受时延。
参数描述:

参数类型描述
latencyint*时延(单位:us)
取值范围:[0, 2000000000]

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置CPU&DMA时延

接口定义:PWR_API int PWR_CPU_DmaSetLatency(int latency)
接口描述:设置CPU&DMA可忍受时延。
参数描述:

参数类型描述
latencyint*时延(单位:us)。取值范围:[0,2000000000]

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注:
不同的C-state,被唤醒所需时间不同,睡得越深,唤醒时延越大,因而系统在进入C-state前会判断CPU&DMA latency,如果对应C-state的时延大于CPU&DMA latency,则不会进入C-state。
各个C-state唤醒时延参考(单位:us)

C-state namelatency
C0 POLL0
C12
C1E10
C340
C6133
C7S166
C8300
C9600
C102600

系统类接口

设置整系统电源状态

接口定义:int PWR_SYS_SetPowerState(int powerState)

接口描述:

  1. 该接口用于进行系统级休眠

参数描述:

参数类型描述
powerStateint1 - 休眠RAM
2 - 休眠Disk

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 系统进入休眠后,如果重新激活系统,需要通过其他方式(如通过BMC物理端口的IPMI接口)远程激活系统。

获取系统当前功耗信息

接口定义:int PWR_SYS_GetRtPowerInfo(PWR_SYS_PowerInfo * powerInfo)

接口描述:

  1. 查询系统实时能耗信息,包括整机当前功率、CPU当前功率、内存当前功率

参数描述:

参数类型描述
powerInfoPWR_SYS_PowerInfo包含sysPower/cpuPower/memPower三部分,这里是最终获取到功耗信息的出参内存地址

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. ARM平台暂时无法获取到CPU功耗信息和内存功耗信息

HBM类接口

查询HBM能力和运行模式

接口定义:int PWR_HBM_GetSysState(PWR_HBM_SYS_STATE *state) 接口描述:

  1. 查询当前设备是否支持HBM,并查询HBM当前运行模式为flat模式、还是cache模式或混合模式。
  2. HBM一般支持flat和cache两种运行模式,前者OS会将HBM作为cpuless的numa节点使用,而后者当做LLC使用。两种方式都支持进行上下电操作。

参数描述:

参数类型描述
statePWR_HBM_SYS_STATEHBM系统状态,包括是否支持HBM以及当前运行模式

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

关闭/启动所有HBM

接口定义:int PWR_HBM_SetAllPwrState(int state)

接口描述:

  1. 关闭/启动所有HBM,包括cache模式和flat模式。

参数描述:

参数类型描述
stateint0:关闭所有HBM
1:启动所有HBM

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

proc进程相关接口

根据关键字查找任务

接口定义: int PWR_PROC_QueryProcs(const char *keywords, pid_t procs[], uint32_t *num)

接口描述:

  1. 根据关键字查找进程,并返回进程列表。

参数描述:

参数类型描述
keywordsconst char*关键字列表。多个关键字用"|"隔开,例如 "nginx|mysql", 注意,空格会被认为是关键字一部分
输入NULL或空字符串时表示查询所有用户态的任务
不包含结束符'\0',长度范围[0,999]
procspid_t*进程列表
numuint32_t*进程列表长度

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

查询瓦特调度开关状态

瓦特调度说明:

  1. 瓦特调度是一种为节省功耗,在内核采取的调度机制。在负载比较低时,系统会将任务集中在部分numa节点,为其他节点创造进入低功耗的条件。随着负载变化,系统会动态地扩缩用于完成任务的numa节点。
  2. 约束:当前瓦特调度在x86内核中是默认是不开启,如果需要开启需要QOS_SCHED_DYNAMIC_AFFINITY和QOS_SCHED_SMART_GRID这两个配置,重新编译内核并替换内核。

接口定义: int PWR_PROC_GetWattState(int *state)

接口描述:

  1. 查询瓦特调度开关状态。

参数描述:

参数类型描述
stateint*瓦特调度开关状态,0表示关闭,1表示打开

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置瓦特调度开关

接口定义: int PWR_PROC_SetWattState(int state)

接口描述:

  1. 设置瓦特调度开关状态。

参数描述:

参数类型描述
stateint瓦特调度开关状态,0表示关闭,1表示打开

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置瓦特调度第一调度域

接口定义: int PWR_PROC_SetWattFirstDomain(int cpuId)

接口描述:

  1. 该接口用于指定瓦特调度使用的第一个调度域。
  2. 默认情况下,在启动瓦特调度时,系统选择最空闲的NUMA node作为第一个调度域(level0),后续在扩缩算力时,根据NUMA node的亲和性进行扩缩(例如:对于2颗CPU芯片,4个NUMA node的设备,node2为第一个调度域时,优先会扩展同一个socket下的node3, 然后是另一个socket下的node1和node0)。
  3. 有些情况下,由于IRQ亲和性等原因,为了保证性能,需要指定第一个调度域为IRQ所在的NUMA node。

参数描述:

参数类型描述
cpuIdint设置cpuId所在域为第一调度域

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 设置的CPU是在线和可调度状态。
  2. 瓦特调度需要是关闭状态。

获取瓦特调度属性

瓦特调度属性说明:

参数名取值含义实际路径
scaleThreshold[0, 100] 默认85扩缩资源的阈值。 即CPU利用率达到该阈值后,瓦特调度自动扩展计算资源。
属性设置时,该值为0,表示不设置该属性
/proc/sys/kernel/sched_util_low_pct
domainMask4个numa node场景(有Level0-3共四个等级,分别表示使用1/2/3/4个numa node),默认值为15,即二进制1111,表示打开所有资源等级。
如果不想打开Level2(Level1不满足算力时,直接扩展为level3),则可以设置为“1011”,即11
资源域掩码。
属性设置时,该值为0,表示不设置该属性
/sys/fs/cgroup/cpu/watt_sched/cpu.affinity_domain_mask
scaleInterval[0,3600000] 默认2000ms系统使用该值作为设置定时器,触发瓦特调度扩缩算力资源。
属性设置时,该值为0,表示不设置该属性
/sys/fs/cgroup/cpu/watt_sched/cpu.affinity_period_ms

接口定义: int PWR_PROC_GetWattAttrs(PWR_PROC_WattAttrs *wattAttrs)

接口描述:

  1. 获取瓦特调度属性。

参数描述:

参数类型描述
wattAttrsPWR_PROC_WattAttrs瓦特调度属性

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置瓦特调度属性

接口定义: int PWR_PROC_SetWattAttrs(PWR_PROC_WattAttrs *wattAttrs)

接口描述:

  1. 设置瓦特调度属性。

参数描述:

参数类型描述
wattAttrsPWR_PROC_WattAttrs瓦特调度属性

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

查询当前瓦特调度任务列表

接口定义:int PWR_PROC_GetWattProcs(pid_t wattProcs[], uint32_t *num)

接口描述:

  1. 查询有哪些任务已经加入到瓦特调度中

参数描述:

参数类型描述
wattProcspid_t瓦特调度任务列表,最大5000个。需要和num个数匹配
numuint32_t瓦特调度任务列表数量,最大值5000

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

添加瓦特调度任务

接口定义:int PWR_PROC_AddWattProcs(const pid_t wattProcs[], uint32_t num)

接口描述:

  1. 添加任务到瓦特调度中

参数描述:

参数类型描述
wattProcspid_t瓦特调度任务列表,最大5000个。需要和num个数匹配
numuint32_t瓦特调度任务列表数量,最大5000

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 子进程会继承父进程/线程的瓦特调度属性。即如果父进程/线程已经在瓦特调度组,则生成的子进程/线程也会在该调度组

删除瓦特调度任务

接口定义:int PWR_PROC_DelWattProcs(const pid_t wattProcs[], uint32_t num)

接口描述:

  1. 删除任务从瓦特调度中

参数描述:

参数类型描述
wattProcspid_t瓦特调度任务列表
numuint32_t瓦特调度任务列表数量,最大5000

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

查询smart_grid开关状态

smart_grid说明:

  1. smart_grid智能网格是一种为节省功耗,在瓦特调度的基础上内核的一种CPU资源划分和标识方法。smart_grid可以将算力资源和任务划分不同等级,高等级任务用高算力来运行,低等级任务用低算力运行。
  2. 为使smart_grid生效,需要先开启smart_grid,并批量设置任务的smart_grid_level。
  3. openEuler 22.03 SP2及以上版本才支持smart_grid功能。
  4. 开启smart_grid前,开启瓦特调度才能让smart_grid功能生效。

接口定义:int PWR_PROC_GetSmartGridState(int *state)

接口描述:

  1. 查询smart_grid开关状态

参数描述:

参数类型描述
stateint0:关闭
1:开启

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置smart_grid开关状态

接口定义:int PWR_PROC_SetSmartGridState(int state)

接口描述:

  1. 设置smart_grid开关状态

参数描述:

参数类型描述
stateint0:关闭
1:开启

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

根据smart_grid_level查询任务列表

smart_grid等级说明:

  1. 当前只支持两个等级:0-高等级, 1-低等级。
  2. 处于高等级的任务将会被调度到性能域,而处于低等级的任务将会被调度到能效域。
  3. 子进程/线程会继承父进程/线程的smart_grid等级属性。即如果父进程/线程的等级是0,则生成的子进程/线程等级也是0。
  4. 已经存在的子进程/线程不会随父进程/线程改变smart_grid等级属性。

接口定义:int PWR_PROC_GetSmartGridProcs(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC_SmartGridProcs *sgProcs)

接口描述:

  1. 根据smart_grid_level查询任务列表

参数描述:

参数类型描述
levelPWR_PROC_SMART_GRID_LEVEL0:高等级
1:低等级
sgProcsPWR_PROC_SmartGridProcs任务列表。
其中:procNum作为输入,指定procs空间所能存储的任务数量。
作为输出,标识实际返回的任务数量。

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

批量设置任务的smart_grid_level

接口定义:int PWR_PROC_SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs)

接口描述:

  1. 批量设置任务的smart_grid等级

参数描述:

参数类型描述
sgProcsPWR_PROC_SmartGridProcs任务列表

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取smart_grid的调频器

smart_gird调频器可设置参数:

参数名取值含义实际路径
sgAgentstate0或1smart_grid调频器状态。
smart_grid调频器状态为1时会覆盖cpufreq设置的governor
/sys/devices/system/cpu/cpufreq/smart_grid_governor_enable
sgLevel0Gov最大长度31,取值范围:conservative/ondemand/userspace/powersave/performance/schedutillevel0的调频器,需要smart_grid开启才有效/sys/devices/system/cpu/cpufreq/smart_grid_governor
sgLevel1Gov最大长度31,取值范围:conservative/ondemand/userspace/powersave/performance/schedutillevel1的调频器,需要smart_grid开启才有效/sys/devices/system/cpu/cpufreq/smart_grid_governor

接口定义:int PWR_PROC_GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov)

接口描述:

  1. 获取smart_grid的调频器

参数描述:

参数类型描述
sgGovPWR_PROC_SmartGridGov调频器参数

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置smart_grid的调频器

接口定义:int PWR_PROC_SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov)

接口描述:

  1. 设置smart_grid的调频器

参数描述:

参数类型描述
sgGovPWR_PROC_SmartGridGov调频器参数

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

获取服务的状态

接口定义:int PWR_PROC_GetServiceState(PWR_PROC_ServiceStatus *sStatus)

接口描述:

  1. 获取服务的状态

参数描述:

参数类型描述
statePWR_PROC_ServiceStatus服务的状态,有

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

设置服务的状态

接口定义:int PWR_PROC_SetServiceState(const PWR_PROC_ServiceState *sState)

接口描述:

  1. 设置服务的状态

参数描述:

参数类型描述
statePWR_PROC_ServiceState服务的状态,目前只支持停止(0)/开启(1)两种状态

返回值:

类型描述
int返回码
0:成功
其他值:失败,参见错误码

注意:

  1. 目前暂时只支持设置mpctool和eagle两个服务的状态。
  2. 设置服务状态前,需要安装mpctool或者eagle两个软件,分别对应python3-eagle-mpctooleagle软件包。
  3. mpctool目前只支持以下arm服务器机型,x86下无法使用
    1. Taishan200 2280(VD)
    2. Taishan200 Pro 2280
    3. Taishan200 2280v2

使用用例

将以下代码保存为powerapi_test.c

sh
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <pwrapic/powerapi.h>

#define MAIN_LOOP_INTERVAL 5
#define TEST_FREQ 2400
#define TEST_CORE_NUM 128
#define AVG_LEN_PER_CORE 5
#define TEST_CPU_DMA_LATENCY 2000
#define TASK_INTERVAL 1000
#define TASK_RUN_TIME 10
#define TEST_FREQ_RANGE_MIN 500
#define TEST_FREQ_RANGE_MAX 2500

static int g_run = 1;

static void PrintResult(char *function, int ret)
{
    int length = 24;
    printf("[TEST ]    ");
    printf("%-*s", length, function);
    printf(":");
    if (ret == PWR_SUCCESS) {
        printf("SUCCESS ret: %d\n", ret);
    } else {
        printf("ERROR   ret: %d\n", ret);
    }
}

enum {
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR
};

static const char *GetLevelName(int level)
{
    static char debug[] = "DEBUG";
    static char info[] = "INFO";
    static char warning[] = "WARNING";
    static char error[] = "ERROR";
    switch (level) {
        case DEBUG:
            return debug;
        case INFO:
            return info;
        case WARNING:
            return warning;
        case ERROR:
            return error;
        default:
            return info;
    }
}

void LogCallback(int level, const char *fmt, va_list vl)
{
    char logLine[4096] = {0};
    char message[4000] = {0};
    int length = 5;

    if (vsnprintf(message, sizeof(message) - 1, fmt, vl) < 0) {
        return;
    }

    printf("[");
    printf("%-*s", length, GetLevelName(level));
    printf("]    %s\n", message);
}

static void SignalHandler(int none)
{
    g_run = 0;
}

static void SetupSignal(void)
{
    // regist signal handler
    (void)signal(SIGINT, SignalHandler);
    (void)signal(SIGUSR1, SignalHandler);
    (void)signal(SIGUSR2, SignalHandler);
    (void)signal(SIGTERM, SignalHandler);
    (void)signal(SIGKILL, SignalHandler);
}
/************************** COMMON ************************/
static void TEST_PWR_SetLogCallback(void)
{
    int ret = -1;
    ret = PWR_SetLogCallback(LogCallback);
    PrintResult("PWR_SetLogCallback", ret);
}

static void TEST_PWR_SetServerInfo(void)
{
    int ret = -1;
    char str[] = "/etc/sysconfig/pwrapis/pwrserver.sock";
    ret = PWR_SetServerInfo(str);
    PrintResult("PWR_SetServerInfo", ret);
}

static void TEST_PWR_Register(void)
{
    while (PWR_Register() != PWR_SUCCESS) {
        sleep(MAIN_LOOP_INTERVAL);
        PrintResult("PWR_Register", PWR_ERR_COMMON);
        continue;
    }
    PrintResult("PWR_Register", PWR_SUCCESS);
}

static void TEST_PWR_RequestControlAuth(void)
{
    int ret = -1;
    ret = PWR_RequestControlAuth();
    PrintResult("PWR_RequestControlAuth", ret);
}
/************************** COMMON END************************/

/***************************** CPU ***************************/
static void TEST_PWR_CPU_GetInfo(void)
{
    int ret = -1;
    PWR_CPU_Info *info = (PWR_CPU_Info *)malloc(sizeof(PWR_CPU_Info));
    if (!info) {
        return;
    }
    bzero(info, sizeof(PWR_CPU_Info));
    ret = PWR_CPU_GetInfo(info);
    PrintResult("PWR_CPU_GetInfo", ret);
    printf("    arch: %s\n    coreNum: %d\n    maxFreq: %f\n    minFreq: %f\n    "
        "modelName: %s\n    numaNum: %d\n    threadsPerCore: %d\n", info->arch,
        info->coreNum, info->maxFreq, info->minFreq, info->modelName, info->numaNum,
        info->threadsPerCore);
    for (int i = 0; i < info->numaNum; i++) {
        printf("    numa node[%d]  cpuList: %s\n", info->numa[i].nodeNo, info->numa[i].cpuList);
    }
    free(info);
}

static void TEST_PWR_CPU_GetFreq(void)
{
    int ret = -1;
    int num = 0;
    int spec = 0;
    int i = 0;

    /**
     * Test 1: spec = 0, get all policy freq.
     * Set the num to the number of CPU cores
     * (it is possible that one kernel corresponds to one policy)
     */
    num = TEST_CORE_NUM;
    spec = 0;
    PWR_CPU_CurFreq cpuCurFreq1[num];
    bzero(cpuCurFreq1, num * sizeof(PWR_CPU_CurFreq));
    ret = PWR_CPU_GetFreq(cpuCurFreq1, &num, spec);
    PrintResult("1  PWR_CPU_GetFreq", ret);
    for (i = 0; i < num; i++) {
        printf("    policy[%d]: %lf\n", cpuCurFreq1[i].policyId, cpuCurFreq1[i].curFreq);
    }

    /**
     * Test 2: spec = 0 num = 2. get the previous 2 policies freq
     */
    ret = -1;
    // 2: previous 2 policies
    num = 2;
    spec = 0;
    PWR_CPU_CurFreq cpuCurFreq2[num];
    bzero(cpuCurFreq2, num * sizeof(PWR_CPU_CurFreq));
    ret = PWR_CPU_GetFreq(cpuCurFreq2, &num, spec);
    PrintResult("2  PWR_CPU_GetFreq", ret);
    for (i = 0; i < num; i++) {
        printf("    policy[%d]: %lf\n", cpuCurFreq2[i].policyId, cpuCurFreq2[i].curFreq);
    }

    /**
     * Test 3: spec = 1, get the two target policy freq
     */
    ret = -1;
    // 2: previous 2 policies
    num = 2;
    spec = 1;
    PWR_CPU_CurFreq cpuCurFreq3[num];
    bzero(cpuCurFreq3, num * sizeof(PWR_CPU_CurFreq));
    cpuCurFreq3[0].policyId = 0;
    // 32 : the Id of the second policy.
    cpuCurFreq3[1].policyId = 32;
    ret = PWR_CPU_GetFreq(cpuCurFreq3, &num, spec);
    PrintResult("3  PWR_CPU_GetFreq", ret);
    for (i = 0; i < num; i++) {
        printf("    policy[%d]: %lf\n", cpuCurFreq3[i].policyId, cpuCurFreq3[i].curFreq);
    }
}

static void TEST_PWR_CPU_SetFreq(void)
{
    int ret = -1;
    int num = 1;
    PWR_CPU_CurFreq cpuCurFreq[num];
    bzero(cpuCurFreq, num * sizeof(PWR_CPU_CurFreq));
    cpuCurFreq[0].policyId = 0;
    cpuCurFreq[0].curFreq = TEST_FREQ;
    ret = PWR_CPU_SetFreq(cpuCurFreq, num);
    PrintResult("PWR_CPU_SetFreq", ret);

    int spec = 1;
    bzero(cpuCurFreq, num * sizeof(PWR_CPU_CurFreq));
    cpuCurFreq[0].policyId = 0;
    ret = PWR_CPU_GetFreq(cpuCurFreq, &num, spec);
    printf("    current policy[%d]: %lf\n", cpuCurFreq[0].policyId, cpuCurFreq[0].curFreq);
}
/*************************** CPU END *************************/

int main(int argc, const char *args[])
{
    /********** Common **********/
    TEST_PWR_SetServerInfo();
    TEST_PWR_SetLogCallback();
    TEST_PWR_Register();
    TEST_PWR_RequestControlAuth();

    /************ CPU ***********/
    TEST_PWR_CPU_GetInfo();
    TEST_PWR_CPU_GetFreq();
    TEST_PWR_CPU_SetFreq();

    PWR_ReleaseControlAuth();
    PWR_UnRegister();
    return 0;
}

使用gcc编译:

sh
gcc powerapi_test.c -o powerapi_test -lpwrapi

运行查看结果:

sh
./powerapi_test