0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

物理內(nèi)存模型的演變

jf_0tjVfeJz ? 來源:嵌入式ARM和Linux ? 2024-02-25 10:35 ? 次閱讀

內(nèi)存管理概述中,主要是以Linux v2.6.11為例進(jìn)行分析的,但是計(jì)算技術(shù)在不斷發(fā)展,新的存儲(chǔ)架構(gòu)、新的指令集架構(gòu)、新的SoC架構(gòu)等都對(duì)物理內(nèi)存模型的抽象提出了更高要求。為此,必須抽象一種完全獨(dú)立于硬件架構(gòu)的物理內(nèi)存模型。

1 NUMA和UMA

第一個(gè)要解決的問題就是非一致性內(nèi)存訪問(NUMA)。對(duì)于多核和多內(nèi)存卡插槽的機(jī)器,內(nèi)存位于不同的分組中,那么與處理器的距離不同,就會(huì)產(chǎn)生訪問時(shí)間的差異。比如,可以將一組內(nèi)存更靠近CPU,另一組內(nèi)存更靠近外設(shè),作為訪問外設(shè)的DMA內(nèi)存。

這樣的每個(gè)分組稱為一個(gè)節(jié)點(diǎn)(node)。不管是NUMA架構(gòu),還是UMA架構(gòu),Linux提供了一個(gè)統(tǒng)一的數(shù)據(jù)結(jié)構(gòu)struct pglist_data表示節(jié)點(diǎn)信息。該列表中是類型為pg_data_t的數(shù)據(jù)結(jié)構(gòu),描述一個(gè)具體的節(jié)點(diǎn),該數(shù)據(jù)結(jié)構(gòu)可以通過NODE_DATA(nid)引用,這兒nid表示節(jié)點(diǎn)的ID。

對(duì)于NUMA架構(gòu),node數(shù)據(jù)結(jié)構(gòu)是由特定于架構(gòu)的代碼在boot階段分配的。通常,這些數(shù)據(jù)結(jié)構(gòu)分配的就是本地的內(nèi)存組(也就是離它們近的內(nèi)存)。對(duì)于UMA體系結(jié)構(gòu),只使用一個(gè)名為cong_page_data的靜態(tài)pg_data_t結(jié)構(gòu)。節(jié)點(diǎn)將在下一節(jié)討論。

2 內(nèi)存分區(qū)(memory zone)

節(jié)點(diǎn)內(nèi)的物理內(nèi)存被劃分為一個(gè)或多個(gè)區(qū),這樣的區(qū)稱為Zone。這些內(nèi)存分區(qū)的劃分通常由硬件架構(gòu)訪問物理內(nèi)存的限制決定。ZONE在內(nèi)核中的數(shù)據(jù)類型是zone_t,結(jié)構(gòu)是zone。zone的分類類型如下所示:

ZONE_DMA和ZONE_DMA32

當(dāng)外設(shè)無法DMA訪問所有可尋址內(nèi)存(ZONE_NORMAL)時(shí),使用ZONE_DMA和ZONE_DMA32。ZONE_DMA32用于覆蓋整個(gè)32位地址空間的架構(gòu)上。ZONE_DMA留給具有較小DMA尋址限制的區(qū)域。這種區(qū)別很重要,因?yàn)槎xZONE_DMA32時(shí)假定使用32位DMA掩碼。某些64位平臺(tái)可能需要2個(gè)區(qū)域,因?yàn)樗鼈冎С志哂胁煌珼MA尋址限制的外設(shè)。雖然近些年提供了更好、更強(qiáng)大的接口分配DMA內(nèi)存(使用通用設(shè)備的動(dòng)態(tài)DMA映射),但ZONE_DMA和ZONE_DMA32仍然表示對(duì)其訪問方式受限制的內(nèi)存。根據(jù)架構(gòu)不同,可以使用CONFIG_ZONE_DMA和CONFIG_ZONE_DMA32配置選項(xiàng),在構(gòu)建內(nèi)核時(shí),禁用這些內(nèi)存區(qū)域。

ZONE_NORMAL

普通內(nèi)存,內(nèi)核一直可以訪問的內(nèi)存區(qū)。如果DMA設(shè)備支持向所有可尋址內(nèi)存的傳輸,則可以對(duì)這些內(nèi)存頁(yè)執(zhí)行DMA操作。ZONE_NORMAL總是使能。

ZONE_HIGHMEM

是內(nèi)核頁(yè)表中永久映射未覆蓋的物理內(nèi)存部分。這個(gè)區(qū)域中的內(nèi)存只能由內(nèi)核使用臨時(shí)映射訪問。該區(qū)域僅在某些32位體系結(jié)構(gòu)上可用,并通過CONFIG_HIGHMEM啟用。

ZONE_MOVABLE

