內存管理概述中,主要是以Linux v2.6.11為例進行分析的,但是計算技術在不斷發展,新的存儲架構、新的指令集架構、新的SoC架構等都對物理內存模型的抽象提出了更高要求。為此,必須抽象一種完全獨立于硬件架構的物理內存模型。
1 NUMA和UMA
第一個要解決的問題就是非一致性內存訪問(NUMA)。對于多核和多內存卡插槽的機器,內存位于不同的分組中,那么與處理器的距離不同,就會產生訪問時間的差異。比如,可以將一組內存更靠近CPU,另一組內存更靠近外設,作為訪問外設的DMA內存。
這樣的每個分組稱為一個節點(node)。不管是NUMA架構,還是UMA架構,Linux提供了一個統一的數據結構struct pglist_data表示節點信息。該列表中是類型為pg_data_t的數據結構,描述一個具體的節點,該數據結構可以通過NODE_DATA(nid)引用,這兒nid表示節點的ID。
對于NUMA架構,node數據結構是由特定于架構的代碼在boot階段分配的。通常,這些數據結構分配的就是本地的內存組(也就是離它們近的內存)。對于UMA體系結構,只使用一個名為cong_page_data的靜態pg_data_t結構。節點將在下一節討論。
2 內存分區(memory zone)
節點內的物理內存被劃分為一個或多個區,這樣的區稱為Zone。這些內存分區的劃分通常由硬件架構訪問物理內存的限制決定。ZONE在內核中的數據類型是zone_t,結構是zone。zone的分類類型如下所示:
ZONE_DMA和ZONE_DMA32
當外設無法DMA訪問所有可尋址內存(ZONE_NORMAL)時,使用ZONE_DMA和ZONE_DMA32。ZONE_DMA32用于覆蓋整個32位地址空間的架構上。ZONE_DMA留給具有較小DMA尋址限制的區域。這種區別很重要,因為定義ZONE_DMA32時假定使用32位DMA掩碼。某些64位平臺可能需要2個區域,因為它們支持具有不同DMA尋址限制的外設。雖然近些年提供了更好、更強大的接口分配DMA內存(使用通用設備的動態DMA映射),但ZONE_DMA和ZONE_DMA32仍然表示對其訪問方式受限制的內存。根據架構不同,可以使用CONFIG_ZONE_DMA和CONFIG_ZONE_DMA32配置選項,在構建內核時,禁用這些內存區域。
ZONE_NORMAL
普通內存,內核一直可以訪問的內存區。如果DMA設備支持向所有可尋址內存的傳輸,則可以對這些內存頁執行DMA操作。ZONE_NORMAL總是使能。
ZONE_HIGHMEM
是內核頁表中永久映射未覆蓋的物理內存部分。這個區域中的內存只能由內核使用臨時映射訪問。該區域僅在某些32位體系結構上可用,并通過CONFIG_HIGHMEM啟用。
ZONE_MOVABLE
與ZONE_NORMAL類似。不同之處是ZONE_MOVABLE區的內存頁是可移動的。也就是說,在這些內存頁的虛擬地址不改變的情況下,他們的內容可以在不同的物理內存頁之間搬運。ZONE_MOVABLE通常在內存熱插拔期間進行填充,但也可以在boot階段,使用kernelcore、movablecore和movable_node命令行參數之一進行填充。具體可以參考內存頁遷移和熱插拔
ZONE_DEVICE
表示駐留在PMEM和GPU等設備上的內存。它和內存ZONE類型有著不同,它的存在是為了設備驅動程序的物理內存范圍提供page和內存映射服務。ZONE_DEVICE可以通過配置選項CONFIG_ZONE_DEVICE使能。設備內存熱插拔支持在mem_map中建立PMEM或其它設備驅動程序發現的內存區域。這允許pfn_to_page()查找“設備物理”地址,這是在O_DIRECT操作中使用DAX映射所需要的。
需要注意的是,許多內核操作只能使用ZONE_NORMAL進行,因此它是性能最關鍵的ZONE區。
節點和ZONE之間的關系由固件報告的物理內存映射、內存尋址的體系結構約束和內核命令行中的某些參數決定。
例如,對于具有2GB內存的x86 UMA架構內核,整個內存將位于節點0上,分為3個區域:“ZONE_DMA”、“ZONE_NORMAL”和“ZONE_HIGHMEM”:
02G +-------------------------------------------------------------+ |node0| +-------------------------------------------------------------+ 016M896M2G +----------+-----------------------+--------------------------+ |ZONE_DMA|ZONE_NORMAL|ZONE_HIGHMEM| +----------+-----------------------+--------------------------+
在ARM64機器上禁用ZONE_DMA并啟用ZONE_DMA32的同時,使用movablecore = 80%參數啟動內核時,在兩個節點之間平均分配16G內存,則節點0上將有ZONE_DMA32,ZONE_NORMAL和ZONE_MOVABLE,節點1上將有ZONE_NORMAL和ZONE_MOVABLE:
1G9G17G +--------------------------------++--------------------------+ |node0||node1| +--------------------------------++--------------------------+ 1G4G4200M9G9320M17G +---------+----------+-----------++------------+-------------+ |DMA32|NORMAL|MOVABLE||NORMAL|MOVABLE| +---------+----------+-----------++------------+-------------+
內存組也可以交替分配給節點。在下面的示例中,x86機器具有16G的內存,分為4組,偶數組屬于節點0,奇數組屬于節點1:
04G8G12G16G +-------------++-------------++-------------++-------------+ |node0||node1||node0||node1| +-------------++-------------++-------------++-------------+ 016M4G +-----+-------++-------------++-------------++-------------+ |DMA|DMA32||NORMAL||NORMAL||NORMAL| +-----+-------++-------------++-------------++-------------+
在這種情況下,節點0將橫跨0→12G,節點1將橫跨4→16G。
3 節點
正如我們所提到的,內存中的每個節點都由pg_data_t描述,pg_data_t是結構體pglist_data的類型定義。在分配頁面時,默認情況下Linux使用節點本地分配策略,從離運行CPU最近的節點分配內存。由于進程傾向于在同一個CPU上運行,因此很可能會使用當前節點的內存。分配策略可以由用戶控制,詳見NUMA內存策略。
大多數NUMA體系結構維護一個指向node結構的指針數組。實際的結構是在boot過程的早期分配的,當特定于體系結構的代碼解析固件報告的物理內存映射時。節點初始化的大部分在boot過程中稍晚的時候通過free_area_init()函數進行,稍后將在初始化一節中描述。
除了node結構,內核還維護一個名為node_states的nodemask_t位掩碼數組。這個數組中的每個位掩碼代表一組具有特定屬性的節點,這些屬性由enum node_states定義:
N_POSSIBLE
節點可能在某個時間點在線。
N_ONLINE
節點在線。
N_NORMAL_MEMORY
節點具有常規內存。
N_HIGH_MEMORY
節點具有常規內存或高端內存。當CONFIG_HIGHMEM被禁用時,別名為N_NORMAL_MEMORY。
N_MEMORY
節點具有內存(常規、高、可移動).
N_CPU
節點內CPU數量。
對于具有上述屬性的每個節點,將設置與node_states[
例如,節點2,具有常規內存和CPU,位2將在下面設置:
node_states[N_POSSIBLE] node_states[N_ONLINE] node_states[N_NORMAL_MEMORY] node_states[N_HIGH_MEMORY] node_states[N_MEMORY] node_states[N_CPU]
關于nodemask的各種操作,請參考include/linux/nodemask.h。
有了節點之后,LRU列表、頁回收機制、交換區(kswapd)等等都需要在NONE分區之上添加處理。細節在此不再詳述。
審核編輯:湯梓紅
-
soc
+關注
關注
38文章
4212瀏覽量
219178 -
Linux
+關注
關注
87文章
11351瀏覽量
210498 -
內存
+關注
關注
8文章
3064瀏覽量
74374 -
模型
+關注
關注
1文章
3340瀏覽量
49267
原文標題:Linux內核8.9-內存管理進階之物理內存模型的演變
文章出處:【微信號:嵌入式ARM和Linux,微信公眾號:嵌入式ARM和Linux】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論