当前位置 博文首页 > jason的笔记:cgroup 架构

    jason的笔记:cgroup 架构

    作者:[db:作者] 时间:2021-09-14 10:25

    网上Cgroup的资料一大堆,我就写一下自己的心得.希望可以抛砖引玉.
    每一个cgroup 对应一个cgroup_subsys 类型,这个类型中最重要的是cftype。
    我们以cpuacct为例
    348 struct cgroup_subsys cpuacct_cgrp_subsys = {
    349 ? ? ? ? .css_alloc ? ? ?= cpuacct_css_alloc,
    350 ? ? ? ? .css_free ? ? ? = cpuacct_css_free,
    351 ? ? ? ? .legacy_cftypes = files,
    352 ? ? ? ? .early_init ? ? = true,
    353 };
    最终要的cftype = files.
    278 static struct cftype files[] = {
    279 ? ? ? ? {
    280 ? ? ? ? ? ? ? ? .name = "usage",
    281 ? ? ? ? ? ? ? ? .read_u64 = cpuusage_read,
    282 ? ? ? ? ? ? ? ? .write_u64 = cpuusage_write,
    283 ? ? ? ? },
    284 ? ? ? ? {
    285 ? ? ? ? ? ? ? ? .name = "usage_user",
    286 ? ? ? ? ? ? ? ? .read_u64 = cpuusage_user_read,
    287 ? ? ? ? },
    288 ? ? ? ? {
    289 ? ? ? ? ? ? ? ? .name = "usage_sys",
    290 ? ? ? ? ? ? ? ? .read_u64 = cpuusage_sys_read,
    291 ? ? ? ? },
    292 ? ? ? ? {
    293 ? ? ? ? ? ? ? ? .name = "usage_percpu",
    294 ? ? ? ? ? ? ? ? .seq_show = cpuacct_percpu_seq_show,
    295 ? ? ? ? },
    296 ? ? ? ? {
    297 ? ? ? ? ? ? ? ? .name = "usage_percpu_user",
    298 ? ? ? ? ? ? ? ? .seq_show = cpuacct_percpu_user_seq_show,
    299 ? ? ? ? },
    300 ? ? ? ? {
    301 ? ? ? ? ? ? ? ? .name = "usage_percpu_sys",
    302 ? ? ? ? ? ? ? ? .seq_show = cpuacct_percpu_sys_seq_show,
    303 ? ? ? ? },
    304 ? ? ? ? {
    305 ? ? ? ? ? ? ? ? .name = "stat",
    306 ? ? ? ? ? ? ? ? .seq_show = cpuacct_stats_show,
    307 ? ? ? ? },
    308 ? ? ? ? { } ? ? /* terminate */
    309 };
    从files 可以,可以在cpuacct.usage/cpuacct.usage_percpu_sys等目录。我们以 cat cpuacct.usage 会调用cpuacct_stats_show函数。
    ?static int cpuacct_stats_show(struct seq_file *sf, void *v)
    251 {
    252 ? ? ? ? struct cpuacct *ca = css_ca(seq_css(sf));
    253 ? ? ? ? int cpu;
    254 ? ? ? ? s64 val = 0;
    255?
    256 ? ? ? ? for_each_possible_cpu(cpu) {
    257 ? ? ? ? ? ? ? ? struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu);
    258 ? ? ? ? ? ? ? ? val += kcpustat->cpustat[CPUTIME_USER];
    259 ? ? ? ? ? ? ? ? val += kcpustat->cpustat[CPUTIME_NICE];
    260 ? ? ? ? }
    261 ? ? ? ? val = cputime64_to_clock_t(val);
    262 ? ? ? ? seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_USER], val);
    263?
    264 ? ? ? ? val = 0;
    265 ? ? ? ? for_each_possible_cpu(cpu) {
    266 ? ? ? ? ? ? ? ? struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu);
    267 ? ? ? ? ? ? ? ? val += kcpustat->cpustat[CPUTIME_SYSTEM];
    268 ? ? ? ? ? ? ? ? val += kcpustat->cpustat[CPUTIME_IRQ];
    269 ? ? ? ? ? ? ? ? val += kcpustat->cpustat[CPUTIME_SOFTIRQ];
    270 ? ? ? ? }
    271?
    272 ? ? ? ? val = cputime64_to_clock_t(val);
    273 ? ? ? ? seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_SYSTEM], val);
    274?
    275 ? ? ? ? return 0;
    276 }


    其中最终要的262行的seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_USER], val);
    和273行的seq_printf(sf, "%s %lld\n", cpuacct_stat_desc[CPUACCT_STAT_SYSTEM], val);
    其中
    245 static const char * const cpuacct_stat_desc[] = {
    246 ? ? ? ? [CPUACCT_STAT_USER] = "user",
    247 ? ? ? ? [CPUACCT_STAT_SYSTEM] = "system",
    248 };
    可以先显示进程在user 和system的时间.cs