<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux內存管理之CPU本地頁幀緩存

jf_0tjVfeJz ? 來源:嵌入式ARM和Linux ? 2024-02-20 09:23 ? 次閱讀

0 CPU頁幀緩存概念

在前一節中,我們學習了buddy伙伴關系系統,它適用于申請連續的大塊物理內存;而有些時候,經常需要申請和釋放單個頁幀。但是,如果使用伙伴關系系統,需要查表、進行合并等操作,效率不高。為了提高性能,每個內存ZONE區都提供了一個per-CPU變量,CPU頁幀緩存。每個CPU頁幀緩存都包含一些預分配好的頁幀,滿足本地CPU發起的單個頁幀請求。

實際上,每個內存ZONE區和每個CPU都有2個緩存:一個是熱緩存,它存儲頁幀,其內容可能包含在CPU的硬件緩存中;另一個是冷緩存。

如果內核或用戶進程在分配后立即寫入頁幀,那么從熱緩存中獲取頁幀將有利于系統性能。實際上,每次訪問頁幀的某個內存位置,都會導致硬件Cache中替換其它頁幀的某一行(Cache-line),當然,除非硬件Cache已經包含剛剛訪問的“熱”頁幀中內存位置的一行。

相反,如果要用DMA操作填充頁幀,則從冷緩存中取頁幀是很方便的。在這種情況下,不涉及CPU,也不會修改硬件Cache的任何行。從冷緩存中取頁幀可以為其他類型的內存分配請求保留熱頁幀。

CPU頁幀緩存的數據結構是per_cpu_pageset類型的數組,其存儲在內存ZONE描述符中的pageset成員中,如下面的代碼所示:

structzone{
/*...*/
structper_cpu_pagesetpageset[NR_CPUS];
/*...*/
}

數組個數與CPU個數相關,其中的每個數組元素又包含2個per_cpu_pages描述符成員:一個是熱緩存;另一個是冷緩存。而per_cpu_pages數據類型的成員如下表所示:

structper_cpu_pages{
intcount;/*緩存中的頁幀數量*/
intlow;/*閾值下限,用于緩存補充*/
inthigh;/*閾值上限,需要清空緩存*/
intbatch;/*需從緩存中添加或減少的頁幀數*/
structlist_headlist;/*緩存中頁幀描述符列表,即內存頁列表*/
};

內核使用兩個閾值(low和high)監控冷/熱緩存的大?。喝绻搸瑪盗康陀陂撝?,則內核使用伙伴系統分配一定數量的單個頁幀(batch);否則,頁幀數量超過閾值上限,內核將緩存中的頁幀釋放到伙伴系統中(batch)。batch、low和high的值,具體依賴于內存ZONE區的頁幀數量。

1 通過CPU頁幀緩存分配頁幀

buffered_rmqueue()函數在給定的內存ZONE區中分配頁幀。它利用CPU頁幀緩存來處理單個頁幀請求。

Linux v2.6.11內核源碼實現如下所示(文件位置:/mm/page_alloc.c):