與ZONE_NORMAL類似。不同之處是ZONE_MOVABLE區(qū)的內(nèi)存頁(yè)是可移動(dòng)的。也就是說,在這些內(nèi)存頁(yè)的虛擬地址不改變的情況下,他們的內(nèi)容可以在不同的物理內(nèi)存頁(yè)之間搬運(yùn)。ZONE_MOVABLE通常在內(nèi)存熱插拔期間進(jìn)行填充,但也可以在boot階段,使用kernelcore、movablecore和movable_node命令行參數(shù)之一進(jìn)行填充。具體可以參考內(nèi)存頁(yè)遷移和熱插拔

ZONE_DEVICE

表示駐留在PMEM和GPU等設(shè)備上的內(nèi)存。它和內(nèi)存ZONE類型有著不同,它的存在是為了設(shè)備驅(qū)動(dòng)程序的物理內(nèi)存范圍提供page和內(nèi)存映射服務(wù)。ZONE_DEVICE可以通過配置選項(xiàng)CONFIG_ZONE_DEVICE使能。設(shè)備內(nèi)存熱插拔支持在mem_map中建立PMEM或其它設(shè)備驅(qū)動(dòng)程序發(fā)現(xiàn)的內(nèi)存區(qū)域。這允許pfn_to_page()查找“設(shè)備物理”地址,這是在O_DIRECT操作中使用DAX映射所需要的。

需要注意的是,許多內(nèi)核操作只能使用ZONE_NORMAL進(jìn)行,因此它是性能最關(guān)鍵的ZONE區(qū)。

節(jié)點(diǎn)和ZONE之間的關(guān)系由固件報(bào)告的物理內(nèi)存映射、內(nèi)存尋址的體系結(jié)構(gòu)約束和內(nèi)核命令行中的某些參數(shù)決定。

例如,對(duì)于具有2GB內(nèi)存的x86 UMA架構(gòu)內(nèi)核,整個(gè)內(nèi)存將位于節(jié)點(diǎn)0上,分為3個(gè)區(qū)域:“ZONE_DMA”、“ZONE_NORMAL”和“ZONE_HIGHMEM”:

02G
+-------------------------------------------------------------+
|node0|
+-------------------------------------------------------------+

016M896M2G
+----------+-----------------------+--------------------------+
|ZONE_DMA|ZONE_NORMAL|ZONE_HIGHMEM|
+----------+-----------------------+--------------------------+

ARM64機(jī)器上禁用ZONE_DMA并啟用ZONE_DMA32的同時(shí),使用movablecore = 80%參數(shù)啟動(dòng)內(nèi)核時(shí),在兩個(gè)節(jié)點(diǎn)之間平均分配16G內(nèi)存,則節(jié)點(diǎn)0上將有ZONE_DMA32,ZONE_NORMAL和ZONE_MOVABLE,節(jié)點(diǎn)1上將有ZONE_NORMAL和ZONE_MOVABLE:

1G9G17G
+--------------------------------++--------------------------+
|node0||node1|
+--------------------------------++--------------------------+

1G4G4200M9G9320M17G
+---------+----------+-----------++------------+-------------+
|DMA32|NORMAL|MOVABLE||NORMAL|MOVABLE|
+---------+----------+-----------++------------+-------------+

內(nèi)存組也可以交替分配給節(jié)點(diǎn)。在下面的示例中,x86機(jī)器具有16G的內(nèi)存,分為4組,偶數(shù)組屬于節(jié)點(diǎn)0,奇數(shù)組屬于節(jié)點(diǎn)1:

04G8G12G16G
+-------------++-------------++-------------++-------------+
|node0||node1||node0||node1|
+-------------++-------------++-------------++-------------+

016M4G
+-----+-------++-------------++-------------++-------------+
|DMA|DMA32||NORMAL||NORMAL||NORMAL|
+-----+-------++-------------++-------------++-------------+

在這種情況下,節(jié)點(diǎn)0將橫跨0→12G,節(jié)點(diǎn)1將橫跨4→16G。

3 節(jié)點(diǎn)

正如我們所提到的,內(nèi)存中的每個(gè)節(jié)點(diǎn)都由pg_data_t描述,pg_data_t是結(jié)構(gòu)體pglist_data的類型定義。在分配頁(yè)面時(shí),默認(rèn)情況下Linux使用節(jié)點(diǎn)本地分配策略,從離運(yùn)行CPU最近的節(jié)點(diǎn)分配內(nèi)存。由于進(jìn)程傾向于在同一個(gè)CPU上運(yùn)行,因此很可能會(huì)使用當(dāng)前節(jié)點(diǎn)的內(nèi)存。分配策略可以由用戶控制,詳見NUMA內(nèi)存策略。

