cgroup学习(五)—— create new cgroup && (六)——attach task

create new cgroup

        该过程就是mkdir/cgroup/cpu/test_cpu:在一个/cgroup/cpu hierarchy上创建一个cgroup,下面的bt是创建一个cpu hierarchy下的cgroup:

[html]  view plain copy
  1. mkdir /cgroup/cpu/test_cpu  
  2. 74447177 8388 (mkdir) call trace:  
  3.  0xffffffff8105fe80 : cpu_cgroup_create+0x0/0x40[kernel]  
  4.  0xffffffff810c1021 :cgroup_mkdir+0x161/0x540 [kernel]  
  5.  0xffffffff811850a7 :vfs_mkdir+0xa7/0x100 [kernel]  
  6.  0xffffffff8118816e :sys_mkdirat+0xfe/0x120 [kernel]  
  7.  0xffffffff811881a8 : sys_mkdir+0x18/0x20[kernel]  
  8.  0xffffffff8100b0f2 :system_call_fastpath+0x16/0x1b [kernel]  
        在cgroup_mkdir里会直接调用cgroup_create(这里可能被编译器优化了),它先为该cgroup所属的每个subsys创建一个cgroup_subsys_state,并初始化:
[cpp]  view plain copy
  1. for_each_subsys(root, ss) {  
  2.               struct cgroup_subsys_state*css = ss->create(ss, cgrp);  
  3.               init_cgroup_css(css, ss,cgrp);  
  4. …  
  5. }  
        通过该cgroup->subsys[]可以获得该cgroup的所有cgroup_subsys_state,同样通过cgroup_subsys_state->cgroup可以知道该cgroup_subsys_state所属的cgroup。以后cgroup与subsys的group控制体的转换都是通过该结构来完成。   
        cpu_cgroup_create最终会通过sched_create_group(继承父cgroup)来生成一个task_group(即cpu子系统的group控制体结构),它包含了该cgroup的se,cfs_rq,shares等(在介绍cpu子系统的时候,我们再详细讨论)。
        创建完成cgroup_subsys_state后就是生成该目录cgroup_create_dir,及生成子系统的文件cgroup_populate_dir:
[html]  view plain copy
  1. 74447240 8388 (mkdir) call trace:  
  2.  0xffffffff81054e60 :cpu_cgroup_populate+0x0/0x30 [kernel]  
  3.  0xffffffff810c007a :cgroup_populate_dir+0x7a/0x110 [kernel]  
  4.  0xffffffff810c11fc : cgroup_mkdir+0x33c/0x540[kernel]  
  5.  0xffffffff811850a7 :vfs_mkdir+0xa7/0x100 [kernel]  
  6.  0xffffffff8118816e :sys_mkdirat+0xfe/0x120 [kernel]  
  7.  0xffffffff811881a8 : sys_mkdir+0x18/0x20[kernel]  
  8.  0xffffffff8100b0f2 :system_call_fastpath+0x16/0x1b [kernel]  
        在创建cgroup目录的时候(cgroup_create_dir)会将该cgroup保存在dentry->d_fsdata = cgrp里,这样就将目录与该cgroup关联起来,当需要操作该目录下的文件时,就通过从这里取得它所属的cgroup;同样在生成每个文件的时候(cgroup_add_file)会把该文件的cftype保存到dentry->d_fsdata = (void *)cft,当在操作该文件的时候,将根据它定义的方法来完成。
        简而言之,该过程完成cgroup结构的创建包括该cgroup所属的所有子系统的cgroup_subsys_state,然后相应的目录及文件,并把这些文件与该cgroup绑定起来。这里并没有建立css_set与该cgroup的关系,因为mkdir时该cgroup还没有attach任何进程,所以也不会有css_set与它有关系。
=====================================
 

