日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )

發布時間:2023/12/20 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、retry 標號代碼分析
  • 二、retry 標號完整代碼

在 【Linux 內核 內存管理】物理分配頁 ② ( __alloc_pages_nodemask 函數參數分析 | __alloc_pages_nodemask 函數分配物理頁流程 ) 博客中 , 分析了 __alloc_pages_nodemask 函數分配物理頁流程如下 :

首先 , 根據 gfp_t gfp_mask 分配標志位 參數 , 得到 " 內存節點 “ 的 首選 ” 區域類型 " " 遷移類型 " ;

然后 , 執行 " 快速路徑 " , 第一次分配 嘗試使用 低水線分配 ;

如果上述 " 快速路徑 " 分配失敗 , 則執行 " 慢速路徑 " 分配 ;

上述涉及到了 " 快速路徑 " 和 " 慢速路徑 " 222 種物理頁分配方式 ;


繼續接著上一篇博客 【Linux 內核 內存管理】物理分配頁 ⑧ ( __alloc_pages_slowpath 慢速路徑調用函數源碼分析 | 獲取首選內存區域 | 異步回收內存頁 | 最低水線也分配 | 直接分配 ) 分析 __alloc_pages_slowpath 慢速路徑 內存分配 調用函數 的后續部分源碼 ;





一、retry 標號代碼分析



下面開始分析 __alloc_pages_slowpath 慢速路徑 內存分配 調用函數 中的 retry 標號下的代碼 ,

調用 wake_all_kswapds 函數 , 確保 " 頁回收線程 " 在遍歷時 保持喚醒狀態 , 不會由于意外導致休眠 ;

retry:/* Ensure kswapd doesn't accidentally go to sleep as long as we loop */if (gfp_mask & __GFP_KSWAPD_RECLAIM)wake_all_kswapds(order, ac);

源碼路徑 : linux-4.12\mm\page_alloc.c#3794


調用 get_page_from_freelist 函數 , 嘗試使用 調整過的 區域列表 和 分配標志位 進行 內存分配 , 如果 內存分配成功 , 則跳轉到 got_pg 標號執行 ;

/* Attempt with potentially adjusted zonelist and alloc_flags */page = get_page_from_freelist(gfp_mask, order, alloc_flags, ac);if (page)goto got_pg;

源碼路徑 : linux-4.12\mm\page_alloc.c#3811


如果 調用者 不想等待 浪費時間 , 則不執行后續操作 , 跳轉到 nopage 處執行 后續代碼 ;

/* Caller is not willing to reclaim, we can't balance anything */if (!can_direct_reclaim)goto nopage;

源碼路徑 : linux-4.12\mm\page_alloc.c#3817


調用 __alloc_pages_direct_reclaim 函數 , 直接進行頁回收 ;

/* Try direct reclaim and then allocating */page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac,&did_some_progress);if (page)goto got_pg;

源碼路徑 : linux-4.12\mm\page_alloc.c#3833


調用 __alloc_pages_direct_compact 函數 , 針對申請 物理頁 階數 大于 0 的情況 , 執行 同步模式 下的 內存碎片整理 操作 ;

/* Try direct compaction and then allocating */page = __alloc_pages_direct_compact(gfp_mask, order, alloc_flags, ac,compact_priority, &compact_result);if (page)goto got_pg;

源碼路徑 : linux-4.12\mm\page_alloc.c#3839


再次進行判斷 , 如果調用者 不想進行循環 , 則放棄內存申請 , 跳轉到 nopage 標號執行 ;

/* Do not loop if specifically requested */if (gfp_mask & __GFP_NORETRY)goto nopage;

源碼路徑 : linux-4.12\mm\page_alloc.c#3845


如果 申請 物理頁 階數 大于 0 , 則調用 should_compact_retry 函數 , 判斷是否重新嘗試 執行 內存碎片整理操作 , 如果判定成功 , 則繼續跳轉到 retry 標號處再執行一遍 ;

/** It doesn't make any sense to retry for the compaction if the order-0* reclaim is not able to make any progress because the current* implementation of the compaction depends on the sufficient amount* of free memory (see __compaction_suitable)*/if (did_some_progress > 0 &&should_compact_retry(ac, order, alloc_flags,compact_result, &compact_priority,&compaction_retries))goto retry;

源碼路徑 : linux-4.12\mm\page_alloc.c#3865


調用 read_mems_allowed_retry 函數 , 判定 cpuset 是否允許修改當前進程 從 指定的內存節點申請 物理頁內存 ;

/** It's possible we raced with cpuset update so the OOM would be* premature (see below the nopage: label for full explanation).*/if (read_mems_allowed_retry(cpuset_mems_cookie))goto retry_cpuset;