大多數(shù)NUMA體系結(jié)構(gòu)維護(hù)一個(gè)指向node結(jié)構(gòu)的指針數(shù)組。實(shí)際的結(jié)構(gòu)是在boot過程的早期分配的,當(dāng)特定于體系結(jié)構(gòu)的代碼解析固件報(bào)告的物理內(nèi)存映射時(shí)。節(jié)點(diǎn)初始化的大部分在boot過程中稍晚的時(shí)候通過free_area_init()函數(shù)進(jìn)行,稍后將在初始化一節(jié)中描述。

除了node結(jié)構(gòu),內(nèi)核還維護(hù)一個(gè)名為node_states的nodemask_t位掩碼數(shù)組。這個(gè)數(shù)組中的每個(gè)位掩碼代表一組具有特定屬性的節(jié)點(diǎn),這些屬性由enum node_states定義:

N_POSSIBLE

節(jié)點(diǎn)可能在某個(gè)時(shí)間點(diǎn)在線。

N_ONLINE

節(jié)點(diǎn)在線。

N_NORMAL_MEMORY

節(jié)點(diǎn)具有常規(guī)內(nèi)存。

N_HIGH_MEMORY

節(jié)點(diǎn)具有常規(guī)內(nèi)存或高端內(nèi)存。當(dāng)CONFIG_HIGHMEM被禁用時(shí),別名為N_NORMAL_MEMORY。

N_MEMORY

節(jié)點(diǎn)具有內(nèi)存(常規(guī)、高、可移動(dòng)).

N_CPU

節(jié)點(diǎn)內(nèi)CPU數(shù)量。

對(duì)于具有上述屬性的每個(gè)節(jié)點(diǎn),將設(shè)置與node_states[]位掩碼中節(jié)點(diǎn)ID對(duì)應(yīng)的位。

例如,節(jié)點(diǎn)2,具有常規(guī)內(nèi)存和CPU,位2將在下面設(shè)置:

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]

關(guān)于nodemask的各種操作,請(qǐng)參考include/linux/nodemask.h。

有了節(jié)點(diǎn)之后,LRU列表、頁(yè)回收機(jī)制、交換區(qū)(kswapd)等等都需要在NONE分區(qū)之上添加處理。細(xì)節(jié)在此不再詳述。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • soc
    soc
    +關(guān)注

    關(guān)注

    38

    文章

    4065

    瀏覽量

    217550
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11161

    瀏覽量

    208467
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    2942

    瀏覽量

    73728
  • 模型
    +關(guān)注

    關(guān)注

    1

    文章

    3058

    瀏覽量

    48572

原文標(biāo)題:Linux內(nèi)核8.9-內(nèi)存管理進(jìn)階之物理內(nèi)存模型的演變

