你的位置:ai 巨乳 > 偷拍自拍视频 >

亚洲色图 千百度 超详备!Linux内核内存规整详解

  • 发布日期:2024-09-30 21:14    点击次数:63
  • 亚洲色图 千百度 超详备!Linux内核内存规整详解

    1.媒介亚洲色图 千百度

    伙伴系统看成内核最基础的物理页内存分拨器,具有高效、完毕逻辑简介等优点,其道理页也尽可能裁减内存外部碎屑产生,但依然无法阻绝碎屑问题。外部碎屑带来的最大影响即是内存迷漫,然则却无法知足内存分拨需求,如下图所示:

    图片亚洲色图 千百度

    内存外部碎屑导致实践占用物理页未几,然则已无法苦求>=4个页连气儿内存,瞎想当中咱们但愿内存莫得外部碎屑,如下图所示:

    图片

    内核并未为此方针策画新的内存分拨算法(伙伴系统迷漫浅易和高效),其经受在伙伴系统基础上字据内存使用需求进行内存分拨,将不可移动内存和可移动内存归类,在内存碎屑问题出当前,尝试进行内存规整(compact),移动可移动的页面,腾出更多连气儿内存,如下图简述:

    图片

    上图中将一个页移动到另一个页的过程叫页转移,这并不是一件松驰的事情,数据的拷贝、进度映射信息更动等等皆很耗时况兼亦然个复杂逻辑,这注定内存规整的过程是一个重担载的过程。事实上,页转移是内存管制的落寞逻辑,内查对此单独封装接口migrate_pages,内存规整只是其中一个应用场景,访佛场景还有NUMA Balance、Memory hotplug及CMA内存等等。本文聚焦内存规整,不形色内存转移逻辑。

    站在开拓者角度有了内存转移基础智力,那么就有完毕内存规整基础,但依然有值得想考的问题,比如内存规整的范围,何时进行内存规整等等。

    对于内存规整范围问题,内核等闲经受以zone为单元进行规整(实践范围受到参数影响可能为zone一部分),并为此封装compact_zone接口,看成内存规整中枢接口(alloc_contig_range例外)。

    对于何时触提问题,属于触发计谋和场景问题,内核当前引入平直内存规整、被迫内存规整、预应性内存规整及主动内存规整四种计谋场景,这些场景最终皆和会过compact_zone进行内存规整,然则他们触发的时机不同、方针不同、规整范围不同、规整退出条目不同,规整强度不同等等。基础智力和计谋分离策画是内核的基础策画理念。

    图片

    如上图所示,内存规整是基于内存转移完毕的功能,内核字据计谋在不同实践触发内存规整,用于缓解内存外部碎屑问题,不错分层分析看待内存规整。

    2.内存规整场景

    媒介中已评释内核当前触发内存规整的计谋有四种,为便于稽查和直不雅交融,优先陈列四种场景特色,见下表:

    图片

    上述表格中各规整计谋详见2.1~2.4节形色,compact_control多样含义,详见3.1节形色。

    FAQ:

    (1)平直内存规整较为特殊,内存分拨过程中如果触发平直内存规整依然无法分拨内存,那么有可能轮回调用况兼提高内存规整的级别,因此出现初度和重试之分。

    欧美日韩在线dvd

    (2)规整页类型中不包含不可回收页,除非通过sysctl_compact_unevictable_allowed进行设立。

    (3)内存规整中有一个特例即是alloc_contig_range函数,该函数用于分拨指定地址区域内存,若这部安分存被占用,会尝试对这段内存进行规整转移,其并非针对zone的规整,而是针对指定内存区域的规整,它的规整类型与主动内存规整访佛,其完毕中枢是内存规整机制,本文分歧此逻辑进行评释。

    2.1 平直内存规整(direct compaction)

    2.1.1 平直内存规整触发条目

    伙伴系统分拨内存时,会先以low水线为基准调用get_page_from_freelist函数尝试进行内存分拨,如果失败则会投入慢速内存分拨经过,即__alloc_pages_slowpath函数,咱们对此函数逻辑稍作删减,内容如下:

    图片

    慢速内存分拨,会尝试叫醒kswapd进行内存回收,但并不会恭候内存回收的结果,而是平直先调用get_page_from_freelist函数尝试内存分拨,但此次不同的是使用min水线进行尝试,如果依然失败,那么将会字据gfp象征阐明当前分拨是否相沿平直内存回收,若相沿,将会调用__alloc_pages_direct_compact尝试第一次平直内存规整以及内存分拨。如果依然失败,则投入叫醒kswapd、get_page_from_freelist、__alloc_pages_direct_reclaim及__alloc_pages_direct_compact轮回调用经过里面来,固然这之中存在广漠条目判断随时可能复返页分拨失败、页分拨获胜、重试以致是触发OOM。值得小心的是在慢速内存分拨逻辑中,初度调用平直内存规整时其优先级设立为INIT_COMPACT_PRIORITY,这将影响内存规整触发页转移的类型,比如INIT_COMPACT_PRIORITY对应的即是MIGRATE_ASYNC即异步转移类型代表页迁移时不会结巴,固然这样带来的恶果即是规整或转移的智力较弱。慢速内存分拨逻辑中后续平直内存规整调用其规整优先级可能会缓缓裁减(越低对应规整强度越高)从而升迁内存规整服从,然则内存规整可能变为结巴规整,这是相互对应逻辑。

    通过上述形色,不错初步了解平直内存规整起到的作用,也不错感受到内核内存分拨投入到慢速分拨逻辑后性能的代价。

    另一方面,平直内存规整实践是由于伙伴系统无法分拨内存时触发,因此平直内存规整方针并也并非排斥通盘zone的外部碎屑,而只是通过内存规整转移出方针阶连气儿内存。

    2.1.2 平直内存规整逻辑评释

    __alloc_pages_direct_compact函数是平直内存规整运行进口,该函数中枢内容如下:

    图片

    try_to_compact_pages函数将会进一步履用compact关联经过进行规整,规整完成后调用get_page_from_freelist进行内存分拨。try_to_compact_pages中枢代码逻辑如下:

    图片

    try_to_compact_pages函数中枢,遍历章程范围内zone,针对每个zone调用compaction_deferred阐明其是否合适进行规整,若合适进一步履用compact_zone_order函数进行规整,规整获胜则平直内存规整将会平直复返。在try_to_compact_pages函数中咱们要点评释一下zone蔓延判断逻辑,这部分逻辑一样适用于后续kcompactd对于zone的判断。

    2.1.2.1 蔓延规整

    compaction_deferred函数用于判断当前zone是否需要进行蔓延处理,蔓延的方针是幸免等闲或无效的内存规整,其引入两个机制用于蔓延,一个是内存规整失败阶判断,另一个是内存规整蔓延次数判断(这更像一种计时器)。

    图片

    A) 规整失败阶的判断(compact_order_failed)

    如果当前规整阶大于等于zone的最大规整失败阶,那么代表当前再去规整失败的可能性很高,淡薄蔓延对当前zone规整。

    B) 内存规整蔓延次数超阈值判断

    如果失败阶判断知足,那么会对蔓延次数进行判断,compact_considered纪录了当前zone蔓延次数,compaction_deferred每次调用时compact_considered皆会累加,如果其小于阈值,那么淡薄zone不进行规整,象征近期可能仍是进行过规整。

    图片

    不错联想到,蔓延判断的这些参数会动态变化,实践如上图所示。

    A) 当内存规整获胜时,调用compaction_defer_reset函数清空compact_considered蔓延计数,清空compact_defer_shift蔓延计数阈值(defer_limit = compact_defer_shift << 1),同期如果当前order大于等于compact_defer_shift ,则更新compact_order_failed最大规整失败阶。

    转头,当规整获胜时,会裁减此zone蔓延圭臬,让后续对zone规整判断变得更为容易。

    B) 当内存规整失败时,依然会将compact_considered清零,若order大于更新更新compact_order_failed最大规整失败阶,增大compact_defer_shift蔓延计数阈值。

    转头,当规整失败时,会增大此zone蔓延圭臬,让后续对zone规整将会蔓延更屡次。

    通过上述蔓延决策,确保对于某个zone不作念重叠规整、不作念获胜率低的规整,当一次对zone规整失败时,内核将会尽量经受zone迷漫时代然后再进行尝试。zone蔓延判断机制适用于平直内存规整以及kcompactd内存规整机制,这两种机制对于耗时较为敏锐,其它场景内存规整等闲不需要此机制。

    2.1.2.2 capture_control评释

    再次回到try_to_compact_pages函数,一个zone在通过蔓延判断后,将会调用compact_zone_order函数,该函数中枢是界说compact_control并调用compact_zone完陈规整。然则这里引入了一个很故道理的机制capture_control,因此需要特别进行评释,这笔修改可见如下内容:

    图片

    等闲的逻辑通过内存规整转移出方针阶内存块,再进行内存分拨,而为了提效capture_control的想路则是在内存规整的过程中就将内存分拨出来,只不外这个分拨更像是截胡,在平直内存规整的过程中,若发生内存开释,则在伙伴系统内存开释逻辑中截胡合适的内存,底下详备评释这个过程。

    图片

    在compact_zone_order函数会填充capture_control变量,并将其赋值给当前进度高下文,标志着当前进度投入到平直规整逻辑里面。不错联想在内存规整过程中触及内存开释,此时capture动手行动,代码如下:

    图片

    内存开释经过中通过compaction_capture尝试拿获已开释的内存,compaction_capture函数代码完毕如下:

    图片

    开释内存阶必须与平直内存规整阶极度才有可能拿获,同期需要强调如果当前开释的是MIGRATE_MOVABLE类型页尽量不去拿获,幸免浑浊可移动页面,因为触发平直规整的有可能是不可移动的内存请求。

    2.1.3 平直内存规整特色

    图片

    (1)指定了规整方针阶,裁减规整范围和难度;

    (2)转移页扫描器和泄气页扫描器,使用快速扫描智力;

    (3)其指定highest_zoneidx和方针阶,因此存在水线判断。

    (4)direct_compaction设立平直规整象征;

    平直内存规整优先级COMPACT_PRIO_ASYNC缓缓升高,内存规整强度将会增强,内容如下:

    (5)跟着规整失败,规整模式MIGRATE_ASYNC变为MIGRATE_SYNC_LIGHT,即平直内存规整可能是不结巴也可能是结巴模式;

    (6)跟着规整失败,规整范围从字据前次规整结果制定范围变为完好zone地址范围;

    (7)跟着规整失败,pageblock将会被从头扫描,不会字据符号skip,缓缓加强规整强度;

    (8)跟着规整失败,泄气页扫描器将变得严格,泄气页必须来自于MIGRATE_MOVABLE和MIGRATE_CMA可移动的页面;

    上述compact_control结构体参数含义见3.1节;

    2.2 被迫内存规整(kcompactd)

    内核在启动过程中会调kcompactd_init函数,为每个node启动一个kcompactd内核线程,况兼kcompactd线程会运行在与node相对应的CPU核上,在合适的时机kcompactd将会被叫醒进行内存规整,这即是被迫内存规整逻辑。一个特殊场景是若开启proactive compaction功能,那么kcompactd会被周期性叫醒。

    本节主要从三个方面评释,分辨是kcompactd叫醒条目、kcompactd运行条目、以及kcompactd内存规整特色(kcompactd被叫醒不一定会进行内存规整)。

    2.2.1 kcompactd叫醒条目

    内存规整模块向内核提供wakeup_kcompactd口用于叫醒node对应的kcompactd线程,内核中kcompactd叫醒与kswapd强关联,转头如下场景会被被迫叫醒:

    图片

    FAQ:这里指的触发内存规整,指的是调用wakeup_kcompactd函数,有时确切进行内存规整,wakeup_kcompactd还存在诸多判断;

    2.2.1.1 kswapd运行前触发内存规整

    图片

    当内存分拨失败时经多样判断后,会进⼊内存慢速分拨过程,此时伙伴系统将尝试叫醒内存回收,在这个过程中,有如下要道代码:

    图片

    上述代码为未叫醒kswapd前进行内存规整的条目判断,其意图如下:

    (1)kswapd内存回收失败屡次;

    (2)字据pgdat_balanced函数判断当前水位安全,即存在⾜够可⽤内存况兼未出现”偷“内存情况;实践在于,当前内存无法分拨的原因并非低内存,此时内存回收可能仍是无法处治此问题时,wakeup_kswapd函数将会提前进行内存规整。这里还需要评释的是,内存分拨指定不相沿平直内存回收时上述逻辑才能奏效,这是因为若相沿平直内存规整,则不错借助平直内存回收来进行改善况兼等闲平直内存规整有更好的性能发扬。

    2.2.1.2 kswapd运行中触发内存规整

    图片

    watermark_boost_factor导致的内存规整,归类为kswapd运行中触发内存规整稍有牵强,不外其如实是在kswapd内存规整中枢逻辑中触发。这里浅易先容⼀下watermark_boost_factor性情,当分拨内存时如果在对应migrate type上莫得分拨到内存,那么系统将会从fall_back的migrate type进行内存分拨,有时将其叫作念”偷“,由于分拨了不匹配转移类型的内存,内核会以为这可能存在外部碎屑的风险,是以当出现这种”偷“时内核会提前进行内存回收及规整,从而裁减后续”偷“行径的发生,幸免内存碎屑问题,升迁内存分拨的效率,这即是watermark_boost_factor性情。

    图片

    steal_suitable_fallback函数是从其它转移类型上分拨内存的中枢逻辑,此函数中会设立⼀个ZONE_BOOSTED_WATERMARK标志位,这个标志位只可被kswapd撤废,伙伴系统在内存分拨获胜后,如果发现ZONE_BOOSTED_WATERMARK被置位,将会叫醒kswapd线程。

    图片

    kswapd函数通过调用balance_pgdat进行内存回收,而balance_pgdat函数会在举座内存回收完了后,尝试叫醒kcompactd线程,固然前提是本次内存回收是boosted属性的内存回收。

    图片

    boost性情引起内存规整,其规整阶为pageblock对应阶,在后续compact_zone函数先容中将会评释其影响。上述只是浅易形色watermark_boost_factor性情,其还触及到内存回收时boost导致水线升迁等性情,由于其与内存回收联系较大,本文不深切分析,全球可通过如下合入纪录进⼀步了解:

    图片

    2.2.1.3 kswapd运行后触发内存规整

    图片

    kswapd内核线程,每次在内存回收完毕后将会调⽤kswapd_try_to_sleep尝试就寝,此函数会在就寝前调用reset_isolation_suitable函数清空转移扫描器和泄气页扫描器扫描过程中产生的缓存数据(比如某个pageblock是否需要跳过信息等等),随后调用wakeup_kcompactd函数尝试进行内存规整。

    浅易说,每次kswapd运行完成后皆会尝试叫醒内存规整线程,然则内存规整线程是否确切需要运行,其有复杂的判断逻辑。

    2.2.2 kcompactd运行条目

    当kcompactd线程运行时,若当前短长预应性规整(详见2.3节),那么将会调用

    kcompactd_do_work函数进行被迫内存规整。kcompactd_do_work函数会遍历当前node的总计zone进行正当性判断,若顺应条目,则调用compact_zone针对zone进⾏内存规整,其对zone的判断逻辑如下:

    图片

    字据上述代码,不错转头如下判断逻辑:

    A. zone是否包含灵验物理页,若不包含,不需要规整;

    B. 当前规整方针阶是否大于等于之前规整失败的最小阶,若大于不需要规整;

    C. 是否需要蔓延规整,若蔓延次数跳跃阈值则须规整,不然不规整,幸免无效规整;

    D. 当前内存水线是否知足内存苦求,若知足则不规整;

    E. 若当前order大于3同期不知足内存分拨,则评估其内存碎屑程度,若小于阈值,则不规整;其中,populated_zone函数只是判断当前zone是否存在灵验物理页,其它逻辑在compaction_deferred和compaction_suitable函数中完毕。

    2.2.2.1 蔓延规整

    在平直内存规整中仍是先容了蔓延判断的逻辑,对于kcompactd一样使用,下述代码不错看到其对蔓延参数的更新逻辑。

    图片

    如果comapct_zone复返值是由于扫描器再会导致(一轮扫描完了),而非规整方针达成导致,代表规整并未达成方针,一样按照失败处理。

    2.2.2.2 水线判断

    compaction_suitable函数一方面通过__compaction_suitable判断水线是否知足当前order阶内存分拨要求,若知足则当前zone不需要规整;另一方面,通过fragmentation_index函数获取当前zone对于order阶内存块碎屑程度评估,如果以为碎屑程度不高,则不进行规整。先来分析__compaction_suitable函数,此函数用于评估当前水线是否知足内存分拨,若不知足,则评估水线是否知足内存规整过程中内存占用需求,要道完毕如下:

    图片

    此函数中,调用两次__zone_watermark_ok进行水线判断,__zone_watermark_ok函数功能是判断当前zone在分拨order阶内存块后水线是否达标。第一次水线查验获胜,代表当前zone不错知足内存分拨诉求,因此当前zone毋庸规整。若第一次调用失败,则尝试第二次判断,第二次水线判断的方针是阐明内存规整过程中是否可能存在水线问题,因为内存规整过程中需要order阶泄气页用于内存转移。因此第二次水线的判断,仅对0阶内存判断,因为转移过程中苦求泄气页皆是单页,另一方面watermark增多order阶内存块代表转移内存占用,然则需要小心的是表面上转移只需要order阶大小的内存,然则实践watermark增多了2倍order阶大小的内存(compact_gap函数),这是由于实践内存规整过程中由于转移页扫描器可能扫描出大于order阶待转移内存,因此泄气页扫描器也会占用大于order阶泄气页,为了确保评估的安全性,改为2倍order阶内存,这部分评释在compact_gap函数里面注释中有所形色。

    2.2.2.3 各阶碎屑评分判断

    fragmentation_index函数用于获取方针阶碎屑程度评价,从而评估当前内存无法分拨的原因是由于低内存照旧外部碎屑导致。

    图片

    其中fill_contig_page_info会遍历zone内存,统计当前泄气页以及对应order阶泄气区域数目,此函数下文将会详备先容,终末通过__fragmentation_index函数和上述遍历泄气页取得的关联信息进行计较评估。代码上钩算公式如下:

    图片

    先明确info->free_blocks_total代表当前zone中各个order阶内存区域数目,info->free_pages代表当前zone中泄气页的数目,requested代表order阶对应页数目。咱们定名info->free_pages/requested为target_order_blocks,在当前泄气页情景下若不存在内存碎屑问题这种瞎想情景下领有若干个order阶内存块,咫尺从头简化公式,即可取得如下形色:

    图片

    极限情景info->free_blocks_total极度大时,意味着严重的内存碎屑问题,上述值趋近于1,反之0代表内存不及问题。__fragmentation_index函数引入1000这个数值参与运算是为了幸免少量,导致复返值不易判断,咫尺引入此值后,使函数复返值落入-1000,0~1000范围中,其中-1000场景较为特殊,其代表当前zone知足内存分拨需求,然则在此之前却通过了上文中__compaction_suitable函数的判断,当前-1000复返值实践在代码中似乎并未被使用。要点照旧回到0~1000复返值,那么数值越大代表对于当前order阶内存块而言碎屑程度越高,难以分拨。

    再回到compaction_suitable函数,有两个温雅点,一个是对于内存分拨阶大于3的苦求才会诓骗fragmentation_index进行特别判断(对于较小内存需求评估其内存碎屑程度道理道理裁减,举例单页内存分拨,伙伴系统基安分拨单元,就不触及内存外部碎屑问题);另一个是,fragmentation_index复返值需要和sysctl_extfrag_threshold阈值进行比拟,如果小于阈值,则不进行规整,此值通过/proc/sys/vm/extfrag_threshold进行设立。

    FAQ:基于上述逻辑,内核中不错通过/sys/kernel/debug/extfrag/extfrag_index文献节点稽查各个阶外部碎屑评估数据,其数值对1000取余为少量,越趋近于1,代表当前order阶内存碎屑程度高,关联代码如下:

    图片

    2.2.3 kcompactd规整特色

    内存规整的特色照旧需要从其建树compact_control来进行评释,下述代码为kcompactd规整CC设立。

    图片

    (1)指定了规整方针阶,裁减规整范围和难度;

    (2)转移页扫描器和泄气页扫描器,使用快速扫描智力;

    (3)其指定highest_zoneidx和方针阶,因此存在水线判断。

    (4)规整模式为MIGRATE_SYNC_LIGHT,轻度同步模式,会结巴;

    (5)规整范围从字据前次规整结果持续规整;

    (6)pageblock将会字据符号经受跳过,幸免等闲扫描;

    上述compact_control结构体参数含义见3.1节;

    2.3 预应性内存规整(proactive compaction)

    这属于新增内存规整性情,其领先方针是裁减大页分拨蔓延,通过大页内存块碎屑程度决策当前是否启动内存规整,提前减少内存碎屑,升迁大页分拨性能。以下畅达对此性情作念了道感性评释:

    https://lwn.net/Articles/817905/

    实践最终代码与上文的领先遐想已不疏浚,下文将依据代码评释,代码合⼊纪录如下:

    https://lore.kernel.org/all/20200616204527.19185-1-nigupta@nvidia.com/T/#u

    2.3.1 触发预应行规整

    预应性规整并非落寞存在,其融⼊kcompactd内核线程,但又与kcompactd原有功能互斥。要道代码如下:

    图片

    上述代码转头如下:

    (1)若设立预应性规整,kcompactd将会每500ms(HPAGE_FRAG_CHECK_INTERVAL_MSEC宏设立)叫醒判断当前是否需要进行规整;

    (2)若设立预应性规整,则会跳过kcompactd原有逻辑,调用预应性规整判断及规整逻辑;

    (3)预应性规整触发的依据是字据通盘node的碎屑化程度决策;

    (4)预应性规整会在规整前后统计碎屑得分,若得分增多,达标碎屑问题未处治,那么会增多kcompactd叫醒周期,幸免等闲无效的预应性规整;

    (5)每轮轮回后,均会关闭预应性规整,这是谈判到在某些镶嵌式场景下并不需要等闲的叫醒并判断,将启动预应性规整计谋交给用户层,如下合入增多了这个功能:

    https://lore.kernel.org/all/1627653207-12317-1-git-send-emailcharante@

    codeaurora.org/T/#u

    预应性规整在内核中引入vm.compaction_proactiveness文献节点,不错向其写入0~100数值,其用于指定预应性规整的积极性,数值越大积极性越高(见2.3节),如果设立为0相当于关闭,设立此数值时,pgdat->proactive_compact_trigger将会被设立为true,预应性内存规整功能绽放,此节点完毕不外多形色。

    2.3.2 碎屑程度评估

    预应性内存规整的碎屑化评价,实践是对大页碎屑程度的评价,其自身亦然为了处治大页分拨蔓延而产生,与上文各order阶内存碎屑评估样式不同,咫尺也并不针对其它order阶内存,通过如下代码进⾏界说:

    图片

    即便未开启大页功能,COMPACTION_HPAGE_ORDER等闲也会被设立为9,代表要预应性内存规整主若是针对2MB内存碎屑程度进行评估,底下从最顶层代码进行评释。

    2.3.2.1 should_proactive_compact_node

    should_proactive_compact_node 函数计较当前node碎屑程度,固然是针对

    COMPACTION_HPAGE_ORDER阶内存块,其将会对每个zone进行评估得分,并将总计zone所得分数累加,取得终末得分。此得分如果高于预应性规整水线线,代表碎屑化程度较高,需要进行预应性规整。之前通过vm.compaction_proactiveness节点设立积极性,将会影响预应性规水线,其值越高,预应性水线值越低,将越容易触发规整。预应性水线判断逻辑如下:

    图片

    小心,预应性规整是⼀种预操作,应尽可能裁减对系统性能影响,因此当kswapd运行时,预应性规整不会启动。

    2.3.2.2 fragmentation_score_wmark

    fragmentation_score_wmark 函数将会获取当前水线值,当low入参设立为true时,获取的是低水线,不然获取高水线。

    图片

    预应性水线的计较不复杂,compaction_proactiveness设立的越低,低水线值越高,高水线等闲比低水线高10,然则曲折水线皆在100数值以内。

    2.3.2.3 fragmentation_score_node

    fragmentation_score_node函数完毕明晰,即针对每⼀个zone计较一个得分,并进行累加,即为node的终末得分。

    图片

    由于每个zone大小不同,因此得分应有对应比重,fragmentation_score_zone_weighted函数完成这个计较,完毕样式较为平直。

    图片

    zone碎屑评分乘以zone的灵验内存页数目,再除以通盘node灵验内存数目,即为zone碎屑程度得分的比重值。(zone灵验页数目 / node灵验页数目) * zone当前得分浅易来说即是按照内存大小重进⾏计较。

    fragmentation_score_zone函数用于计较每个zone碎屑得分,其完毕道理是统计当前zone中⼤于等于COMPACTION_HPAGE_ORDER阶泄气区域的个数,并计较除此之外泄气内存内存与当前zone泄气内存百分比,这个占比不错评释碎屑程度,此值越高,评释顺应COMPACTION_HPAGE_ORDER阶内存块越少。

    图片

    fill_contig_page_info函数用于获取当前zone泄气页、若干个COMPACTION_HPAGE_ORDER阶内存块等等,此函数将会遍历当前zone上总计order的泄气链表进行累加计较,对于order等于COMPACTION_HPAGE_ORDER的阶内存块个数累加,对于order大于COMPACTION_HPAGE_ORDER阶内存块会拆分累加(因为包含多个COMPACTION_HPAGE_ORDER阶泄气内存区),此函数完毕并不复杂,不张开形色。

    2.3.3 预应性规整特色

    经过上述的判断,终于不错动手预应性内存规整,proactive_compact_node函数完毕此功能,代码如下:

    图片

    从compact_control结构体的设立不错看出,预应性规整与下文主动规整访佛,其指定参数有如下特色:

    (1)不指定方针阶,规整合手续进行,待扫描完了;

    (2)转移页扫描器和泄气页扫描器,不使用快速扫描智力;

    (3)规整模式为MIGRATE_SYNC_LIGHT,轻度同步模式,会结巴;

    (4)规整范围为完好zone地址空间;

    (5)pageblock将会不会字据符号经受跳过;

    上述compact_control结构体参数含义见3.1节;

    2.4 主动内存规整

    主动内存规整主若是指用户通过建设节点触发完好内存规整或针对node内存规整。内核提供两个建设节点用于触发内存规整。

    图片

    通过compact_memory节点不错触发当前总计node以及下属总计zone的内存规整,这个操作的老本极度高。另一个compact节点唯有在NUMA系统上存在,不错仅触发某一个node进行规整。不管怎么主动内存规整触发逻辑是下里巴人。

    2.4.1 主动内存规整特色

    图片

    主动内存规整compact_control设立较为浅易,讲授如下:

    (1)不指定方针阶,规整合手续进行,待扫描完了;

    (2)转移页扫描器和泄气页扫描器,不使用快速扫描智力;

    (3)规整模式为MIGRATE_SYNC,同步模式,会结巴;

    (4)规整范围为完好zone地址空间;

    (5)pageblock将会不会字据符号经受跳过;

    上述compact_control结构体参数含义见3.1节;

    主动内存规整,是内存规整最全面的本领,固然其带来的性能影响也会最大,默许情况下内核并不会触发这类内存规整。

    3.内存规整

    媒介中仍是简述规整的大要想路,将一些页转移集会,腾出更多连气儿空间。那么在真实完毕时实践需要处治的问题是内存规整范围是什么,怎么找到需要转移的页,什么页稳当转移,规整何时完了等问题。上述的问题最终皆在compact_zone函数中被处治。

    compact_zone函数针对单个zone内存区进行内存规整,这是内存规整的最小单元。其通过转移页扫描器从低地址到高地址寻找转移页,通过泄气页扫描器从高地址到低地址寻找泄气页,最终将扫描出的转移页转移至扫描出的泄气页,完成内存规整,如下图所示:

    图片

    更细节一些来说,内存规整动手后,先通过转移页扫描器扫描,况兼扫描的单元为一个pageblock,将当前pageblock中可转移的页休止后放入到待转移的链表。随后调用泄气页扫描器扫描,泄气页扫描器依然以pageblock为步长,但不再结果扫描一个pageblock,其扫描的方针是找到大于等于当前转移页数目的泄气页,上述中绿色和黄色箭头长度不同即想抒发这个逻辑。上述扫描过程将会产生转移页和泄气页,用于后续内存转移,这样就完成了内存规整的一轮操作,可能与全球交融不同,内存规整并非一次性扫描zone然后再转移,而是以这种一步一步的样式进行转移,这能平摊内存规整对性能带来的风险,况兼每轮处理后皆有契机判断当前内存规整是否不错退出。上文形色仍是极度明晰勾勒了compact_zone函数的中枢逻辑,然则实践上完毕可能愈加复杂,比如什么条目下规整不错提前完了、转移页扫描器和泄气页扫描器是否不错加快等等,这些皆属于更高层面优化的话题,下文将会简述。

    再次回到compact_zone函数,将复杂的代码剥离不错很容易得到如下中枢代码逻辑:

    图片

    (1)compact_finished函数用于判断当前规整是否完了

    (2)isolate_migratepages是转移页扫描器完毕,用于查找需要移动的页;

    (3)isolate_freepages是泄气页扫描器完毕,用于查找用于页转移的泄气页;

    (4)migrate_pages是页转移函数,将上述两个扫描器扫描结果进行页转移处理,完陈规整;

    至此,compact_zone大体逻辑仍是完成评释,下文将会对(1)~(3)函数进行细腻形色。

    3.1 内存规整参数评释

    compact_control限度了compact_zone的诸多行径,不同场景触发内存规整诉求不同,因此参数也不同,这里初步陈列常用参数含义,有助于交融不同场景下内存规整的互异。

    图片

    图片

    3.2 转移页扫描器(migrate scanner)

    isolate_migratepages函数实践即是转移页扫描器的代码完毕,其等闲会从低地址到高地址完好或部分扫描zone区域,以pageblock为步长经受一个合适pageblock调用isolate_migratepages_block函数进行内存休止,需要小心的是isolate_migratepages函数在处理完一个pageblock后就会退出,换句话说此函数一次调用只处理一个合适的pageblock。中枢代码如下所示:

    图片

    转头一下,isolate_migratepages函数主要通过如下三个函数调用完成通盘isolate责任:

    图片

    A)快速寻找合适pageblock或复返而转移扫描肇始位置(fast_find_migrateblock)

    B)判断pageblock是否合适进行休止(suitable_migration_source)

    C)实践对一个pageblock进行休止页搜索操作(isolate_migratepages_block)

    FAQ:小心若未找到合适pageblock,那么会合手续进行线性遍历查找,直到地址跳跃cc->free_pfn(最动手时此值应为zone地址区域收尾处)。

    底下将会对上述三个函数进行瓦解,完好形色isolate_migratepages函数功能细节。

    isolate_migratepages函数会复返三个复返值,内容如下:

    图片

    这些复返值将会影响compact_zone函数的复返值。

    3.2.1 转移页扫描器快速扫描

    (fast_find_migrateblock)

    fast_find_migrateblock函数会尝试快速寻找一个pageblock来进行规整,如果无法找到则复返cc->migrate_pfn(注:此值运行应为zone的肇始地址,后续应纪录上一次转移扫描器扫描完了位置幸免后续重叠扫描)看成肇始地址动手遍历,等闲谈判不即是从zone内存区域的肇始地址寻找一个么,但这样可能并不高效,在之前版块中,转移页扫描器每次轮回如实是基于zone的某个地址动手进行线性遍历,这是一种线性搜索的过程,然则随后引入了如下补丁,窜改了这一近况:

    https://patchwork.kernel.org/project/linux-mm/patch/20181214230531.GC29005@techsingularity.net/

    其方针是尽量经受一个充斥着可移动泄气页pageblock块,这样通过较少页转移,就不错知足高阶order内存苦求需求。通过查找freelist泄气内存块反向查找对应pageblock,这样效率极度高,另一方面,由于pageblock经受不是浅易的法例查找,为了幸免后续扫描重叠pageblock还需要将其进行单独象征,通过set_pageblock_skip函数完成设立,确保再次进行扫描时会跳过这个pageblock内存块。以上即是主要想路,然则具体在完毕上有好多细节比如:

    (a)如果规整方针order太小,那么十足没必要去寻找,依然使用cc->migrate_pfn看成肇始地址;

    (b)由于对于cc->order有要求,因此仅适用于平直内存回收和异步内存回收(仅这两种场景会指定cc->order,其它场景cc->order为-1);

    (c)寻找泄气页处所pageblock必须是在内存搜索范围的前1/2或1/8,这部分是最有可能被转移页扫描到得区域,幸免影响到泄气页扫描;

    (d)泄气页扫描会窜改free_list布局,尽量保证下次扫描free_list不重叠扫描泄气内存块;

    (e)若这只cc->ignore_skip_hint,则转移页扫描器不经受转移页的fast机制;

    (f)仅搜索可移动泄气页,况兼搜索范围从order - 1阶动手;

    fast_find_migrateblock函数若无法找到合适pageblock,那么将会复返cc->migrate_pages退化为常常线性扫描,请小心的是fast_find_migrateblock函数每次也只找到一个pageblock并设立其为skip,通过上述样式如真实一定程度上粗略加快针对方针阶内存规整,粗略更快整理出方针阶内存需求,然则对于完好内存规整并无实质恶果,因此fast加快查找仅适用于平直内存规整和kcompactd被迫内存规整,因为这些场景下等闲会指定例整方针阶。中枢代码如下:

    图片

    不管怎么,通过fast_find_migrateblock函数咱们不错找到一个待转移pageblock或者复返一个转移页扫描肇始地址(cc->migrate_pfn),用于后续针对pageblock内存转移页扫描使用。

    3.2.2 suitable_migration_source函数瓦解

    suitable_migration_source函数用于判断当前pageblock是否不错进行休止及转移,这部分逻辑相对浅易。

    图片

    这里需要温雅的是,如果非平直内存规整或非转移类型非ASYNC模式,则不需要判断pageblock转移类型与compact_control转移类型是否匹配,尽可能进行内存规整。

    3.2.3 pageblock内存休止(isolate_migratepages_block)

    isolate_migratepages_block函数会在单个pageblock内进行遍历,尝试将顺应规整要求的页放入对应compact_control所指向的migratepages链表,进行休止,用于后续页转移操作。函数举座结构大要如下:

    图片

    肇始和会过too_many_isolated函数查验当前内存节点上是否存在过多isolated页,如果数目过大(isolated > (inactive + active) / 2)那么字据MIGRATE模式经受处理本领,比如对于异步模式即是平直退出,对于同步模式函数将会在这里进行恭候一段时代,再轮回查验是否合适持续向下践诺。随后即是通过for轮回动手遍历这个pageblock里面总计页,并对每一个页进行判断,决定其处理本领,这是一个复杂的过程,下文拆分代码进行评释。

    3.2.3.1 大页处理

    对于大页处理,一般情况下内存规整是会经受略过,不进行整理。处理代码如下:

    图片

    从代码看当页为复合页况兼cc->alloc_contig为false时,此页将不会被规整。不管是hugetlbfs和THP大页皆属于复合页,那么问题的要道来到cc->alloc_contig是什么?

    从代码进一步鼓动不错看到,通过alloc_contig_range函数进行内存分拨时,此函数会指定苦求内存地址范围并致力于完毕,如果指定范围仍是被占用,会尝试触发平直规整进行页转移,如下代码所示:

    图片

    不错看到,这种情况下会将alloc_contig参数设立为true,在此逻辑中当调用到isolate_migratepages_block函数是会尝试规整大页,其实践的作念法是通过isolate_or_dissolve_huge_page函数完毕大页融化,这部分触及大页逻辑不再发散。

    转头,唯有当页是hugetlbfs大页况兼通过alloc_contig_range函数调用下来触发内存规整时才会进行处理,其它场景下大页处理计谋皆是略过。

    3.2.3.2 泄气物理页处理

    泄气页的处理为平直跳过,这无可厚非,独一需要小心的时,泄气页跳落后并非单页跳过,而是字据页的order阶进行跳过,代码如下:

    图片

    3.2.3.3 non-LRU物理页

    图片

    这个很故道理,上文谈到大部分可移动页应该皆是用户态的匿名页,这里奈何还会有不再LRU上的物理页呢,实践这触及到页转移性情的一种功能,有兴致的一又友不错阅读一下"Documentation/vm/page_migration.rst"著作中"Non-LRU page migration"这一末节。内核中苦求的内存等闲皆是non-LRU上况兼不可移动,然则内核提供了定制智力,开拓者不错在内核驱动中将我方苦求的内存符号为可移动,为此内核为page添加了两个新的flag即PG_movable和PG_isolated用于象征这种non-LRU况兼可转移的页。开拓者等闲使用__SetPageMovable接口主动设立这些内存页PG_movable符号,而PG_isolated象征此页仍是被休止,开拓者不需要主动设立此符号。

    咫尺咱们应该不错交融上述代码中对于__PageMovable(page)判断,如果一个non-LRU页被设立了PG_movable况兼PG_isolated还未被设立,那么代表这个页亦然不错进行转移,随后将会调用isolate_movable_page函数进行休止操作。

    问题还莫得完了,实践想要让这些在内核中平直苦求的页变为可转移,光设立符号还不行,开拓东谈主员需要自界说这些页怎么休止以及怎么转移,因此内核要求,开拓者需要在address_space_operations结构体里面完毕isolate_page、migratepage及putback_page函数。咫尺回到isolate_movable_page函数,此函数将会调用开拓东谈主员注册的isolate_page函数完成这些页休止操作,代码如下:

    图片

    3.2.3.4 pinned匿名页

    如果匿名页仍是被mlock等接口pin住,那么将会略过。

    图片

    一方面,通过page_mapping判断当前页是否为文献页;另一方面,通过page_count(page) > page_mapcount(page)判断是否被pin住,匿名页被pin住时会增多_refcount数值。

    3.2.3.5 GFP_NOFS建树下仅处理匿名页

    图片

    __GFP_FS示意内存分拨过程中不错触发文献操作,如果compact_control中gfp_mask不带__GFP_FS则结果依赖page_mapping复返值,对于匿名页而言page_mapping复返,因此上述代码判断实践的含义是当分拨高下文为无__GFP_FS况兼是文献页时将会略过,另一方面也不错讲授为GFP_NOFS时仅处理匿名页。

    那么什么时候compact_control中gfp_mask不带__GFP_FS,前文评释了触发内存回收的场景,在内存分拨失败时有可能导致直构兵发内存规整,此时内存分拨GFP符号将会被赋值到compact_control顶用于建树内存规整行径。

    图片

    不错联想这样作念的原因,实践在内存分拨的过程中直构兵发内存规整其系统并不但愿糜掷过多时代,作念有限定规整更为合适。

    其它触发内存规整的场景,等闲compact_control中gfp_mask为GFP_KERNEL,这是包含__GFP_FS,因此规整触及的内存范围等闲更广。

    3.2.3.6 不同isolate模式会影响页的处理计谋

    图片

    __isolate_lru_page_prepare完成此任务,要道代码如下:

    图片

    此处逻辑是字据休止类型筛选可转移的物理页,休止类型来源于cc-mode也即是转移类型,代码如下:

    图片

    等闲,仅当MIGRATE_ASYNC和MIGRATE_SYNC_LIGHT模式时,其休止模式为ISOLATE_ASYNC_MIGRATE异步模式,在这种模式下其会尽可能幸免休止可能会结巴页,比如代码中正在回写的页或者是脏页,这里小心如果页为脏页,然则其并非文献页(swap匿名页)或领有我方migratepage函数那么页被以为转移过程不会被结巴,不然皆无法休止。如果isolate_mode为ISOLATE_UNEVICTABLE,代表本次休止不错处理不可回收页,这个主若是针对那些被lock住的unevictable页,这些页不粗略被回收然则相沿转移。

    3.2.3.7 修改LRU即真实道理道理isolate(休止)

    图片

    在完成(1)~(6)的判断后,剩下页将粗略被休止,休止的含义即是将其从LRU链表去除(这个LRU有可能是来自于pglist_data也可能来自于页对应memcg),随后将这些页添加至cc->migratepages,用于后续页转移。

    3.2.3.8 转头

    isolate_migratepages_block函数是内存规整过程中页休止的首要函数,其详情哪些页应该被休止,哪些页应该被略过,其基本计谋如下:

    (1)大页不应被休止,然则alloc_contig_range场景下有可能触发hugetlbfs大页融化,但这已不属于内存规整场景;

    (2)泄气物理页,不会被休止;

    (3)non-LRU物理页,看成在内核分拨内存,如果开拓者为其完毕isolate_page、migratepage及putback_page函数,则不错被休止或转移;

    (4)被Pin住的匿名页,不会被休止;

    (5)GFP_NOFS分拨高下文仅休止匿名页;

    (6)不同isolate模式会影响页的处理计谋,比如ISOLATE_ASYNC_MIGRATE不会休止正在回写的页或脏页;

    3.3 泄气页扫描器(free scanner)

    isolate_freepages函数是泄气页扫描器的中枢逻辑,然则compact_zone中对于泄气页扫描器调用并扞拒直,而是通过migrate_pages辗转调用。

    图片

    migrate_pages是内存转移的基础接口,其中枢功能是将from链表中的页转移至泄气页,泄气页怎么获取则在get_new_page中完毕,这是一个函数指针,在compact_zone函数中,此接口的实践调用形态如下:

    图片

    cc->migratepages即是之前通过isolate_migratepages休止出来页,compaction_alloc则完毕怎么获取泄气页,不错联想isolate_freepages函数会在此调用,亦然本节分析的要点。compaction_alloc函数并不复杂,其用于为内存规整页迁移时苦求转移的方针内存,代码如下:

    图片

    cc->migratepages保存了需要进行规整转移的页,也即是转移扫描器扫描的结果。

    cc->freepages保存了页转移的方针泄气页,也即是泄气页扫描器扫描的结果。

    当cc->freepages为空时,尝试调用泄气页扫描器isolate_freepages函数尝试扫描休止更多泄气页用于页转移,为什么要休止呢?休止的实践是将其从伙伴分拨系统中取出不再参与系统内存分拨,仅用于内存规整转移使用。

    isolate_freepages与上文isolate_migratepages函数相对应,用于休止泄气页,用于页转移。此函数亦然free scanner(泄气页扫描器的中枢逻辑)。其完毕逻辑也与isolate_migratepages函数相似,中枢逻辑大要如下:

    图片

    isolate_freepages函数,会字据cc->free_pfn动手反向以pageblock为单元进行遍历,如果遭受合适pageblock,则会进一步对pageblock中的页进行遍历,将其中合适的泄气页进行休止,放入cc->freepages链表顶用于后续页转移使用,当收罗的泄气页迷漫迁移时将会退出。上图仅形色中枢逻辑与实践完毕存一些相差,比如fast_isolate_freepages机制引入,就会导致上述反向线性遍历的过程窜改,然则上图仍是比拟简要评释了泄气页扫描器的责任道理。

    图片

    上文从函数调用角度形色isolate_freepages函数逻辑,下文对部分首要函数调用作念详备分析。

    3.3.1 泄气页扫描器快速扫描(fast_isolate_freepages)

    老例情况下,系统通过从cc->free_pfn动手反向遍历寻找一个合适pageblock,随后针对这个pageblock休止其泄气页。然则这有可能低效,比如第一个pageblock里面并莫得若干泄气页,那么针对这个pageblock进行大部分操作皆是无效,fast_isolate_freepages即是为改善这个问题,其并不从cc->free_pfn动手进行线性查找,而是借助伙伴系统中free_list快速找到一块合适泄气区域进行休止,从某种角度看这仍是不是基于pageblock的处理了。这与fast_find_migrateblock函数方针访佛均为升迁扫描器效率。详备代码功能形色如下:

    (1)起首选取合适order即cc->search_order,等闲动手此值为cc->order - 1;

    FAQ:此功能亦然应用在平直内存回收和kcompactd场景下,因为其快速搜索的前提是cc->order和cc->search_order。其它场景下触发的内存规整,cc->order为-1,其平直复返cc->free_pfn,也就波折为线性搜索的模式;

    (2)在order的free_list中进行泄气页的遍历查找;

    图片

    (3)查找到合适泄气页后,如果泄气页落入图中下图中绿色区域,那么此泄气区域就会被优先休止,这里小心并非以pageblock为单元进行了(min_pfn为1/2处,low_pfn为3/4处);

    图片

    这个逻辑并不复杂,内存规整祈望内存向后方转移,如果泄气页太靠前,顶点点,如果泄气页落入红色区域,内存规整扫描器容易快速再会导致无法处治内存碎屑的问题;

    那么,如果泄气页落入min_pfn和low_pfn之间,那么系统会裁减在当前阶freelist遍历契机,倾向于降阶在新search_order阶的freelist中寻找绿色区域的泄气页;除此之外这种场景下,系统还会纪录当前search_order对应freelist搜索纪录(这会窜改freelist内存块法例),后续可幸免特别搜索,代码如下:

    图片

    (4)对于(3)仍是找到search_order次的泄气区域,将平直调用__isolate_free_page(接口分析详见3.3.2.1节)函数完成休止,随后将这些页放入cc->freepages链表,完成通盘操作;

    (5)到这里,仍是获胜休止了search_order阶泄气页,这并不针对pageblock,况兼对于是否仍是知足转移需求数目也并莫得敛迹,是以在函数末尾调用了fast_isolate_around函数,此函数实践是字据当前需求,阐明是否需要针对当前泄气区域处所pageblock再特别进行休止,代码如下:

    图片

    浅易转头,代码逻辑如下:

    图片

    如果当前已休止的绿色区域仍是知足诉求,那么此函数将会平直退出,如果不知足,将会尝试将这个泄气区域对应pageblock左侧和右侧区域通过isolate_freepages_block函数进行泄气页休止。

    不管怎么,fast_isolate_freepages接口皆尝试以更快速的样式获取泄气页,有可能这个泄气页并不是紧贴着cc->free_pfn,然则它一定在后1/4范围内,况兼它会窜改freelist的结构幸免重叠判断疏浚泄气页,这是一个优化功能。对于内存规整若想浅易交融,不错忽略此处细节平直交融为从zone末尾动手线性查找。

    3.3.2 泄气页休止(isolate_freepages_block)

    isolate_freepages_block函数,即在指定内存范围内正向遍历,将合适的泄气页进行休止加入到cc->freepages链表,用于后续页转移,这是isolate_freepages函数得中枢函数调用,等闲isolate_freepages每次调用会传递一个pageblock范围进行泄气页休止。要道代码如下:

    图片

    函数要道逻辑评释:

    (1)函数在pageblock内遍历并不一定按照页为单元,参数stride看成步长存在;

    (2)复合页将会略过;

    (3)非泄气页将会略过;

    (4)顺应上述要求泄气页通过__isolate_free_page进行休止操作,随后将这些加入到cc->freepages链表;

    (5)如果当前收罗泄气页仍是大于当前仍是收罗转移页则退出轮回;

    上述即isolate_freepages_block函数的逻辑,这里面需要温雅一个strict参数,如果该参数为true,那么isolate_freepages_block函数将会以页为遍历单元进行遍历及休止,况兼不会再字据上述(5)条目提前退出,而是完好休止通盘pageblock中合适的泄气页。

    3.3.2.1 伙伴系统处理(__isolate_free_page)

    泄气页休止与转移页的休止不太疏浚,由于泄气页还属于伙伴系统统领范围内,伙伴体统提供专用休止接口,即__isolate_free_page函数。

    图片

    此结构逻辑明晰,不外多赘述。

    3.4 内存规整退出判断(compact_finished)

    compact_finished用于判断当前规整是否完了,有多种不同条目导致规整完了,况兼复返值不同,由于compact_finished函数较长况兼对于交融内存规整较为首要,因此代码拆分评释。

    3.4.1 扫描器再会

    上文评释migrate scanner从正向扫描,free scanner反向扫描,当两者再会,代表扫描和转移操作完了,因此规整完了,这是最为常常的一种退出样式,代码如下:

    图片

    扫描器再会场景退出,上述代码注释完好符号其逻辑,对于怎么判断扫描器再会,实践字据cc->free_pfn和cc->migrate_pfn的大小容易判断,不进行函数代码评释。

    3.4.2 预应性规整退出条目

    这里预应性规整除了扫描器再会退出条目外,领有特别退出条目。

    图片

    fragmentation_score_zone和fragmentation_score_wmark均为预应性规整碎屑评估函数,浅易说当前如果对于大页阶碎屑评估分数低于预应性碎屑水线时,则罢手规整,复返获胜。对于预应性规整碎屑评估逻辑详见2.3.2节。

    3.4.3 direct规整模式特别退出条目

    平直内存规整在识别是否获胜时,如果判断当前苦求需求已知足,况兼分拨转移类型也知足一定要求即可退出平直规整逻辑。为安在苦求不错知足的情况下还要知足一定要求才能退出呢,主要谈判是即便知足分拨,但也不成引入潜在扩大内存碎屑化的情况,不然将会等闲投入平直内存规整。

    图片

    3.4.4 复返值转头

    1.COMPACT_CONTINUE:代表内存规整未完了,持续规整;

    2.COMPACT_COMPLETE:在cc->whole_zone为true场景下,完周至区域扫描和规整,将复返此值;

    3.COMPACT_PARTIAL_SKIPPED:多种场景下均会复返此值,举例:

    (1)cc->whole_zone为false场景下,扫描和规整完成,将会范围此值;

    (2)在proactive_compaction模式下,如果此时kswapd运行,规整也将会罢手,复返此值;

    4.COMPACT_SUCCESS:代表规整获胜,此值亦然多种场景下均会复返:

    (1)proactive规整模式下,碎屑化得分达标,主动退出规整,即复返获胜;

    (2)direct规整模式下,需求order阶及转移类型链表上,已有足量内存,即复返获胜;

    (3)direct规整模式下,需求order阶上如果有足量CMA内存,前提是自身需求亦然可转移页(不然CMA内存苦求时无法转移),即复返获胜;

    (4)direct规整模式下,不错从其它转移类型偷到内存,在知足一定条目下也会范围获胜;

    5.COMPACT_CONTENDED:若当前进度被强制退出或依然合手有zone lock,则规整逻辑复返此值,属于一种极端退出情景;

    4.内存规整转头

    代码分析基本完成,再对内存规整统计信息及可调文献节点进行简要评释。

    4.1 内存规整统计信息

    在上文的代码形色中忽略内存规整关联信息统计逻辑,统计信息不错通过/proc/vmstat文献节点进查询,关联信息含义评释如下:

    图片

    4.2 内存规整文献节点

    图片

    4.3 转头

    内存规整是一个较重内存碎屑优化措施,在使用时内核较为严慎,当前有平直内存规整、kcompactd内存规整、预应性内存规整及主动内存规整四种场景,这些场景涵盖在内存分拨、内存回收等高下文,由于规整的诉乞降遑急程度不同,其通过compact_control结构体参数限度compact_zone内存规整行径包括但不限于内存扫描范围、页转移的智力、转移页是否稳当规整及是否不错结巴等等。

    另一方面,内存规整的中枢逻辑在于转移页扫描器(migrate scanner)和泄气页扫描器(free scanner)运作道理,包括哪些页不错看成转移页或泄气页,何时内存规整完了等等这些平直影响对内存规整交融。

    由于个东谈主智力有限,文中如有松弛或空幻,请海涵指正。

    参考畅达:

    【1】https://elixir.bootlin.com/linux/v5.15/source/mm/compaction.c

    【2】https://lore.kernel.org/all/20190118175136.31341-23-mgorman@techsingularity.net/T/#u

    【3】https://lore.kernel.org/all/20181123114528.28802-5-mgorman@techsingularity.net/T/#u

    【4】https://lwn.net/Articles/817905/

    【5】https://lore.kernel.org/all/20200616204527.19185-1-nigupta@nvidia.com/T/#u

    【6】https://lore.kernel.org/all/1627653207-12317-1-git-send-emailcharante@codeaurora.org/T/#u

    【7】https://patchwork.kernel.org/project/linux-mm/patch/20181214230531.GC29005@techsingularity.net/亚洲色图 千百度

    本站仅提供存储就业,总计内容均由用户发布,如发现存害或侵权内容,请点击举报。



    Powered by ai 巨乳 @2013-2022 RSS地图 HTML地图

    Copyright Powered by365建站 © 2013-2024