HugeTLB 控制器¶
可以透過首先掛載 cgroup 檔案系統來建立 HugeTLB 控制器。
# mount -t cgroup -o hugetlb none /sys/fs/cgroup
完成上述步驟後,初始或父 HugeTLB 組將在 /sys/fs/cgroup 可見。在啟動時,該組包含系統中的所有任務。/sys/fs/cgroup/tasks 列出了此 cgroup 中的任務。
可以在父組 /sys/fs/cgroup 下建立新組
# cd /sys/fs/cgroup
# mkdir g1
# echo $$ > g1/tasks
上述步驟建立了一個新組 g1 並將當前 shell 程序 (bash) 移入其中。
控制檔案簡要概述
hugetlb.<hugepagesize>.rsvd.limit_in_bytes # set/show limit of "hugepagesize" hugetlb reservations
hugetlb.<hugepagesize>.rsvd.max_usage_in_bytes # show max "hugepagesize" hugetlb reservations and no-reserve faults
hugetlb.<hugepagesize>.rsvd.usage_in_bytes # show current reservations and no-reserve faults for "hugepagesize" hugetlb
hugetlb.<hugepagesize>.rsvd.failcnt # show the number of allocation failure due to HugeTLB reservation limit
hugetlb.<hugepagesize>.limit_in_bytes # set/show limit of "hugepagesize" hugetlb faults
hugetlb.<hugepagesize>.max_usage_in_bytes # show max "hugepagesize" hugetlb usage recorded
hugetlb.<hugepagesize>.usage_in_bytes # show current usage for "hugepagesize" hugetlb
hugetlb.<hugepagesize>.failcnt # show the number of allocation failure due to HugeTLB usage limit
hugetlb.<hugepagesize>.numa_stat # show the numa information of the hugetlb memory charged to this cgroup
對於支援三種大頁大小(64k、32M 和 1G)的系統,控制檔案包括
hugetlb.1GB.limit_in_bytes
hugetlb.1GB.max_usage_in_bytes
hugetlb.1GB.numa_stat
hugetlb.1GB.usage_in_bytes
hugetlb.1GB.failcnt
hugetlb.1GB.rsvd.limit_in_bytes
hugetlb.1GB.rsvd.max_usage_in_bytes
hugetlb.1GB.rsvd.usage_in_bytes
hugetlb.1GB.rsvd.failcnt
hugetlb.64KB.limit_in_bytes
hugetlb.64KB.max_usage_in_bytes
hugetlb.64KB.numa_stat
hugetlb.64KB.usage_in_bytes
hugetlb.64KB.failcnt
hugetlb.64KB.rsvd.limit_in_bytes
hugetlb.64KB.rsvd.max_usage_in_bytes
hugetlb.64KB.rsvd.usage_in_bytes
hugetlb.64KB.rsvd.failcnt
hugetlb.32MB.limit_in_bytes
hugetlb.32MB.max_usage_in_bytes
hugetlb.32MB.numa_stat
hugetlb.32MB.usage_in_bytes
hugetlb.32MB.failcnt
hugetlb.32MB.rsvd.limit_in_bytes
hugetlb.32MB.rsvd.max_usage_in_bytes
hugetlb.32MB.rsvd.usage_in_bytes
hugetlb.32MB.rsvd.failcnt
頁錯誤記賬
hugetlb.<hugepagesize>.limit_in_bytes
hugetlb.<hugepagesize>.max_usage_in_bytes
hugetlb.<hugepagesize>.usage_in_bytes
hugetlb.<hugepagesize>.failcnt
HugeTLB 控制器允許使用者限制每個控制組的 HugeTLB 使用(頁錯誤),並在頁錯誤期間強制執行限制。由於 HugeTLB 不支援頁回收,因此在頁錯誤時強制執行限制意味著,如果應用程式嘗試分配超出其限制的 HugeTLB 頁,它將收到 SIGBUS 訊號。因此,應用程式需要事先準確知道它使用了多少 HugeTLB 頁,並且系統管理員需要確保機器上有足夠的可用頁來滿足所有使用者,以避免程序收到 SIGBUS。
預留記賬
hugetlb.<hugepagesize>.rsvd.limit_in_bytes
hugetlb.<hugepagesize>.rsvd.max_usage_in_bytes
hugetlb.<hugepagesize>.rsvd.usage_in_bytes
hugetlb.<hugepagesize>.rsvd.failcnt
HugeTLB 控制器允許限制每個控制組的 HugeTLB 預留,並在預留時以及 HugeTLB 記憶體未被預留時發生頁錯誤時強制執行控制器限制。由於預留限制在預留時(在 mmap 或 shget 上)強制執行,如果記憶體事先已預留,預留限制永遠不會導致應用程式收到 SIGBUS 訊號。對於 MAP_NORESERVE 分配,預留限制與頁錯誤限制行為相同,在錯誤時強制執行記憶體使用,如果超出限制,則導致應用程式收到 SIGBUS。
預留限制優於上述頁錯誤限制,因為預留限制在預留時(在 mmap 或 shget 上)強制執行,並且如果記憶體事先已預留,則永遠不會導致應用程式收到 SIGBUS 訊號。這允許更容易地回退到其他替代方案,例如非 HugeTLB 記憶體。在頁錯誤記賬的情況下,很難避免程序收到 SIGBUS,因為系統管理員需要精確地知道系統中所有任務的 HugeTLB 使用情況,並確保有足夠的頁來滿足所有請求。在超額提交的系統上,透過頁錯誤記賬實際上不可能避免任務收到 SIGBUS。
共享記憶體的注意事項
對於共享 HugeTLB 記憶體,HugeTLB 預留和頁錯誤都記入導致記憶體被預留或發生頁錯誤的第一個任務,並且此後對該預留或發生頁錯誤的記憶體的所有後續使用都不記賬。
共享 HugeTLB 記憶體僅在取消預留或解除分配時才解除記賬。這通常發生在 HugeTLB 檔案被刪除時,而不是導致預留或頁錯誤的任務退出時。
HugeTLB cgroup 離線的注意事項。
當一個 HugeTLB cgroup 離線時,如果它仍然記賬有某些預留或頁錯誤,其行為如下:
頁錯誤記賬將記入父 HugeTLB cgroup(重新分配父級),
預留記賬保留在離線的 HugeTLB cgroup 上。
這意味著如果一個 HugeTLB cgroup 在仍記賬有 HugeTLB 預留時離線,該 cgroup 將作為殭屍狀態持續存在,直到所有 HugeTLB 預留都解除記賬。HugeTLB 預留的這種行為與記憶體控制器匹配,記憶體控制器的 cgroup 也會作為殭屍狀態持續存在,直到所有記賬的記憶體都解除記賬。此外,HugeTLB 預留的跟蹤比 HugeTLB 頁錯誤的跟蹤更復雜一些,因此在離線時重新分配預留的父級要困難得多。