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)存內(nèi)核中發(fā)生頁面遷移的典型場景

Linux愛好者 ? 來源:知乎 ? 2023-11-08 12:28 ? 次閱讀

1. 概述

頁面遷移(page migrate)最早是為NUMA系統(tǒng)提供一種將進(jìn)程頁面遷移到指定內(nèi)存節(jié)點(diǎn)的能力用來提升訪問性能。后來在內(nèi)核中廣泛被使用,如內(nèi)存規(guī)整、CMA、內(nèi)存hotplug等。

頁面遷移對(duì)上層應(yīng)用業(yè)務(wù)來說是不可感知的,因?yàn)槠溥w移的是物理頁面,而應(yīng)用只訪問的是虛擬內(nèi)存。內(nèi)核遷移完成后,更新修改對(duì)應(yīng)頁表指向遷移后的頁面即可。當(dāng)然了這里說的不可感知是指業(yè)務(wù)不太關(guān)注,也不需要做對(duì)應(yīng)修改。實(shí)際上有些場景發(fā)生頁面遷移是業(yè)務(wù)性能是有影響的,下面會(huì)詳細(xì)描述。

2. 典型場景

我們列舉2個(gè)內(nèi)核中發(fā)生頁面遷移的典型場景。

2.1 NUMA Balancing引起的頁面遷移

在典型 NUMA 中,存在多個(gè) node, 本地 CPU 訪問本地 node 節(jié)點(diǎn)對(duì)應(yīng)的 memory 性能會(huì)快一些。

8acebe30-7dea-11ee-939d-92fbcf53809c.png

Linux 的 NUMA 自動(dòng)均衡機(jī)制會(huì)嘗試將內(nèi)存遷移到正在訪問它的 CPU 節(jié)點(diǎn)所在的 node。如下圖所示,CPU24 ~ CPU47訪問不是本地 node 對(duì)應(yīng)的 memory,性能會(huì)比較慢,系統(tǒng)會(huì)將其遷移到本地 node 對(duì)應(yīng)的 memory 以提升訪問性能。

8af5dbbe-7dea-11ee-939d-92fbcf53809c.png

遷移后如下圖:

8b1387d6-7dea-11ee-939d-92fbcf53809c.png

2.2 內(nèi)存碎片整理

系統(tǒng)使用一段時(shí)候后,由于內(nèi)存碎片的原因,較難滿足連續(xù)內(nèi)存需求,如果需要分配連續(xù)大塊內(nèi)存,需要進(jìn)行內(nèi)存規(guī)整以形成大塊連續(xù)內(nèi)存,頁面遷移是內(nèi)存碎片整理的基礎(chǔ)。

3. 實(shí)現(xiàn)分析

3.1 遷移模式

內(nèi)核中通過接口migrate_pages實(shí)現(xiàn)頁而遷移, 分為3個(gè)模式。

模式 簡介 應(yīng)用場景
MIGRATE_ASYNC 異步遷移,過程中不會(huì)發(fā)生阻塞 內(nèi)存分配slowpath
MIGRATE_SYNC_LIGHT 輕度同步遷移,允許大部分的阻塞操作,唯獨(dú)不允許臟頁的回寫操作 kcompactd觸發(fā)的規(guī)整
MIGRATE_SYNC 同步遷移,遷移過程會(huì)發(fā)生阻塞,若需要遷移的某個(gè)page正在writeback或被locked會(huì)等待它完成 sysfs主動(dòng)觸發(fā)的內(nèi)存規(guī)整
MIGRATE_SYNC_NO_COPY 同步遷移,但不等待頁面的拷貝過程。頁面的拷貝通過回調(diào)migratepage(),過程可能會(huì)涉及DMA migrate_vma_pages

3.2 實(shí)現(xiàn)流程

內(nèi)核文檔有描述這個(gè)API是怎么工作的。不過這個(gè)描述著實(shí)是不太友好, 不容易在腦海形成畫面。

8b3ac846-7dea-11ee-939d-92fbcf53809c.png

我們通過結(jié)合代碼實(shí)現(xiàn),把這個(gè)轉(zhuǎn)化為流程圖:

8b69551c-7dea-11ee-939d-92fbcf53809c.jpg

總結(jié)一下,頁面遷移過程本質(zhì)就是分配一個(gè) new_page, 解除原有 page 映射,把舊 page 復(fù)制到新 page 并建立新 page 的映射。

4. 頁面遷移過程用戶態(tài)訪問處理

到這里可能會(huì)有疑問:如果在頁面遷移過程中,應(yīng)用發(fā)生發(fā)訪問這個(gè)遷移中的頁面,會(huì)發(fā)生什么?

