Please enable Javascript to view the contents

Kernel -Page Frame Management

 ·  ☕ 2 åˆ†é’Ÿ

Page Frame Management

Page Descriptors

一些地址的转换:

  • 宏 virt_to_page(addr) :输入一个线性的虚拟地址,返回相关的 Page Descriptor
  • 宏 pfn_to_page(pfn) :输入一个 page frame 的 number pfn,返回相关的 Page Descriptor

page descriptor 的数据结构:

image-20210301115706559

图出处:Understanding The Linux Kernel 3rd Edition
  • _count :引用计数,-1时可以回收
  • flags:

image-20210301120149822

image-20210301120301328

Non-Uniform Memory Access (NUMA)

在多CPU架构中,为提高内存访问的并发能力,有一种硬件架构设计,把物理内存分成几个组,这个组叫 node 。每个CPU归属于一个node。CPU 有专用线路去访问node的内存,CPU 访问非归属NODE的性能会更差 。

Node 的物理内存又再划分成多个 Zone。

每个 Node 对应一个数据结构(pg_data_t):

image-20210301122036513

Memory Zones

image-20210301143311688

对于 64-bit 架构,ZONE_HIGHMEM总是空的。

Zone 的数据结构:

image-20210301144556827

image-20210301144711895

image-20210301144739159

image-20210301144753381

很多 field 是在 Page 回收时用到的。

保留的 Page

要处理 Page 的分配,有两种情况:

  • 空闲内存足够时,直接使用
  • 空闲内存不足时,需要发起内存回收。而请求分配内存的线程需要挂起,直到回收到足够的内存

但有的内核程序不能被挂起,如:终断处理程序。这种情况下,程序应该使用atomic memory allocation requests(即内存分配请求时,用 GFP_ATOMIC标记)。这种分配请求,不会挂起,只会失败。

为最大程度减少atomic memory allocation requests失败的可能。内核保留了一块内存,只在可用内存少时才使用。这块内存的大小由配置 min_free_kbytes 指定。

Zone 的数据结构中,pages_min字段就表示本 zone 的保留 Page 数。

Zoned Page Frame Allocator

image-20210301151557776

Page 的分配经由 Zoned Page Frame Allocator 完成。每个CPU有一个快速分配的缓存区。

发起分配和回收

发起分配和回收有以下函数:

  • alloc_pages(gfp_mask, order) :分配连续的 Page,返回第一个 Page 的 Descriptor(元信息)
  • __get_free_pages(gfp_mask, order):功能同上,但返回第一个 Page 的线性地址。

gfp_mask

image-20210301152715825

组合:

image-20210301152734871

Buddy System 算法

所有空闲 Page 以连续的 Page 数,分组为 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 。数字为连续的 Page 数。

初始时,每个块的首个 page 的物理地址是组大小的倍数。

数据源

每个内存的 Zone 都有自己的 Buddy System。

Zone Allocator

Zone Allocator 作为内核 Page Frame Allocator 的前端。它要实现:

  • 保护保留的 Page
  • 触发Page回收。当空闲Page不足,且当前进程允许挂起时,它将触发Page回收,并重试分配

参考

https://www.kernel.org/doc/gorman/html/understand/understand005.html

[Understanding The Linux Kernel 3rd Edition]

Chapter 2 Describing Physical Memory

分享

Mark Zhu
作者
Mark Zhu
Old Developer