Week 2 - Buddy System
本文章涵蓋基礎 Buddy system 和記憶體管理。
Memory management
Linux 將記憶體分成 node, zone, page 三層次管理。
在 NUMA 架構下,不同 NUMA node 用 QPI 等方式交換資料,由 Linux node 層次負責。
Zone 是 Linux 相容不同系統和記憶體大小,開發出來的記憶體分區機制。
ZONE_DMA
部分 ISA 設備只支援 24-bit 位址線,僅能存取 0-16MB 的記憶體,因此 kernel 畫出一片區域給這些設備使用。ZONE_DMA32
供 32-bit PCI 設備使用,道理與ZONE_DMA
相同。ZONE_NORMAL
存放 kernel 可直接存取的記憶體,像是 stack, kmalloc 分配的區域, page tables 等。
在 32-bit 系統上,會留 128MB 給 I/O 記憶體和 kernel 結構,因此只能映射 16MB-896MB 的物理記憶體。ZONE_HIGHMEM
記憶體超過 4GB 時,32-bit kernel 無法直接映射高於 896MB 的部分,只能透過額外的方法存取。64-bit 無此 zone。ZONE_MOVABLE
允許被遷移,用於防止物理 fragmentation。ZONE_DEVICE
供特殊記憶體使用。
1 | struct zone { |
struct page 為了節省空間,使用大量 union 結構。
index
在 virtual address 的偏移量private
用於管理此 page 的資料,像是 buddy system_mapcount
該 page 被多少 process 映射_refcount
該 page 現正被多少 process 使用lru
與zone->__lruvec
組成 link list
Buddy system
buddy system 分配記憶體都以 page 為單位,可申請 2^n page 大小的記憶體。
申請和釋放時,buddy system 維護 free_area
的結構,進行 page 拆分或合併。/proc/buddyinfo
得知各 order 中 free page 數。
alloc_pages
可向 buddy system 申請記憶體,order 表示區塊大小。
1 | static inline struct page *alloc_pages(gfp_t gfp_mask, unsigned int order) |
__get_free_pages
多了呼叫 page_address
得到 virtual address 的動作。
__GFP_DMA
從 ZONE_DMA 分配__GFP_MOVABLE
記憶體調整時可以遷移或回收 page__GFP_ATOMIC
允許分配最低 watermark 的預留區域__GFP_ZERO
內容填充為 0__GFP_KERNEL
分配時可被 block
若有 GFP_THISNODE
限制在 local node 分配,則使用默認分配策略。
若當前策略是 MPOL_INTERLEAVE
,就必須跨 node 分配,否則走 UMA 照常分配。
__alloc_page_nodemask
分配又分 fast path 和 slow path,fast path 從 buddy system 抓 page,slow path 會進行 swap, memory compaction 等操作。
free_area 在 zone 結構底下,free_list 是好幾個 link list,用 page->lru
串起來,一個 page 不會同時在 lru 和 buddy system。
1 | struct free_area { |
migration 是減少物理 external fragmentation 機制,不同 migrate type 代表 migration 可做的動作,free_area
為每個 type 創建一個 free_list
。
MIGRATE_UNMOVABLE
不能移動MIGRATE_MOVABLE
可隨意移動MIGRATE_RECLAIMABLE
不能直接移動,但可以刪除,例如映射自文件的 pageMIGRATE_PCPTYPES
遷移僅限於同一節點內MIGRATE_ISOLATE
不能從該 list 分配頁面,用於跨 NUMA 節點進行移動
釋放時用 free_pages
。
參考資料
- https://arttnba3.cn/2021/11/28/OS-0X02-LINUX-KERNEL-MEMORY-5.11-PART-I/
- https://arttnba3.cn/2022/06/30/OS-0X03-LINUX-KERNEL-MEMORY-5.11-PART-II/
- https://blog.csdn.net/yhb1047818384/article/details/112298996
- https://blog.csdn.net/yhb1047818384/article/details/114454299
- https://s3.shizhz.me/linux-mm/3.2-wu-li-nei-cun/3.2.4-buddy-system-huo-ban-xi-tong
- https://www.kernel.org/doc/gorman/html/understand/understand009.html