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

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

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

Linux內(nèi)核中用GFP_ATOMIC申請(qǐng)內(nèi)存意味著什么

Linux閱碼場(chǎng) ? 來源:Linuxer ? 作者:Linuxer ? 2021-01-04 13:43 ? 次閱讀

本文目的

本文補(bǔ)充校正一些Linux內(nèi)核開發(fā)者關(guān)于GFP_ATOMIC的認(rèn)知不完整的地方,闡述GFP_ATOMIC與free內(nèi)存watermark的關(guān)系,并明確什么時(shí)候應(yīng)該用GFP_ATOMIC申請(qǐng)內(nèi)存。目錄:

1. GFP_ATOMICvs. GFP_KERNEL

2. 內(nèi)存水位,PF_MEMALLOC和GFP_ATOMIC

3. 何時(shí)使用GFP_ATOMIC(一個(gè)patch分析)

GFP_ATOMICvs. GFP_KERNEL

我們都知道,在中斷、軟中斷、spinlock等原子上下文里面,申請(qǐng)內(nèi)存,應(yīng)該使用GFP_ATOMIC標(biāo)記,譬如內(nèi)核中有大量的kmalloc/GFP_ATOMIC的例子:

fd0acb90-4e4c-11eb-8b86-12bb97331649.png

對(duì)于不可睡眠的上下文,如果我們用常規(guī)的GFP_KERNEL這樣的標(biāo)記去申請(qǐng)內(nèi)存,可能引發(fā)直接的內(nèi)存reclaim,從而引起睡眠,所以GFP_KERNEL這種標(biāo)記只適合進(jìn)程上下文調(diào)用:

fd396c0c-4e4c-11eb-8b86-12bb97331649.png

GFP_KERNEL的標(biāo)記可以引發(fā)直接的內(nèi)存回收,從而導(dǎo)致進(jìn)程阻塞睡眠,這在原子上下文顯然是不允許的。

#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) #define __GFP_RECLAIM ((__force gfp_t)(___GFP_DIRECT_RECLAIM|___GFP_KSWAPD_RECLAIM)

內(nèi)存水位,PF_MEMALLOC和GFP_ATOMIC

那么GFP_ATOMIC是否僅僅意味著不能睡眠呢?檔案是否定的,GFP_ATOMIC還與內(nèi)存reclaim的水位相關(guān)。下面這個(gè)圖是講述水位watermark的一個(gè)著名的圖,筆者懶得畫了,直接從網(wǎng)下copy過來:

fda0690c-4e4c-11eb-8b86-12bb97331649.jpg

在Linux中,內(nèi)存有3個(gè)水位:

HIGH:系統(tǒng)的free內(nèi)存大于HIGH水位的時(shí)候,是一個(gè)相對(duì)保險(xiǎn)的值,不需要急著做內(nèi)存回收(reclaim);

LOW: 系統(tǒng)的free內(nèi)存達(dá)到LOW水位的時(shí)候,啟動(dòng)后臺(tái)kswapd進(jìn)行內(nèi)存回收,回收的目標(biāo)是讓空閑內(nèi)存達(dá)到HIGH水位;

MIN:系統(tǒng)應(yīng)該保有的最小free內(nèi)存,當(dāng)空閑內(nèi)存達(dá)到這個(gè)值的時(shí)候,kswapd的后臺(tái)回收可能來不及了,一般用戶在申請(qǐng)內(nèi)存的時(shí)候,進(jìn)行DIRECT RECLAIM。

min水位一般是系統(tǒng)自動(dòng)換算的,其具體值可以從/proc看出:

# cat /proc/sys/vm/min_free_kbytes 45056

而LOW水位一般是min*125%,HIGH 一般是min*150%。

MIN水位以下的內(nèi)存,只能被緊急情況下的用戶申請(qǐng)到,最著名的緊急用戶莫過于PF_MEMALLOC用戶,task_struct設(shè)置了這個(gè)標(biāo)記表示忽略MIN水位。比如回收內(nèi)存的代碼本身也可能需要申請(qǐng)內(nèi)存,這個(gè)時(shí)候我們應(yīng)該給它無限制的申請(qǐng)能力。典型地,比如kswapd就設(shè)置了這個(gè)標(biāo)記,這個(gè)代碼里面的注釋也非常精彩:

fddec24c-4e4c-11eb-8b86-12bb97331649.png

如果我們不允許回收內(nèi)存的代碼申請(qǐng)min以下的內(nèi)存,則回收內(nèi)存的代碼可以觸發(fā)回收內(nèi)存,這樣“子子孫孫,無窮匱也”。

當(dāng)然,PF_MEMALLOC不是唯一的緊急用戶,GFP_ATOMIC實(shí)際也是一個(gè)“半緊急”任務(wù):

說它“緊急”,是因?yàn)槿绻由舷挛纳暾?qǐng)內(nèi)存失敗,往往意味著相應(yīng)的中斷、軟中斷、spinlock內(nèi)部的代碼就會(huì)執(zhí)行失敗,而我們又不會(huì)因?yàn)檫@種失敗,而去嘗試內(nèi)存回收,這顯然比較慘,我們應(yīng)該盡可能讓GFP_ATOMIC申請(qǐng)成功;

說它“半”,是因?yàn)樗恢劣诰o急到PF_MEMALLOC這個(gè)程度,如果我們給它無限地申請(qǐng)到free內(nèi)存為0的權(quán)力,則會(huì)導(dǎo)致PF_MEMALLOC沒有內(nèi)存了。想想,如果征糧隊(duì)的人都餓死了,還怎么去征糧呢?

所以,內(nèi)存的設(shè)計(jì)選擇是,當(dāng)有人用GFP_ATOMIC申請(qǐng)內(nèi)存的時(shí)候,允許它從MIN水位以下,申請(qǐng)一定數(shù)量的內(nèi)存。什么叫“一定數(shù)量”呢?就是不能讓GFP_ATOMIC導(dǎo)致free 內(nèi)存觸底,GFP_ATOMIC還包含了高優(yōu)先級(jí)的含義:

#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)

注意這個(gè)里面的__GFP_HIGH不是HIGHMEM高端內(nèi)存的意思,而是高優(yōu)先級(jí)。

當(dāng)我們用GFP_ATOMIC申請(qǐng)內(nèi)存的時(shí)候,內(nèi)核的水位檢查代碼,會(huì)允許我們觸及到MIN水位以下的1/2:

fe13730c-4e4c-11eb-8b86-12bb97331649.png

那么,“魔鬼”就是在畫紅圈的2行代碼。但是,如果我們進(jìn)一步深究,會(huì)發(fā)現(xiàn),GFP_ATOMIC不只是觸及1/2*min,它甚至可以觸及1/4*min,因?yàn)镚FP_ATOMIC中的__GFP_HIGH讓ALLOC_HIGH成立,而__GFP_ATOMIC讓ALLOC_HARDER成立:

fe5222dc-4e4c-11eb-8b86-12bb97331649.png

所以,“魔鬼”又隱藏在了gfp_to_alloc_flags()的細(xì)節(jié)里。

一個(gè)patch的例子

在具體的工程實(shí)戰(zhàn)中,我們建議:

原子上下文使用GFP_ATOMIC

比如在網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)drivers/net/ethernet中,就有大量的案例

fe6582dc-4e4c-11eb-8b86-12bb97331649.png

在內(nèi)存緊急的路徑上(比如不想睡眠,要求低延遲;或者要求內(nèi)存吃緊的情況下,仍然可以從min水位以下申請(qǐng)內(nèi)存),哪怕是進(jìn)程上下文,我們也建議可以考慮使用GFP_ATOMIC

比如田濤童鞋最近在mm/zswap.c發(fā)的RFC patch:

https://lore.kernel.org/linux-mm/1608894171-54174-2-git-send-email-tiantao6@hisilicon.com/

fe85c902-4e4c-11eb-8b86-12bb97331649.png

fea50934-4e4c-11eb-8b86-12bb97331649.png