文章出處:【微信號(hào):嵌入式ARM和Linux,微信公眾號(hào):嵌入式ARM和Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux的內(nèi)存管理是什么,Linux的內(nèi)存管理詳解

    物理內(nèi)存模型 ? ? ? 物理內(nèi)存模型主要分為兩種:UMA(Uniform Memory Ac
    的頭像 發(fā)表于 05-11 17:54 ?5900次閱讀
    Linux的<b class='flag-5'>內(nèi)存</b>管理是什么,Linux的<b class='flag-5'>內(nèi)存</b>管理詳解

    Linux內(nèi)核的物理內(nèi)存組織結(jié)構(gòu)詳解

    Linux中內(nèi)存管理子系統(tǒng)使用 節(jié)點(diǎn)(node)、區(qū)域(zone)和頁(yè)(page) 三級(jí)結(jié)構(gòu)描述物理內(nèi)存。
    發(fā)表于 08-21 15:35 ?512次閱讀
    Linux內(nèi)核的<b class='flag-5'>物理</b><b class='flag-5'>內(nèi)存</b>組織結(jié)構(gòu)詳解

    用labview模擬物理模型

    課程推薦:http://z.elecfans.com/258.html?elecfans_trackid=bbs_toptxtlabview是很神奇的,可以模擬物理模型,挺好玩的
    發(fā)表于 05-13 22:55

    如何使用Simscape Multibody的物理建模模塊來建立倒立擺模型?

    Multibody的物理建模模塊來建立倒立擺模型。Simscape庫(kù)中的塊代表實(shí)際的物理組件;因此,可以構(gòu)建復(fù)雜的多體動(dòng)力學(xué)模型,而無需通過物理
    發(fā)表于 07-07 06:16

    物理內(nèi)存和虛擬內(nèi)存之間的轉(zhuǎn)換

    內(nèi)存操作:涉及到了物理內(nèi)存和虛擬內(nèi)存之間的轉(zhuǎn)換,需要用到兩個(gè)函數(shù): ioremap 和 iounmap。ioremap :函 數(shù) 用 于 獲 取 指 定 物 理 地 址 空 間 對(duì) 應(yīng)
    發(fā)表于 12-17 06:48

    Linux虛擬內(nèi)存物理內(nèi)存的深刻分析

    進(jìn)程這種情況,浪費(fèi)內(nèi)存!第二層理解每個(gè)進(jìn)程的4G內(nèi)存空間只是虛擬內(nèi)存空間,每次訪問內(nèi)存空間的某個(gè)地址,都需要把地址翻譯為實(shí)際物理
    發(fā)表于 05-31 08:00

    UMTS的物理結(jié)構(gòu)模型

    UMTS的物理結(jié)構(gòu)模型
    發(fā)表于 09-18 15:13 ?1230次閱讀

    NetWare內(nèi)存模型與NetWare組網(wǎng)的介紹

    NetWare內(nèi)存模型 N e t Ware 4.x只可以使用物理內(nèi)存, N e t Ware 5.0可以同時(shí)使用物理
    發(fā)表于 11-23 17:51 ?3次下載

    如何避免Linux的物理內(nèi)存碎片化

    Linux buddyy系統(tǒng)是linux kernel比較穩(wěn)定的一個(gè)模塊,但是并不是說它沒有缺陷,Linux內(nèi)存管理系統(tǒng)自誕生之日,就一直存在物理內(nèi)存碎片化的問題:在系統(tǒng)啟動(dòng)并且運(yùn)行很長(zhǎng)一段時(shí)間后
    的頭像 發(fā)表于 05-01 16:43 ?5409次閱讀
    如何避免Linux的<b class='flag-5'>物理</b><b class='flag-5'>內(nèi)存</b>碎片化

    淺析計(jì)算機(jī)中物理內(nèi)存模型

    個(gè)人感覺學(xué)這部分的知識(shí)應(yīng)該首先在腦海中抽象出存儲(chǔ)體系,因?yàn)闊o論磁盤,物理內(nèi)存還是虛擬內(nèi)存都是互相有聯(lián)系的,抽象出模型有助于我們的理解和記憶。接著需要哪部分知識(shí)或再次深入哪部分知識(shí),從體
    的頭像 發(fā)表于 08-28 16:29 ?4327次閱讀

    了解并學(xué)習(xí)Linux內(nèi)存模型

    在linux內(nèi)核中支持3中內(nèi)存模型,分別是flat memory model,Discontiguous memory model和sparse memory model。所謂memory
    發(fā)表于 05-12 09:44 ?665次閱讀
    了解并學(xué)習(xí)Linux<b class='flag-5'>內(nèi)存</b><b class='flag-5'>模型</b>

    電腦物理內(nèi)存過高的處理技巧

    電腦物理內(nèi)存過高的處理技巧。很多時(shí)候,我們的一些電腦管家或者電腦助手都總會(huì)顯示內(nèi)存過大,需要我們及時(shí)清理。其實(shí)這一種提示中的內(nèi)存過大,不是指我們的電腦中的
    發(fā)表于 06-19 10:26 ?3126次閱讀
    電腦<b class='flag-5'>物理</b><b class='flag-5'>內(nèi)存</b>過高的處理技巧

    內(nèi)存是怎么映射到物理地址空間的?內(nèi)存是連續(xù)分布的嗎?

    如果我們將兩個(gè)4G內(nèi)存插入內(nèi)存插槽,得到的內(nèi)存地址空間是0到8G嗎?是不是0到4G是第一根內(nèi)存,4到8G是第二根內(nèi)存呢?實(shí)際情況相差甚遠(yuǎn),
    的頭像 發(fā)表于 06-30 15:59 ?2981次閱讀
    <b class='flag-5'>內(nèi)存</b>是怎么映射到<b class='flag-5'>物理</b>地址空間的?<b class='flag-5'>內(nèi)存</b>是連續(xù)分布的嗎?

    jvm內(nèi)存模型內(nèi)存結(jié)構(gòu)

    JVM(Java虛擬機(jī))是Java程序的運(yùn)行平臺(tái),它負(fù)責(zé)將Java程序轉(zhuǎn)換成機(jī)器碼并在計(jì)算機(jī)上執(zhí)行。在JVM中,內(nèi)存模型內(nèi)存結(jié)構(gòu)是兩個(gè)重要的概念,本文將詳細(xì)介紹它們。 一、JVM內(nèi)存
    的頭像 發(fā)表于 12-05 11:08 ?791次閱讀

    邏輯內(nèi)存物理內(nèi)存的區(qū)別

    邏輯內(nèi)存物理內(nèi)存是計(jì)算機(jī)系統(tǒng)中兩個(gè)重要的概念,它們?cè)谟?jì)算機(jī)的運(yùn)行和數(shù)據(jù)處理中起著至關(guān)重要的作用。 1. 物理內(nèi)存(Physical Mem
    的頭像 發(fā)表于 09-27 15:38 ?243次閱讀