使用powerapi进行开发
下载源码(可选)
源码下载:https://gitee.com/openeuler/powerapi
源码中部分接口还处于实验阶段,并未发布,代码中使用 RELEASE_MODE 对接口是否正式发布进行了隔离。
当前已发布接口参考源码库中的 API 文档。
安装软件包
使用以下命令安装 powerapi-devel 软件包,使用提供的接口进行开发。
yum install powerapi-devel
基本流程
查询类接口调用只需要注册,设置类接口调用前除了注册还需要请求控制权。按业务场景分,业务流程如下:
离散型感知类业务场景:设置日志回调 -> 注册 -> 查询接口调用 -> 注销
配置类业务场景:设置日志回调 -> 注册 -> 请求控制权 -> 配置接口调用 -> 释放控制权 -> 注销
powerapi接口
通用接口
设置日志回调函数
接口定义:PWR_API int PWR_SetLogCallback(void(LogCallback)(int level, const char *fmt, va_list vl))
接口描述:设置日志打印回调,设置后,powerapi库将回调LogCallBack函数打印日志。如不设置,默认打印到控制台。该接口可在注册前调用。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
LogCallBack | void(*) | 日志打印回调函数指针 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 4:失败,回调函数指针为空 |
设置服务端信息
接口定义:PWR_API int PWR_SetServerInfo(const char* socketPath)
接口描述:该接口用于设置unix domain socket通信服务端地址信息。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
socketPath | const 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)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
socketPath | const char* | 客户端socket文件路径 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 该接口必须在注册前调用才能让新设置的socket文件路径生效。
- 调用该接口设置的路径必须是存在并且当前用户有读写权限的路径。
设置数据采集任务的回调函数
接口定义:int PWR_SetMetaDataCallback(void(MetaDataCallback)(const PWR_COM_CallbackData *callbackData))
接口描述:Powerapi目前支持部分功耗相关数据采集,此接口用户可设置回调函数,在回调函数中处理这些数据。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
MetaDataCallback | void(*) | 采集数据的回调函数指针 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 该接口必须在启动采集任务前进行设置,否则不处理数据。
- 回调函数中应该尽量轻量化,不宜做过多逻辑处理,尤其是比较费时的逻辑处理。
创建数据采集任务
接口定义:int PWR_CreateDcTask(const PWR_COM_BasicDcTaskInfo *basicDcTaskInfo)
接口描述:该接口用于创建周期性数据采集任务,目前暂时只支持两种类型的数据采集:CPU使用率和CPU性能数据。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
basicDcTaskInfo | PWR_COM_BasicDcTaskInfo* | 数据采集任务基础信息,包含采集的周期、采集数据类型 |
PWR_COM_BasicDcTaskInfo 结构体具体定义,可以查看头文件pwrdata.h 中具体定义 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 创建的采集任务是以数据类型为单位,多次创建同一数据类型的采集任务,内部是只有一个这个数据类型的采集任务。
删除数据采集任务
接口定义:int PWR_DeleteDcTask(PWR_COM_COL_DATATYPE dataType)
接口描述:该接口根据数据类型删除数据采集任务。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
dataType | PWR_COM_COL_DATATYPE | 数据采集的数据类型 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置事件回调函数
接口定义:int PWR_SetEventCallback(void(EventCallback)(const PWR_COM_EventInfo* eventInfo))
接口描述:PowerAPI内部定义了一些事件,用户可以设置回调函数,在回调函数中处理这些事件。目前支持认证失败和控制权被抢占两个事件。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
EventCallback | void(*) | 事件回调函数指针 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 回调函数的实现应轻量化,不宜做过多逻辑处理,尤其是比较费时的逻辑处理,否则可能导致由于数据拥塞而丢失数据。
CPU
获取CPU信息
接口定义:PWR_API int PWR_CPU_GetInfo(PWR_CPU_Info *cpuInfo)
接口描述:获取CPU信息,包含CPU基础信息,NUMA信息。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
cpuinfo | PWR_CPU_Info* | CPU信息 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取CPU使用率
接口定义:int PWR_CPU_GetUsage(PWR_CPU_Usage *usage, uint32_t bufferSize)
接口描述:获取CPU全部核心的平均使用率,以及每个核心分别的使用率。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
Usage | PWR_CPU_Usage* | CPU使用率信息 |
bufferSize | uint32_t | CPU使用率信息内存块大小 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 该接口会阻塞当前线程500ms,如果是比较频繁的获取CPU使用率,建议采用任务方式,参见创建数据采集任务
获取CPU性能数据
接口定义:int PWR_CPU_GetPerfData(PWR_CPU_PerfData *perfData)
接口描述:获取CPU性能数据,实时获取CPU单指令平均LLC miss数和IPC(统计时长100ms)
参数描述:
参数 | 类型 | 描述 |
---|---|---|
perfData | PWR_CPU_PerfData* | CPU性能数据信息 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 该接口会阻塞当前线程100ms,如果是比较频繁的获取CPU性能数据,建议采用任务方式,参见创建数据采集任务
获取CPU Frequency能力
接口定义:PWR_API int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize)
参数描述:查询可用的CPUFreq调频域信息,可用governor和当前使用的CPUFreq驱动。
参数 | 类型 | 描述 |
---|---|---|
freqAbi | PWR_CPU_FreqAbility* | CPUFreq能力信息 |
bufferSize | uint32_t | freqAbi内存块大小。 该内存块建议大小: 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)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
gov | char[] | governor的名称,最大长度31。 |
size | uint32_t | 给定gov数组空间大小,需大于等于PWR_MAX_ELEMENT_NAME_LEN(32)。 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置CPU Frequency governor
接口定义:PWR_API int PWR_CPU_SetFreqGovernor(const char gov[])
接口描述:设置系统当前使用的CPUFreq调频器(设置时将所有调频域设置为输入的governor)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
gov | char[] | 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调频器的所有属性信息。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
govAttrs | PWR_CPU_FreqGovAttrs* | 调频器属性信息 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取CPU Frequency governor属性
接口定义:PWR_API int PWR_CPU_GetFreqGovAttr(PWR_CPU_FreqGovAttr *govAttr)
接口描述:获取当前使用的CPUFreq属性(系统将获取第一个调频域(policy0)当前使用的governor对应的属性)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
govAttrs | PWR_CPU_FreqGovAttrs* | 调频器属性信息 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置CPU Frequency governor属性
接口定义:PWR_API int PWR_CPU_SetFreqGovAttr(const PWR_CPU_FreqGovAttr *govAttr)
接口描述:设置当前使用的CPUFreq属性(系统将设置第一个调频域(policy0)当前使用的governor对应的属性)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
govAttrs | PWR_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工作频率范围(默认获取第一个调频域的工作频率范围)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
freqRange | PWR_CPU_FreqRange* | 所获取的工作频率范围 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置CPU工作频率范围
接口定义:PWR_API int PWR_CPU_SetFreqRange(const PWR_CPU_FreqRange *freqRange)
接口描述:设置CPU工作频率范围(把所有调频域设置成指定的频率范围)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
freqRange | PWR_CPU_FreqRange* | 设置的工作频率范围 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取CPU当前频率
接口定义:PWR_API int PWR_CPU_GetFreq(PWR_CPU_CurFreq curFreq[], uint32_t *num, int spec)
接口描述:获取调频域的当前频率。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
curFreq | PWR_CPU_CurFreq[] | 表示要查询的policy当前调频域的频率信息。 spec=1时需要设置对应成员的policyId。 输出调频域的当前频率。 |
num | uint32_t * | curFreq数组空间长度,代表要查询的policy的个数。 输出时为系统实际返回的有效数据长度(表现为实际policy的个数与输入num的较小值)。 |
spec | int | 释放获取特定某个或某几个调频域的信息。 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时才可设置)。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
curFreq | PWR_CPU_CurFreq[] | 要设置的调频域及其频率列表。 |
num | uint32_t | curFreq数组空间长度,即调整policy的个数。 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取CPU休眠能力和状态信息
接口定义:PWR_API int PWR_CPU_GetIdleInfo(PWR_CPU_IdleInfo *idleInfo)
接口描述:获取CPUIdele能力和状态信息。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
idleInfo | PWR_CPU_IdleInfo* | CPUIdle能力和状态信息 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取CPU休眠governor
接口定义:PWR_API int PWR_CPU_GetIdleGovernor(char idleGov[], uint32_t size)
接口描述:获取CPU休眠模式。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
idleGov | char[] | governor名称 |
size | uint32_t | idleGov缓存区大小,最小值PWR_MAX_ELEMENT_NAME_LEN(32) |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置CPU休眠governor
接口定义:PWR_API int PWR_CPU_SetIdleGovernor(const char idleGov[])
接口描述:设置CPU休眠模式。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
idleGov | char[] | governor名称,如: ladder menu teo haltpoll |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取CPU&DMA时延
接口定义:PWR_API int PWR_CPU_DmaGetLatency(int *latency)
接口描述:获取CPU&DMA可忍受时延。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
latency | int* | 时延(单位:us) 取值范围:[0, 2000000000] |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置CPU&DMA时延
接口定义:PWR_API int PWR_CPU_DmaSetLatency(int latency)
接口描述:设置CPU&DMA可忍受时延。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
latency | int* | 时延(单位:us)。取值范围:[0,2000000000] |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注:
不同的C-state,被唤醒所需时间不同,睡得越深,唤醒时延越大,因而系统在进入C-state前会判断CPU&DMA latency,如果对应C-state的时延大于CPU&DMA latency,则不会进入C-state。
各个C-state唤醒时延参考(单位:us)
C-state name | latency |
---|---|
C0 POLL | 0 |
C1 | 2 |
C1E | 10 |
C3 | 40 |
C6 | 133 |
C7S | 166 |
C8 | 300 |
C9 | 600 |
C10 | 2600 |
系统类接口
设置整系统电源状态
接口定义:int PWR_SYS_SetPowerState(int powerState)
接口描述:
- 该接口用于进行系统级休眠
参数描述:
参数 | 类型 | 描述 |
---|---|---|
powerState | int | 1 - 休眠RAM 2 - 休眠Disk |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 系统进入休眠后,如果重新激活系统,需要通过其他方式(如通过BMC物理端口的IPMI接口)远程激活系统。
获取系统当前功耗信息
接口定义:int PWR_SYS_GetRtPowerInfo(PWR_SYS_PowerInfo * powerInfo)
接口描述:
- 查询系统实时能耗信息,包括整机当前功率、CPU当前功率、内存当前功率
参数描述:
参数 | 类型 | 描述 |
---|---|---|
powerInfo | PWR_SYS_PowerInfo | 包含sysPower/cpuPower/memPower三部分,这里是最终获取到功耗信息的出参内存地址 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- ARM平台暂时无法获取到CPU功耗信息和内存功耗信息
HBM类接口
查询HBM能力和运行模式
接口定义:int PWR_HBM_GetSysState(PWR_HBM_SYS_STATE *state) 接口描述:
- 查询当前设备是否支持HBM,并查询HBM当前运行模式为flat模式、还是cache模式或混合模式。
- HBM一般支持flat和cache两种运行模式,前者OS会将HBM作为cpuless的numa节点使用,而后者当做LLC使用。两种方式都支持进行上下电操作。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | PWR_HBM_SYS_STATE | HBM系统状态,包括是否支持HBM以及当前运行模式 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
关闭/启动所有HBM
接口定义:int PWR_HBM_SetAllPwrState(int state)
接口描述:
- 关闭/启动所有HBM,包括cache模式和flat模式。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | int | 0:关闭所有HBM 1:启动所有HBM |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
proc进程相关接口
根据关键字查找任务
接口定义: int PWR_PROC_QueryProcs(const char *keywords, pid_t procs[], uint32_t *num)
接口描述:
- 根据关键字查找进程,并返回进程列表。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
keywords | const char* | 关键字列表。多个关键字用"|"隔开,例如 "nginx|mysql", 注意,空格会被认为是关键字一部分 输入NULL或空字符串时表示查询所有用户态的任务 不包含结束符'\0',长度范围[0,999] |
procs | pid_t* | 进程列表 |
num | uint32_t* | 进程列表长度 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
查询瓦特调度开关状态
瓦特调度说明:
- 瓦特调度是一种为节省功耗,在内核采取的调度机制。在负载比较低时,系统会将任务集中在部分numa节点,为其他节点创造进入低功耗的条件。随着负载变化,系统会动态地扩缩用于完成任务的numa节点。
- 约束:当前瓦特调度在x86内核中是默认是不开启,如果需要开启需要QOS_SCHED_DYNAMIC_AFFINITY和QOS_SCHED_SMART_GRID这两个配置,重新编译内核并替换内核。
接口定义: int PWR_PROC_GetWattState(int *state)
接口描述:
- 查询瓦特调度开关状态。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | int* | 瓦特调度开关状态,0表示关闭,1表示打开 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置瓦特调度开关
接口定义: int PWR_PROC_SetWattState(int state)
接口描述:
- 设置瓦特调度开关状态。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | int | 瓦特调度开关状态,0表示关闭,1表示打开 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置瓦特调度第一调度域
接口定义: int PWR_PROC_SetWattFirstDomain(int cpuId)
接口描述:
- 该接口用于指定瓦特调度使用的第一个调度域。
- 默认情况下,在启动瓦特调度时,系统选择最空闲的NUMA node作为第一个调度域(level0),后续在扩缩算力时,根据NUMA node的亲和性进行扩缩(例如:对于2颗CPU芯片,4个NUMA node的设备,node2为第一个调度域时,优先会扩展同一个socket下的node3, 然后是另一个socket下的node1和node0)。
- 有些情况下,由于IRQ亲和性等原因,为了保证性能,需要指定第一个调度域为IRQ所在的NUMA node。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
cpuId | int | 设置cpuId所在域为第一调度域 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 设置的CPU是在线和可调度状态。
- 瓦特调度需要是关闭状态。
获取瓦特调度属性
瓦特调度属性说明:
参数名 | 取值 | 含义 | 实际路径 |
---|---|---|---|
scaleThreshold | [0, 100] 默认85 | 扩缩资源的阈值。 即CPU利用率达到该阈值后,瓦特调度自动扩展计算资源。 属性设置时,该值为0,表示不设置该属性 | /proc/sys/kernel/sched_util_low_pct |
domainMask | 4个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)
接口描述:
- 获取瓦特调度属性。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
wattAttrs | PWR_PROC_WattAttrs | 瓦特调度属性 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置瓦特调度属性
接口定义: int PWR_PROC_SetWattAttrs(PWR_PROC_WattAttrs *wattAttrs)
接口描述:
- 设置瓦特调度属性。
参数描述:
参数 | 类型 | 描述 |
---|---|---|
wattAttrs | PWR_PROC_WattAttrs | 瓦特调度属性 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
查询当前瓦特调度任务列表
接口定义:int PWR_PROC_GetWattProcs(pid_t wattProcs[], uint32_t *num)
接口描述:
- 查询有哪些任务已经加入到瓦特调度中
参数描述:
参数 | 类型 | 描述 |
---|---|---|
wattProcs | pid_t | 瓦特调度任务列表,最大5000个。需要和num个数匹配 |
num | uint32_t | 瓦特调度任务列表数量,最大值5000 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
添加瓦特调度任务
接口定义:int PWR_PROC_AddWattProcs(const pid_t wattProcs[], uint32_t num)
接口描述:
- 添加任务到瓦特调度中
参数描述:
参数 | 类型 | 描述 |
---|---|---|
wattProcs | pid_t | 瓦特调度任务列表,最大5000个。需要和num个数匹配 |
num | uint32_t | 瓦特调度任务列表数量,最大5000 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 子进程会继承父进程/线程的瓦特调度属性。即如果父进程/线程已经在瓦特调度组,则生成的子进程/线程也会在该调度组
删除瓦特调度任务
接口定义:int PWR_PROC_DelWattProcs(const pid_t wattProcs[], uint32_t num)
接口描述:
- 删除任务从瓦特调度中
参数描述:
参数 | 类型 | 描述 |
---|---|---|
wattProcs | pid_t | 瓦特调度任务列表 |
num | uint32_t | 瓦特调度任务列表数量,最大5000 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
查询smart_grid开关状态
smart_grid说明:
- smart_grid智能网格是一种为节省功耗,在瓦特调度的基础上内核的一种CPU资源划分和标识方法。smart_grid可以将算力资源和任务划分不同等级,高等级任务用高算力来运行,低等级任务用低算力运行。
- 为使smart_grid生效,需要先开启smart_grid,并批量设置任务的smart_grid_level。
- openEuler 22.03 SP2及以上版本才支持smart_grid功能。
- 开启smart_grid前,开启瓦特调度才能让smart_grid功能生效。
接口定义:int PWR_PROC_GetSmartGridState(int *state)
接口描述:
- 查询smart_grid开关状态
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | int | 0:关闭 1:开启 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置smart_grid开关状态
接口定义:int PWR_PROC_SetSmartGridState(int state)
接口描述:
- 设置smart_grid开关状态
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | int | 0:关闭 1:开启 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
根据smart_grid_level查询任务列表
smart_grid等级说明:
- 当前只支持两个等级:0-高等级, 1-低等级。
- 处于高等级的任务将会被调度到性能域,而处于低等级的任务将会被调度到能效域。
- 子进程/线程会继承父进程/线程的smart_grid等级属性。即如果父进程/线程的等级是0,则生成的子进程/线程等级也是0。
- 已经存在的子进程/线程不会随父进程/线程改变smart_grid等级属性。
接口定义:int PWR_PROC_GetSmartGridProcs(PWR_PROC_SMART_GRID_LEVEL level, PWR_PROC_SmartGridProcs *sgProcs)
接口描述:
- 根据smart_grid_level查询任务列表
参数描述:
参数 | 类型 | 描述 |
---|---|---|
level | PWR_PROC_SMART_GRID_LEVEL | 0:高等级 1:低等级 |
sgProcs | PWR_PROC_SmartGridProcs | 任务列表。 其中:procNum作为输入,指定procs空间所能存储的任务数量。 作为输出,标识实际返回的任务数量。 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
批量设置任务的smart_grid_level
接口定义:int PWR_PROC_SetSmartGridLevel(const PWR_PROC_SmartGridProcs *sgProcs)
接口描述:
- 批量设置任务的smart_grid等级
参数描述:
参数 | 类型 | 描述 |
---|---|---|
sgProcs | PWR_PROC_SmartGridProcs | 任务列表 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取smart_grid的调频器
smart_gird调频器可设置参数:
参数名 | 取值 | 含义 | 实际路径 |
---|---|---|---|
sgAgentstate | 0或1 | smart_grid调频器状态。 smart_grid调频器状态为1时会覆盖cpufreq设置的governor | /sys/devices/system/cpu/cpufreq/smart_grid_governor_enable |
sgLevel0Gov | 最大长度31,取值范围:conservative/ondemand/userspace/powersave/performance/schedutil | level0的调频器,需要smart_grid开启才有效 | /sys/devices/system/cpu/cpufreq/smart_grid_governor |
sgLevel1Gov | 最大长度31,取值范围:conservative/ondemand/userspace/powersave/performance/schedutil | level1的调频器,需要smart_grid开启才有效 | /sys/devices/system/cpu/cpufreq/smart_grid_governor |
接口定义:int PWR_PROC_GetSmartGridGov(PWR_PROC_SmartGridGov *sgGov)
接口描述:
- 获取smart_grid的调频器
参数描述:
参数 | 类型 | 描述 |
---|---|---|
sgGov | PWR_PROC_SmartGridGov | 调频器参数 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置smart_grid的调频器
接口定义:int PWR_PROC_SetSmartGridGov(const PWR_PROC_SmartGridGov *sgGov)
接口描述:
- 设置smart_grid的调频器
参数描述:
参数 | 类型 | 描述 |
---|---|---|
sgGov | PWR_PROC_SmartGridGov | 调频器参数 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
获取服务的状态
接口定义:int PWR_PROC_GetServiceState(PWR_PROC_ServiceStatus *sStatus)
接口描述:
- 获取服务的状态
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | PWR_PROC_ServiceStatus | 服务的状态,有 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
设置服务的状态
接口定义:int PWR_PROC_SetServiceState(const PWR_PROC_ServiceState *sState)
接口描述:
- 设置服务的状态
参数描述:
参数 | 类型 | 描述 |
---|---|---|
state | PWR_PROC_ServiceState | 服务的状态,目前只支持停止(0)/开启(1)两种状态 |
返回值:
类型 | 描述 |
---|---|
int | 返回码 0:成功 其他值:失败,参见错误码 |
注意:
- 目前暂时只支持设置mpctool和eagle两个服务的状态。
- 设置服务状态前,需要安装mpctool或者eagle两个软件,分别对应
python3-eagle-mpctool
和eagle
软件包。 - mpctool目前只支持以下arm服务器机型,x86下无法使用
- Taishan200 2280(VD)
- Taishan200 Pro 2280
- Taishan200 2280v2
使用用例
将以下代码保存为powerapi_test.c
。
#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编译:
gcc powerapi_test.c -o powerapi_test -lpwrapi
运行查看结果:
./powerapi_test