源碼路徑 : linux-4.12\mm\page_alloc.c#3875


調用 __alloc_pages_may_oom 函數 , 如果內存耗盡 , 分配內存失敗 , 則殺死一個進程 , 以獲取足夠的內存空間 ;

/* Reclaim has failed us, start killing things */page = __alloc_pages_may_oom(gfp_mask, order, ac, &did_some_progress);if (page)goto got_pg;

源碼路徑 : linux-4.12\mm\page_alloc.c#3879


假如 當前進程 出現內存耗盡的情況 , 則忽略 最低水線 的限制 , 或者 不允許使用 緊急保留內存 ;

/* Avoid allocations with no watermarks from looping endlessly */if (test_thread_flag(TIF_MEMDIE) &&(alloc_flags == ALLOC_NO_WATERMARKS ||(gfp_mask & __GFP_NOMEMALLOC)))goto nopage;

源碼路徑 : linux-4.12\mm\page_alloc.c#3884


內存耗盡殺手 取得一定進展 , 繼續跳轉到 retry 標號重新嘗試分配內存 ;

/* Retry as long as the OOM killer is making progress */if (did_some_progress) {no_progress_loops = 0;goto retry;}

源碼路徑 : linux-4.12\mm\page_alloc.c#3890





二、retry 標號完整代碼



retry 標號完整代碼 :

static inline struct page * __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,struct alloc_context *ac) {... retry:/* Ensure kswapd doesn't accidentally go to sleep as long as we loop */if (gfp_mask & __GFP_KSWAPD_RECLAIM)wake_all_kswapds(order, ac);if (gfp_pfmemalloc_allowed(gfp_mask))alloc_flags = ALLOC_NO_WATERMARKS;/** Reset the zonelist iterators if memory policies can be ignored.* These allocations are high priority and system rather than user* orientated.*/if (!(alloc_flags & ALLOC_CPUSET) || (alloc_flags & ALLOC_NO_WATERMARKS)) {ac->zonelist = node_zonelist(numa_node_id(), gfp_mask);ac->preferred_zoneref = first_zones_zonelist(ac->zonelist,ac->high_zoneidx, ac->nodemask);}/* Attempt with potentially adjusted zonelist and alloc_flags */page = get_page_from_freelist(gfp_mask, order, alloc_flags, ac);if (page)goto got_pg;/* Caller is not willing to reclaim, we can't balance anything */if (!can_direct_reclaim)goto nopage;/* Make sure we know about allocations which stall for too long */if (time_after(jiffies, alloc_start + stall_timeout)) {warn_alloc(gfp_mask & ~__GFP_NOWARN, ac->nodemask,"page allocation stalls for %ums, order:%u",jiffies_to_msecs(jiffies-alloc_start), order);stall_timeout += 10 * HZ;}/* Avoid recursion of direct reclaim */if (current->flags & PF_MEMALLOC)goto nopage;/* Try direct reclaim and then allocating */page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac,&did_some_progress);if (page)goto got_pg;/* Try direct compaction and then allocating */page = __alloc_pages_direct_compact(gfp_mask, order, alloc_flags, ac,compact_priority, &compact_result);if (page)goto got_pg;/* Do not loop if specifically requested */if (gfp_mask & __GFP_NORETRY)goto nopage;/** Do not retry costly high order allocations unless they are* __GFP_REPEAT*/if (costly_order && !(gfp_mask & __GFP_REPEAT))goto nopage;if (should_reclaim_retry(gfp_mask, order, ac, alloc_flags,did_some_progress > 0, &no_progress_loops))goto retry;/** It doesn't make any sense to retry for the compaction if the order-0* reclaim is not able to make any progress because the current* implementation of the compaction depends on the sufficient amount* of free memory (see __compaction_suitable)*/if (did_some_progress > 0 &&should_compact_retry(ac, order, alloc_flags,compact_result, &compact_priority,&compaction_retries))goto retry;/** It's possible we raced with cpuset update so the OOM would be* premature (see below the nopage: label for full explanation).*/if (read_mems_allowed_retry(cpuset_mems_cookie))goto retry_cpuset;/* Reclaim has failed us, start killing things */page = __alloc_pages_may_oom(gfp_mask, order, ac, &did_some_progress);if (page)goto got_pg;/* Avoid allocations with no watermarks from looping endlessly */if (test_thread_flag(TIF_MEMDIE) &&(alloc_flags == ALLOC_NO_WATERMARKS ||(gfp_mask & __GFP_NOMEMALLOC)))goto nopage;/* Retry as long as the OOM killer is making progress */if (did_some_progress) {no_progress_loops = 0;goto retry;}... }

源碼路徑 : linux-4.12\mm\page_alloc.c#3792

總結

以上是生活随笔為你收集整理的【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。