鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

TEE内TA资源利用率获取

对于一些监控程序,需要获取TA应用CPU、内存等资源的占用情况,为了满足该需求,CCOS对TA开放了TEE内“/proc”目录下的访问权限,客户可基于此计算出TA和系统的运行状态等信息(如TA的CPU占用率)。

新增文件访问权限

CCOS对TA开放了如下文件的访问权限。各文件格式与Linux man手册基本保持一致。

  • /proc/stat:提供系统和各CPU核心的统计信息,可基于此计算出各CPU的运行状态和性能指标,格式如下:
    cpu <user> <nice> <system> <idle> <iowait> <irq> <softirq> <steal> <guest> <guest_nice>
    cpu0 <user> <nice> <system> <idle> <iowait> <irq> <softirq> <steal> <guest> <guest_nice>
    ...
    cpuN <user> <nice> <system> <idle> <iowait> <irq> <softirq> <steal> <guest> <guest_nice>
    intr <total> <num> ...
    ctxt <num>
    btime <num>
    processes <num>
    procs_running <num>
    procs_blocked <num>
    softirq <total> <num> ...

    其中N为CPU核数。通过该文件可计算出总CPU和各CPU核的占用率信息。比如计算用户态CPU占用率可参考如下方式计算:

    • TEE OS仅统计user、system、idle、irq项,其他项未统计。
    • TEE侧的每个CPU默认绑定一个smcd线程,没有任务时该线程处于wait状态;当有来自CA的OpenSession指令时,该线程会让出CPU,转而处理session的任务。因此空闲时,每个核会运行smcd线程,system占用100%,当在TA内绑定某个线程到CPU核时,TA用户态线程与核的smcd线程均分CPU,表现为用户态和内核态各占50%。
    • 当CA绑定CPU核时,对应的TA并不全部运行在该核上,即该核的用户态CPU利用率并非100%。
  • /proc/uptime:提供系统自启动以来的运行时间和空闲时间,格式如下:
    <uptime> <idle_time>

    时间单位为秒,其他proc文件里的数据时间单位多为内核时钟频率,两者的比值为sysconf(_SC_CLK_TCK)。

  • /proc/loadavg:提供系统的平均负载信息(最近一段时间内系统活跃的任务数量),格式如下:
    <1min_avg> <5min_avg> <15min_avg>

    由于TEE侧每个CPU核默认会绑定一个smcd线程,因此无TA运行时,负载的值默认为CPU核数。

  • /proc/self/*:提供当前进程的统计信息,比如比较常用的两个文件:
    • /proc/self/statm提供当前进程的内存信息。
      <size> <resident> <shared> <text> <lib> <data> <dt>

      单位为页,可通过sysconf(_SC_PAGESIZE)获取TEE内页大小。若需要获取总内存大小,可通过int sysinfo(struct sysinfo *info)接口获取。

    • /proc/self/stat提供当前进程运行的统计信息。
      <pid> (<comm>) <state> <ppid> <pgrp> <session> <tty_nr> <tpgid> <flags> <minflt> <cminflt> <majflt> <cmajflt> <utime> <stime> <cutime> <cstime> <priority> <nice> <num_threads> <itrealvalue> <starttime> <vsize> <rss> <rsslim> <startcode> <endcode> <startstack> <kstkesp> <kstkeip> <signal> <blocked> <sigignore> <sigcatch> <wchan> <nswap> <cnswap> <exit_signal> <processor> <rt_priority> <policy> <delayacct_blkio_ticks> <guest_time> <cguest_time>

      时间单位为内核时钟频率,结合/proc/uptime计算进程CPU占用率时,需要注意两者单位的差异,可参考如下公式:

      分子为进程在统计时间内所占用的时间片,可从/proc/self/stat中获取,一般为用户态时间utime和内核态时间stime之和,可根据需要确定是否需要加入其他状态的时间片。分母为系统在统计时间内所占的时间,sysconf(_SC_CLK_TCK)为每秒时钟滴答数。

TA CPU占用率示例

下面提供TA内读取CPU利用率的片段代码示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#define BUF_SIZE 1024
#define PROC_SELF_STAT "/proc/self/stat"
#define DELTA_TIME 1 // s

// 读取/proc文件获取原始数据
int read_cpu_time(double *utime, double *stime) {
    int fd;
    char buf[BUF_SIZE];
    char *token;
    
    // 读取/proc/self/stat内容
    fd = open(PROC_SELF_STAT, O_RDONLY);
    if (fd == -1) {
        tloge("Failed to open %s\n", PROC_SELF_STAT);
        return -1;
    }
    if (read(fd, buf, BUF_SIZE) == -1) {
        tloge("Failed to read %s\n", PROC_SELF_STAT);
        close(fd);
    }
    close(fd);
    // 解析获取utime和stime
    token = strtok(buf, " ");
    for (int i = 1; i <= 17 && token != NULL; i++) {
        if (i == 14) *utime = atof(token);  // utime in jiffies
        if (i == 15) *stime = atof(token);  // stime in jiffies
        token = strtok(NULL, " ");
    }
    return 0;
}

// 计算TA cpu占用率
void calculate_cpu_usage() {
    double utime1, stime1;
    double utime2, stime2;
    double cpu_usage = 0;
    
    read_cpu_time(&utime1, &stime1);
    // or do other work
    sleep(DELTA_TIME);  
    read_cpu_time(&utime2, &stime2);

    cpu_usage = ((utime2 + stime2) - (utime1 + stime1)) / (DELTA_TIME * sysconf(_SC_CLK_TCK));
    tlogi("cpu usage is %lf %%\n", cpu_usage * 100);
}