1. 程式人生 > >【CGROUP】10分鐘深入理解CGROUP V1本質

【CGROUP】10分鐘深入理解CGROUP V1本質

  本文作為cgroup核心程式碼的開篇文件,只介紹cgroup的設計理念,不介紹具體程式碼。理解了本文即理解了cgroup的核心思想,可以更容易地理解其它cgroup的原始碼分析文章。文中出現的核心原始碼來源於4.14.4版本。

一、資源的樹型管理
  CGROUP是擁有共同資源屬性的任務的集合,用來控制一組任務擁有多少資源可用。核心中有多種資源(稱為子系統,參考struct cgroup_subsys和 參考struct  cgroup_subsys_state),這些資源絕大多數是可數、可分配的,因此CGROUP V1版本中是以層次樹(也叫 hierarchy)的方式來進行管理。因為樹的子樹或子節點 (參考struct  cgroup )屬性可以體現資源的包含或子集關係。比如根節點擁有全部的資源上限(如記憶體2G),子節點擁有部分的資源上限(如記憶體1G)。任務掛到哪個節點上,就有相應的資源控制屬性。
  為了簡化或者減少資料結構,可以把多個資源放到一顆樹上進行管理,因此cgroup這個物件可以同時管理多個資源(subsys),可以看到它有一個
cgroup_subsys_state陣列成員用來儲存這個節點中的多種資源當時的狀態。

二、任務資源
  當一個任務分配資源(如記憶體malloc後產生的缺頁)時,需要把分配的資源統計到cgroup的節點上。因此需要從task_struct物件訪問到cgroup_subsys_state狀態物件。task_struct的cgroups成員(css_set物件,即集合)儲存了和這個任務相關的所有cgroup_subsys_state狀態的陣列。這樣,每個任務消費了資源,就可以通過該成員進行統計。
  但是每個任務的cgroup成員所指向的c
ss_set物件是不同的。有的任務限制CPU,有的任務限制記憶體。只有那些有相同限制類別的任務會指向相同的css_set物件(比如某容器內的task通常指向同一個css_set物件)

三、從cgroup獲取任務列表
  反過來,當需要從cgroup來遍歷它裡面的task的需求。一種方式是把擁有相同資源層次樹hierarchy的任務都連結到cgroup上。但是任務有可能同時存在於多個hierarchy中(擁有多種資源)。在task_struct中增加一個list_head不夠,增加多個list_head不現實。因此一個任務可能存在多個cgroup中(不同hierarchy),一個cgroup又有多個任務。task和cgroup是多對多的關係。對於這種多對多關係的物件,可以設計一種中間結構體A,當某tas
k和某個cgroup進行匹配時,就建立一個A物件。A物件分別指標指回關聯的task和cgroup。在cgroup中將和它相關的A物件連結起來,遍歷這個連結串列,就可以遍歷在該group中的所有task。如果某tasT在兩個cgroup中,則有兩個A物件分別指向T,這兩個A物件分別鏈入兩個cgroup的連結串列。這樣兩個cgroup能夠遍歷訪問到不同的A物件和T。
  實際上核心設計將上述思想做了進一步的優化。由於多個任務擁有一個公共的css_set物件上,因此核心就將任務鏈入css_set的task連結串列css_set的tasks成員。而讓css_set與cgroup形成多對多的關係,因此css_set和cgroup是一個多對多的關係。struct cgrp_cset_link就css_set與cgroup多對多匹配的中間結構。採用css_set(比採用task)與cgroup進行匹配,可以減少很多中間結構。css_set與cgroup的多對多的關係圖,請參考我的另外一篇文章(http://blog.csdn.net/lovelycheng/article/details/78359991)。從cgroup遍歷task時,先遍歷中間的cgrp_cset_link物件,然後通過cgrp_cset_link訪問相關的css_set物件,然後再遍歷css_set的所有task

四、cgroup V2
  可以看到,CGROUP V1的多層hierarchy的支援,是css_set與cgroup多對多關係以及cgrp_cset_link的複雜性根源。因此在4.X的核心版本,社群實現了一個unified hierarchy(只有一個層級的hierarchy)的簡化版的CGROUP V2。