cgroup学习(六)——attach task

        该过程对应于我们上面的实例操作的:echo 512 > tasks的过程,其实质就是先对cgroup下tasks文件进行写操作,建立该进程新的css_set与所有管理它的cgroup的关系;然后再根据各个子系统自己的attach函数进行attach操作。在这里我们先介绍第一个过程,第二个过程在各个子系统中介绍。先看一下bt:
[html]  view plain copy
  1. 12530 (sh) cpu_cgroup_attach call trace:  
  2.  0xffffffff81065a20 :cpu_cgroup_attach+0x0/0x60 [kernel]  
  3.  0xffffffff810c1d3e :cgroup_attach_task+0x26e/0x620 [kernel]  
  4.  0xffffffff810c214c :cgroup_tasks_write+0x5c/0xf0 [kernel]  
  5.  0xffffffff810be29a :cgroup_file_write+0x2ba/0x320 [kernel]  
  6.  0xffffffff81177e68 :vfs_write+0xb8/0x1a0 [kernel]  
  7.  0xffffffff81178871 : sys_write+0x51/0x90[kernel]  
  8.  0xffffffff8100b0f2 :system_call_fastpath+0x16/0x1b [kernel]  
        从该bt可以看到在第一个过程中最终调用的函数为cgroup_attach_task:首先通过task_cgroup_from_root确定该task现在属于该hierarchy的哪一个cgroup,一个task一定属于一个hierarchy里某个cgroup,而且仅属于其中的某一个,要么在该hierarchy的top_cgroup(task->cgroups==&init_css_set),要么是hierarchy下的其它某个cgroup:
[cpp]  view plain copy
  1. if (css == &init_css_set) {  
  2.        res = &root->top_cgroup;  
  3. else {  
  4.        struct cg_cgroup_link *link;  
  5. /*因为css_set会被多个cgroup管理,但是这些cgroup都是属于不同的hierarchy,所以当遍历到一个cgroup它的root等于当前的hierarchy,那么这个cgroup就是该task在该hierarchy下当前所属的cgroup*/  
  6.        list_for_each_entry(link, &css->cg_links, cg_link_list) {  
  7.               struct cgroup *c = link->cgrp;  
  8.               if (c->root == root) {  
  9.                      res = c;  
  10.                      break;  
  11.               }  
  12.        }  
  13. }  
注:attach一定是从一个旧的cgroup转移到一个新的cgroup的过程。
        如果要attach的新的cgroup与该task之前在该 hierarchy所属的cgroup一样则直接返回;否则,先判断该task是否可以在所有subsys上can_attach,然后通过find_css_set查找一个已经存在的css_set或者创建一个新的:首先通过find_existing_css_set查找是否有一个可用的css_set( css_set_table哈希表中查出与该task旧的css_set所属的子系统+新的子系统相同的css_set链表,然后遍历这个链表的每个node与旧的css_set所关联的cgroup是否一样(compare_css_sets,除去新的将要attachcgroup),其实质就是查找是否存在这样一个css_set:该task旧的css_set的所有cgroup去掉它在当前hierarchy下的cgroup,加上新的它即将加入的cgroup,组成的css_set),有则直接返回;否则,创建一个新的css_set,并且建立新的css_set(res)与该task之前旧的css_set(oldcg)的所有关联的cgroup(其实也是root_count个 hierarchy,因为在每个hierarchy下都有一个cgroup与之相关,除去它之前所属的cgroup)的关系,再把该新的css_set加入到哈希表hlist。最后再调用每个子系统的attach,即第二个过程。

       下面的图3(来自http://blog.chinaunix.net/uid-20543183-id-1930840.html),展现了我们前面介绍的三个过程mount,mkdir,attach:


图3 cgroup mount,mkdir及attach关系图

        其中task结构里的字段是错误的,应该是:cgroups,cg_list(在2.6.32-220 kernel)。它mount一个由两个subsys组成的hierarchy。到这里我们就介绍了cgroup框架里mount,mkdir,attach三个操作,后面我们将介绍cgroup的子系统。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值