staticstructpage*
buffered_rmqueue(structzone*zone,intorder,intgfp_flags)
{
unsignedlongflags;
structpage*page=NULL;
intcold=!!(gfp_flags&__GFP_COLD);

if(order==0){
structper_cpu_pages*pcp;

pcp=&zone->pageset[get_cpu()].pcp[cold];
local_irq_save(flags);
if(pcp->count<=?pcp->low)
pcp->count+=rmqueue_bulk(zone,0,
pcp->batch,&pcp->list);
if(pcp->count){
page=list_entry(pcp->list.next,structpage,lru);
list_del(&page->lru);
pcp->count--;
}
local_irq_restore(flags);
put_cpu();
}

if(page==NULL){
spin_lock_irqsave(&zone->lock,flags);
page=__rmqueue(zone,order);
spin_unlock_irqrestore(&zone->lock,flags);
}

if(page!=NULL){
BUG_ON(bad_range(zone,page));
mod_page_state_zone(zone,pgalloc,1<

輸入參數分別是內存ZONE區的描述符的地址(zone)、內存分配請求大?。?^order)和分配標志gfp_flags。如果在gfp_flags中設置了__GFP_COLD標志,則應從冷緩存中獲取頁幀,否則應從熱緩存中獲取頁幀(此標志僅對單個頁幀請求有意義)。該函數基本上執行以下操作:

如果order不等于0,則頁幀緩存不能使用,函數直接跳轉到第4步。

檢查由__GFP_COLD標志標識的內存ZONE區域的CPU緩存是否必須被補充(per_cpu_pages的count ≤ low)。在本例中,它執行以下子步驟:

重復調用__rmqueue()函數,從伙伴系統中分配batch個頁幀。

將分配的頁幀描述符插入到緩存的列表中。

更新count變量(將新分配的頁幀數量加上)。

如果count > 0,從緩存列表中取一個頁幀,然后跳轉到第5步。(CPU頁幀緩存可能是空的,在第2步的__rmqueue()沒有申請到頁幀時就會發生)

到這兒,如果內存請求沒有被滿足,調用__rmqueue()申請從伙伴系統中分配所請求頁幀。

如果內存請求被滿足,初始化該頁幀(第1個)的頁描述符:清除某些標志、設置private為0,設置頁幀引用計數器為1。另外,如果設置了__GPF_ZERO,將申請的內存清零。

返回頁幀(第1個)的描述符,失敗返回NULL。

2 通過CPU頁幀緩存釋放頁幀

從CPU頁幀緩存中釋放頁幀,使用free_hot_page()和free_cold_page()函數。它們都是free_hot_cold_page()的封裝函數,如下所示(文件位置:/mm/page_alloc.c):

staticvoidfastcallfree_hot_cold_page(structpage*page,intcold)
{
structzone*zone=page_zone(page);
structper_cpu_pages*pcp;
unsignedlongflags;

arch_free_page(page,0);

kernel_map_pages(page,1,0);
inc_page_state(pgfree);
if(PageAnon(page))
page->mapping=NULL;
free_pages_check(__FUNCTION__,page);
pcp=&zone->pageset[get_cpu()].pcp[cold];
local_irq_save(flags);
if(pcp->count>=pcp->high)
pcp->count-=free_pages_bulk(zone,pcp->batch,&pcp->list,0);
list_add(&page->lru,&pcp->list);
pcp->count++;
local_irq_restore(flags);
put_cpu();
}

free_hot_cold_page()接受的參數是待釋放頁幀的描述符地址page,表示熱緩存還是冷緩存的標志cold。

執行的步驟如下:

根據頁幀,獲取page->flags標志。

根據cold標志獲取對應頁幀緩存的描述符per_cpu_pages地址。

檢查緩存是否不足:如果count ≥ high,調用free_pages_bulk()函數。該函數會重復調用__free_pages_bulk()函數釋放指定的頁幀到伙伴系統中。

將該頁幀添加到緩存列表中,增加count計數。

應該注意的是,在Linux v2.6內核中,沒有任何頁幀被釋放到冷緩存中:內核總是假設釋放的頁幀相對于硬件緩存來說是熱的。當然,這并不意味著冷緩存是空的:當達到低閾值時,緩存由buffered_rmqueue()補充。

3 移除__GFP_COLD

雖然我們前邊分析了基于冷熱緩存的CPU頁幀緩存,但是,從v4.14版本以后的內核中已經移除,參考patch。Patches 1-4是與移除冷緩存最相關的部分;Patches 5-8是可選的,因為它們都是刪除無用但也不影響性能的代碼。

free_hot_cold_page的大多數調用者用戶都聲稱被釋放的頁是熱緩存的。唯一的例外是頁回收代碼,因為在不久的將來可能會釋放足夠多的頁,因此CPU的本地頁幀緩存列表將被回收,熱緩存信息將丟失。由于沒有人真正關心被釋放到分配器的頁的熱信息,所以省略該參數即可。




審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 計數器
    +關注

    關注

    32

    文章

    2199

    瀏覽量

    93303
  • Cache
    +關注

    關注

    0

    文章

    127

    瀏覽量

    28067
  • LINUX內核
    +關注

    關注

    1

    文章

    312

    瀏覽量

    21407

原文標題:Linux內核8.5-內存管理之CPU本地頁幀緩存

文章出處:【微信號:嵌入式ARM和Linux,微信公眾號:嵌入式ARM和Linux】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    高并發系統中的緩存 緩存系統存在的三大問題

    緩存在計算機系統是無處不在,在CPU層面有L1-L3的Cache,在Linux中有TLB加速虛擬地址和物理地址的轉換,在瀏覽器有本地緩存、手
    的頭像 發表于 07-15 11:03 ?4054次閱讀

    Linux內存管理是什么,Linux內存管理詳解

    Linux內存管理 Linux內存管理是一個非常復雜的過程,主要分成兩個大的部分:內核的
    的頭像 發表于 05-11 17:54 ?5391次閱讀
    <b class='flag-5'>Linux</b>的<b class='flag-5'>內存</b><b class='flag-5'>管理</b>是什么,<b class='flag-5'>Linux</b>的<b class='flag-5'>內存</b><b class='flag-5'>管理</b>詳解

    關于Linux內存管理的詳細介紹

    Linux內存管理是指對系統內存的分配、釋放、映射、管理、交換、壓縮等一系列操作的管理。在
    發表于 03-06 09:28 ?902次閱讀

    HVM的緩存控制與內存管理

    控制的虛擬指令 下圖列出了HVM緩存控制的虛擬指令: 內存管理概述 HVM映射虛擬地址0x0000_0000至0xfeff_ffff置于一個32位的邏輯地址空間,既可以使用一系列的轉換或者1或2級別
    發表于 09-20 10:19

    Linux內存系統: Linux 內存分配算法

    內存管理算法:對討厭自己管理內存的人來說是天賜的禮物。1、內存碎片1) 基本原理· 產生原因:內存
    發表于 08-24 07:44

    Linux內存系統---走進Linux 內存

    的運算數據· 2)硬盤等外部存儲器交換的數據· 3)保障 cpu 計算的穩定性和高性能 二、 Linux 內存地址空間 1、Linux 內存
    發表于 08-26 08:05

    深入細節的詳解,嵌入式必懂知識Linux內存管理

    前面說的段管理機制算是虛擬空間的部分,然而linux內存管理的另外一個重要部分就是物理內存
    發表于 08-28 10:34

    linux內存管理

    公交,地鐵,睡前必備,方便大家查閱,持續更新,敬請期待!---更新于2020-02-12linux 內存管理Linux內存初始化
    發表于 07-22 08:41

    如何定義虛擬內存?

    本文將探討什么是虛擬內存,它為什么存在,以及它如何工作。緩存的發明是因為內存訪問速度和 CPU 處理能力之間的差異。通過使用硬件緩存,最近從
    發表于 04-11 10:20

    一文搞定Linux內存管理原理

    &quot;,讓其崩潰;如果是,則分配一個物理,并為建立映射。物理內存管理(圖:右上)那么物理內存是如何分配的呢?首先,
    發表于 06-28 10:05

    Linux內存管理導讀

    Linux 內存管理導讀 :1. 存儲層次結構和 x86存儲管理硬件(MMU) 1.1 存儲層次 高速緩存(cache) 主存(main m
    發表于 11-03 22:32 ?39次下載

    CPU緩存的作用及原理有哪些

    CPU緩存是位于CPU內存之間的臨時存儲器,它的容量比內存小很多,但交換速度比內存要快很多。
    的頭像 發表于 08-27 15:58 ?9788次閱讀

    關于CPU緩存的作用

    CPU沒有存儲功能,那么緩存到底是干什么的?CPU緩存是用于減少處理器訪問內存所需平均時間的部件,作用類似于
    的頭像 發表于 03-30 10:58 ?4055次閱讀
    關于<b class='flag-5'>CPU</b><b class='flag-5'>緩存</b>的作用

    如何在 Linux 上查看本地 DNS 緩存

    ? 刷新本地 DNS 緩存可以解決 HTTP 錯誤并保護您免受 DNS 欺騙。以下是在 Linux 上執行此操作的方法。 當您使用域名訪問網站時,您的系統會向 DNS 服務器發送請求以獲取
    的頭像 發表于 06-26 10:52 ?2618次閱讀
    如何在 <b class='flag-5'>Linux</b> 上查看<b class='flag-5'>本地</b> DNS <b class='flag-5'>緩存</b>

    Linux 內存管理總結

    、緩存、交換分區等。Linux內存管理的目標是最大限度地利用可用內存,同時保證系統的穩定和可靠性。 1.1 什么是
    的頭像 發表于 11-10 14:58 ?281次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>內存</b><b class='flag-5'>管理</b>總結
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>