情景1: 舊頁面的頁表還未解映射, 此時(shí)發(fā)生缺頁可以正常訪問原來頁面。

8b85670c-7dea-11ee-939d-92fbcf53809c.jpg

情景2: 舊頁面解除了映射,但新頁面還未建立映射。這時(shí)訪問會(huì)發(fā)生等待,需要等新頁面建立映射并copy完成頁面后才能訪問。

8b964086-7dea-11ee-939d-92fbcf53809c.jpg

情景3: 完成了頁面遷移動(dòng)作,可以正常訪問新頁面了。

8baf4310-7dea-11ee-939d-92fbcf53809c.jpg

下面我們重點(diǎn)分析一下,當(dāng)舊頁面解除了映射,且新頁面未建立映射這個(gè)過程中發(fā)生了用戶態(tài)訪問,內(nèi)核的處理流程是怎樣的。

首先我們看一下舊頁面解除了映射的過程:

staticbooltry_to_unmap_one(structpage*page,structvm_area_struct*vma,
unsignedlongaddress,void*arg)
{
...
if(PageHWPoison(page)&&!(flags&TTU_IGNORE_HWPOISON)){

...
}elseif(pte_unused(pteval)&&!userfaultfd_armed(vma)){
...
}elseif(IS_ENABLED(CONFIG_MIGRATION)&&
(flags&(TTU_MIGRATION|TTU_SPLIT_FREEZE))){
// 頁面遷移會(huì)設(shè)置TTU_MIGRATION標(biāo)記,走到這個(gè)分支來
swp_entry_tentry;
pte_tswp_pte;

if(arch_unmap_one(mm,vma,address,pteval)

解除映射后,再次發(fā)生映射就走到do_swap_page中了。

vm_fault_tdo_swap_page(structvm_fault*vmf)
{
...
//獲取到這是一個(gè)在遷移過程的的PTE的標(biāo)識(shí)
entry=pte_to_swp_entry(vmf->orig_pte);
if(unlikely(non_swap_entry(entry))){//不是傳統(tǒng)的Swapentry
if(is_migration_entry(entry)){//是遷移標(biāo)記進(jìn)來的
/*等待migration的完成。本質(zhì)是在等待舊page釋放其page lock
*最終調(diào)用到wait_on_page_bit_common
*/
migration_entry_wait(vma->vm_mm,vmf->pmd,vmf->address);
}
...
}

總結(jié)一下:

頁面遷移前,首先會(huì)獲取舊頁面和新頁面的頁面鎖PG_lock,在解除映射的時(shí)候傳入了由于頁面遷移導(dǎo)致的解映射標(biāo)記TTU_MIGRATION,設(shè)置了此標(biāo)記會(huì)生成一個(gè)帶頁面遷移標(biāo)識(shí)的swap_entry設(shè)置到pte中。在設(shè)置好的那一刻走,應(yīng)用進(jìn)程無法很順利地訪問這個(gè)頁面了,需要通過do_swap_entry路徑。

假如此時(shí)應(yīng)用進(jìn)程訪問了這個(gè)頁面,會(huì)走進(jìn)到do_swap_entry,取出帶遷移標(biāo)識(shí)的swap_entry,識(shí)別到這個(gè)標(biāo)識(shí),會(huì)等待頁面鎖釋放。頁面鎖只有在頁面遷移完成后才會(huì)被釋放,也就是會(huì)發(fā)生等待直到頁面遷移完成。

5. 用戶態(tài)如何避免發(fā)生頁面遷移

上面我們已經(jīng)知道,如果有頁面遷移過程中發(fā)生用戶態(tài)訪問,很可能是需要發(fā)生等待其遷移完成, 這個(gè)過程需要一定耗時(shí)。而有時(shí)的場景我們是需要避免此種時(shí)延抖動(dòng),那有什么辦法呢?

方法就是讓這個(gè)頁面短時(shí)間內(nèi)變得不可移動(dòng)。

intmigrate_page_move_mapping(structaddress_space*mapping,
structpage*newpage,structpage*page,intextra_count)
{
...
if(page_count(page)!=expected_count)
return-EAGAIN;
...
returnMIGRATEPAGE_SUCCESS;
}

可以看到當(dāng)發(fā)生頁面復(fù)制過程中,如果 page 的引用計(jì)數(shù)不符合預(yù)期(期望為0)時(shí),這時(shí)系統(tǒng)認(rèn)為有人在使用,不適用做遷移。那么,我們只需要增加 page 的引用計(jì)數(shù)就可以。

可以在不想被遷移的時(shí)間段開始前通過pin_user_pages這樣的接口,結(jié)束時(shí)unpin就可以了。接口最終會(huì)調(diào)到try_grab_page增加引用計(jì)數(shù)。

bool__must_checktry_grab_page(structpage*page,unsignedintflags)
{
...
refs=GUP_PIN_COUNTING_BIAS;//#defineGUP_PIN_COUNTING_BIAS(1U<

編輯:黃飛

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

    關(guān)注

    68

    文章

    10804

    瀏覽量

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

    關(guān)注

    8

    文章

    2966

    瀏覽量

    73812
  • CMA
    CMA
    +關(guān)注

    關(guān)注

    0

    文章

    26

    瀏覽量

    9784
  • 虛擬內(nèi)存
    +關(guān)注

    關(guān)注

    0

    文章

    70

    瀏覽量

    8046

原文標(biāo)題:圖解|內(nèi)存頁面遷移技術(shù)

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)存管理之頁面回收

    請(qǐng)求調(diào)頁機(jī)制,只要用戶態(tài)進(jìn)程繼續(xù)執(zhí)行,他們就能獲得頁框,然而,請(qǐng)求調(diào)頁沒有辦法強(qiáng)制進(jìn)程釋放不再使用的頁框。因此,遲早所有空閑內(nèi)存將被分配給進(jìn)程和高速緩存,Linux內(nèi)核頁面回收算法(PFRA)采取從用戶進(jìn)程和
    發(fā)表于 05-19 14:09 ?1050次閱讀
    Linux<b class='flag-5'>內(nèi)存</b>管理之<b class='flag-5'>頁面</b>回收

    走進(jìn)Linux內(nèi)存系統(tǒng)探尋內(nèi)存管理的機(jī)制和奧秘

    Linux 內(nèi)存是后臺(tái)開發(fā)人員,需要深入了解的計(jì)算機(jī)資源。合理的使用內(nèi)存,有助于提升機(jī)器的性能和穩(wěn)定性。本文主要介紹Linux 內(nèi)存組織結(jié)構(gòu)和頁面布局,
    的頭像 發(fā)表于 01-05 09:47 ?1580次閱讀

    Linux內(nèi)核內(nèi)存泄漏怎么辦

    在Linux內(nèi)核開發(fā)中,Kmemleak是一種用于檢測內(nèi)核內(nèi)存泄漏的工具。
    發(fā)表于 07-04 11:04 ?780次閱讀

    Linux內(nèi)存相關(guān)知識(shí)科普

    ,Linux 內(nèi)核幾種內(nèi)存管理的方法,內(nèi)存使用場景以及內(nèi)存使用的那些坑。**從內(nèi)存的原理和結(jié)構(gòu),
    發(fā)表于 07-25 14:43 ?704次閱讀
    Linux<b class='flag-5'>內(nèi)存</b>相關(guān)知識(shí)科普

    Linux內(nèi)核內(nèi)存規(guī)整總結(jié)

    1.前言 伙伴系統(tǒng)作為內(nèi)核最基礎(chǔ)的物理頁內(nèi)存分配器,具有高效、實(shí)現(xiàn)邏輯簡介等優(yōu)點(diǎn),其原理頁也盡可能降低內(nèi)存外部碎片產(chǎn)生,但依然無法杜絕碎片問題。外部碎片帶來的最大影響就是內(nèi)存足夠,但是
    的頭像 發(fā)表于 11-11 11:17 ?1253次閱讀
    Linux<b class='flag-5'>內(nèi)核</b><b class='flag-5'>內(nèi)存</b>規(guī)整總結(jié)

    Linux內(nèi)核內(nèi)存管理架構(gòu)解析

    內(nèi)存管理子系統(tǒng)可能是linux內(nèi)核中最為復(fù)雜的一個(gè)子系統(tǒng),其支持的功能需求眾多,如頁面映射、頁面分配、頁面回收、
    的頭像 發(fā)表于 01-04 09:24 ?619次閱讀
    Linux<b class='flag-5'>內(nèi)核</b><b class='flag-5'>內(nèi)存</b>管理架構(gòu)解析

    鴻蒙OS開發(fā):【一次開發(fā),多端部署】(典型布局場景

    雖然不同應(yīng)用的頁面千變?nèi)f化,但對(duì)其進(jìn)行拆分和分析,頁面中的很多布局場景是相似的。本小節(jié)將介紹如何借助自適應(yīng)布局、響應(yīng)式布局以及常見的容器類組件,實(shí)現(xiàn)應(yīng)用中的典型布局
    的頭像 發(fā)表于 05-25 16:39 ?2014次閱讀
    鴻蒙OS開發(fā):【一次開發(fā),多端部署】(<b class='flag-5'>典型</b>布局<b class='flag-5'>場景</b>)

    鴻蒙OS開發(fā):典型頁面場景【一次開發(fā),多端部署】(設(shè)置應(yīng)用頁面

    本小節(jié)以“設(shè)置”應(yīng)用頁面為例,介紹如何使用自適應(yīng)布局能力和響應(yīng)式布局能力適配不同尺寸窗口。
    的頭像 發(fā)表于 05-27 10:33 ?1034次閱讀
    鴻蒙OS開發(fā):<b class='flag-5'>典型</b><b class='flag-5'>頁面</b><b class='flag-5'>場景</b>【一次開發(fā),多端部署】(設(shè)置應(yīng)用<b class='flag-5'>頁面</b>)

    鴻蒙OS開發(fā):典型頁面場景【一次開發(fā),多端部署】實(shí)戰(zhàn)(設(shè)置典型頁面

    本示例展示了設(shè)置應(yīng)用的典型頁面,其在小窗口和大窗口有不同的顯示效果,體現(xiàn)一次開發(fā)、多端部署的能力。
    的頭像 發(fā)表于 05-27 09:36 ?1062次閱讀
    鴻蒙OS開發(fā):<b class='flag-5'>典型</b><b class='flag-5'>頁面</b><b class='flag-5'>場景</b>【一次開發(fā),多端部署】實(shí)戰(zhàn)(設(shè)置<b class='flag-5'>典型</b><b class='flag-5'>頁面</b>)

    鴻蒙OS開發(fā):典型頁面場景【一次開發(fā),多端部署】(短信)案例介紹

    本章從系統(tǒng)預(yù)置的應(yīng)用中,選擇短信應(yīng)用作為典型的案例,從頁面開發(fā)和工程結(jié)構(gòu)的角度,介紹"一多"的具體實(shí)踐。系統(tǒng)的產(chǎn)品形態(tài)在不斷豐富中,當(dāng)前主要有默認(rèn)設(shè)備和平板兩種產(chǎn)品形態(tài),本章的具體實(shí)踐也將圍繞這兩種產(chǎn)品形態(tài)展開。
    的頭像 發(fā)表于 05-28 15:08 ?1145次閱讀
    鴻蒙OS開發(fā):<b class='flag-5'>典型</b><b class='flag-5'>頁面</b><b class='flag-5'>場景</b>【一次開發(fā),多端部署】(短信)案例介紹

    Linux內(nèi)存系統(tǒng):內(nèi)存使用場景

    out of memory 的時(shí)代過去了嗎?no,內(nèi)存再充足也不可任性使用。1、內(nèi)存的使用場景· page 管理· slab(kmalloc、內(nèi)存池)· 用戶態(tài)
    發(fā)表于 08-25 07:42

    內(nèi)存之旅——如何提升CMA利用率?

    (migrate type)的內(nèi)存頁面,不同的遷移類型有各自的用途。舉例來說, MIGRATE_MOVABLE 表示保存在其頁面的數(shù)據(jù)是可以被遷移
    發(fā)表于 03-22 16:26

    一文解析Linux內(nèi)存系統(tǒng)

    Linux 內(nèi)存是后臺(tái)開發(fā)人員,需要深入了解的計(jì)算機(jī)資源。合理的使用內(nèi)存,有助于提升機(jī)器的性能和穩(wěn)定性。本文主要介紹Linux 內(nèi)存組織結(jié)構(gòu)和頁面布局,
    的頭像 發(fā)表于 09-01 10:46 ?2409次閱讀
    一文解析Linux<b class='flag-5'>內(nèi)存</b>系統(tǒng)

    基于內(nèi)存關(guān)聯(lián)分析的內(nèi)存預(yù)拷貝遷移策略

    內(nèi)存預(yù)拷貝遷移在密集型負(fù)載下存在內(nèi)存臟頁反復(fù)傳輸?shù)膬疹},導(dǎo)致迭代輪數(shù)較多且大幅降低了內(nèi)存預(yù)拷貝遷移的整體性能。臟頁概率預(yù)測能夠有效減少
    發(fā)表于 05-24 15:40 ?14次下載

    Linux內(nèi)核中的頁面分配機(jī)制

    Linux內(nèi)核中是如何分配出頁面的,如果我們站在CPU的角度去看這個(gè)問題,CPU能分配出來的頁面是以物理頁面為單位的。也就是我們計(jì)算機(jī)中常講的分頁機(jī)制。本文就看下Linux
    的頭像 發(fā)表于 08-07 15:51 ?214次閱讀
    Linux<b class='flag-5'>內(nèi)核</b>中的<b class='flag-5'>頁面</b>分配機(jī)制