上面2個(gè)地方,其實(shí)都是可以睡眠的進(jìn)程上下文,但是我們認(rèn)為在frontendswap的路徑上,我們對(duì)延遲敏感,對(duì)swap內(nèi)存過程中進(jìn)一步引發(fā)內(nèi)存回收也擔(dān)憂,因此,這里哪怕是非原子上下文,我們也沒有使用GFP_KERNEL。

責(zé)任編輯:xj

原文標(biāo)題:宋寶華:Linux內(nèi)核中用GFP_ATOMIC申請(qǐng)內(nèi)存究竟意味著什么?

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

聲明:本文內(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)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1336

    瀏覽量

    40084
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207919
  • GFP
    GFP
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    1393

原文標(biāo)題:宋寶華:Linux內(nèi)核中用GFP_ATOMIC申請(qǐng)內(nèi)存究竟意味著什么?

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    請(qǐng)問固定增益芯片是否意味著不能通過改變外圍參數(shù)來改變?cè)鲆妫?/a>

    固定增益芯片是否意味著我不能通過改變外圍參數(shù)來改變?cè)鲆妫?
    發(fā)表于 09-11 07:13

    歡創(chuàng)播報(bào) 華為宣布鴻蒙內(nèi)核已超越Linux內(nèi)核

    自誕生以來的最大一次升級(jí)換代。HarmonyOS NEXT不依賴傳統(tǒng)的Unix內(nèi)核Linux內(nèi)核,而是依靠自主的鴻蒙內(nèi)核。這就意味著,鴻蒙
    的頭像 發(fā)表于 06-27 11:30 ?573次閱讀

    可以在RTOS的任何位置使用malloc申請(qǐng)內(nèi)存了嗎?

    今天看了CubeIDE 1.7.0的release note ,里面寫的一條新特性是:Thread-safe malloc solution 這是否意味著我可以在RTOS的任何位置使用malloc申請(qǐng)內(nèi)存了?
    發(fā)表于 04-03 07:23

    Linux內(nèi)核內(nèi)存管理之內(nèi)核非連續(xù)物理內(nèi)存分配

    的主要優(yōu)點(diǎn)是避免了外部碎片,而缺點(diǎn)是需要修改內(nèi)核頁(yè)表。顯然,非連續(xù)內(nèi)存區(qū)域的大小必須是4096的倍數(shù)。Linux使用非連續(xù)物理內(nèi)存區(qū)的場(chǎng)景有幾種:(1)為swap區(qū)分配數(shù)據(jù)結(jié)構(gòu);(2)
    的頭像 發(fā)表于 02-23 09:44 ?751次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>內(nèi)存</b>管理之<b class='flag-5'>內(nèi)核</b>非連續(xù)物理<b class='flag-5'>內(nèi)存</b>分配

    Linux內(nèi)核內(nèi)存管理之ZONE內(nèi)存分配器

    內(nèi)核中使用ZONE分配器滿足內(nèi)存分配請(qǐng)求。該分配器必須具有足夠的空閑頁(yè)幀,以便滿足各種內(nèi)存大小請(qǐng)求。
    的頭像 發(fā)表于 02-21 09:29 ?746次閱讀

    linux內(nèi)核主要由哪幾個(gè)部分組成,作用是什么

    Linux內(nèi)核主要由以下幾個(gè)部分組成: 進(jìn)程管理:Linux內(nèi)核負(fù)責(zé)管理和調(diào)度系統(tǒng)中的進(jìn)程。它通過進(jìn)程調(diào)度算法來決定哪個(gè)進(jìn)程在什么時(shí)間運(yùn)行以及如何分配系統(tǒng)資源。
    的頭像 發(fā)表于 01-22 14:34 ?2273次閱讀

    ADM1191本身芯片電源為3.15到26V,是否意味著SENSE端只能測(cè)試接近這個(gè)范圍的電壓?

    小弟我是一個(gè)尚在學(xué)習(xí)過程的學(xué)生,現(xiàn)如今試圖用ADM1191芯片測(cè)試其他電路的電流, 有兩個(gè)問題想要請(qǐng)教: 1、ADM1191本身芯片電源為3.15到26V,是否意味著SENSE端只能測(cè)試接近這個(gè)
    發(fā)表于 01-09 06:15

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

    內(nèi)存管理子系統(tǒng)可能是linux內(nèi)核中最為復(fù)雜的一個(gè)子系統(tǒng),其支持的功能需求眾多,如頁(yè)面映射、頁(yè)面分配、頁(yè)面回收、頁(yè)面交換、冷熱頁(yè)面、緊急頁(yè)面、頁(yè)面碎片管理、頁(yè)面緩存、頁(yè)面統(tǒng)計(jì)等,而且對(duì)性能也有很高
    的頭像 發(fā)表于 01-04 09:24 ?556次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>內(nèi)存</b>管理架構(gòu)解析

    兆芯正引入Linux首選內(nèi)核調(diào)度技術(shù),優(yōu)化性能

    近期,兆芯工程團(tuán)隊(duì)亦在致力于將首選內(nèi)核調(diào)度技術(shù)引進(jìn)Linux系統(tǒng)中。他們?cè)噲D通過提議的Linux內(nèi)核補(bǔ)丁,利用已有的ACPI功能來辨別每個(gè)核心的特性。這項(xiàng)補(bǔ)丁將在ACPI CPUFre
    的頭像 發(fā)表于 12-29 14:30 ?440次閱讀
    兆芯正引入<b class='flag-5'>Linux</b>首選<b class='flag-5'>內(nèi)核</b>調(diào)度技術(shù),優(yōu)化性能

    美智光電二度撤回IPO申請(qǐng)

      美智光電于12月19日申請(qǐng)撤回上市申請(qǐng)文件,這也意味著美智光電上市進(jìn)程再度終止。
    的頭像 發(fā)表于 12-28 16:01 ?506次閱讀

    AD5420沒有CS引腳是否意味著不能和其他SPI接口的芯片共用SPI總線呢?

    請(qǐng)問一下,AD5420沒有CS引腳是否意味著不能和其他SPI接口的芯片共用SPI總線呢?如果必須共用SPI總線有沒有什么解決方案呢? 我的電路中將AD7715和AD5420同時(shí)連接到MCU的SPI
    發(fā)表于 12-15 07:25

    獲取Linux內(nèi)核源碼的方法

    (ELF1/ELF1S開發(fā)板及顯示屏)Linux內(nèi)核是操作系統(tǒng)中最核心的部分,它負(fù)責(zé)管理計(jì)算機(jī)硬件資源,并提供對(duì)應(yīng)用程序和其他系統(tǒng)組件的訪問接口,控制計(jì)算機(jī)的內(nèi)存、處理器、設(shè)備驅(qū)動(dòng)程
    的頭像 發(fā)表于 12-13 09:49 ?537次閱讀
    獲取<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>源碼的方法

    Linux內(nèi)核slab性能優(yōu)化的核心思想

    今天分享一篇內(nèi)存性能優(yōu)化的文章,文章用了大量精美的圖深入淺出地分析了Linux內(nèi)核slab性能優(yōu)化的核心思想,slab是Linux內(nèi)核小對(duì)象
    的頭像 發(fā)表于 11-13 11:45 ?490次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>slab性能優(yōu)化的核心思想

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

    分配需求,如下圖所示: 內(nèi)存外部碎片導(dǎo)致實(shí)際占用物理頁(yè)不多,但是已無法申請(qǐng)>=4個(gè)頁(yè)連續(xù)內(nèi)存,理想當(dāng)中我們希望內(nèi)存沒有外部碎片,如下圖所示: 內(nèi)核
    的頭像 發(fā)表于 11-11 11:17 ?1150次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>內(nèi)存</b>規(guī)整總結(jié)

    Linux 內(nèi)存管理總結(jié)

    一、Linux內(nèi)存管理概述 Linux內(nèi)存管理是指對(duì)系統(tǒng)內(nèi)存的分配、釋放、映射、管理、交換、壓縮等一系列操作的管理。在
    的頭像 發(fā)表于 11-10 14:58 ?432次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>內(nèi)存</b>管理總結(jié)