您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關linux中swappiness參數有什么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
swappiness是Linux的一個內核參數,控制系統在進行swap時,內存使用的相對權重。swappiness參數值可設置范圍在0到100之間。 此參數值越低,就會讓Linux系統盡量少用swap分區,多用內存;參數值越高就是反過來,使內核更多的去使用swap空間。
page reclaim發生的場景主要有兩類,一個是kswapd后臺線程進行的活動,另一個是direct reclaim,即分配頁時沒有空閑內存滿足,需要立即直接進行的頁回收。大體上內存分配的流程會分為兩部分,一部分是fast path,另一部分是slow path,通常內存使用非緊張情況下,都會在fast path就可以滿足要求。并且fast path下的內存分配不會出現dirty writeback及swap等頁回收引起的IO阻塞情況。
fast path大體流程如下:1.如果系統掛載使用了memory cgroup,則首先檢查是否超過cgroup限額,如果超過則進行direct reclaim,通過do_try_to_free_pages完成。如果沒超過則進行cgroup的charge工作(charge是通過兩階段提交完成的,這里不展開了)。2.從本地prefered zone內存節點查找空閑頁,需要判斷是否滿足系統watermark及dirty ratio的要求,如果滿足則從buddy system上摘取相應page,否則嘗試對本地prefered zone進行頁回收,本次fast path下頁回收只會回收clean page,即不會考慮dirty page以及mapped page,這樣就不會產生任何swap及writeback,即不會引起任何blocking的IO操作,如果這次回收仍然無法滿足請求的內存頁數目則進入slow path
slow path大體流程如下:\1. 首先喚醒kswapd進行page reclaim后臺操作。\2. 重新嘗試本地prefered zone進行分配內存,如果失敗會根據請求的GFP相關參數決定是否嘗試忽略watermark, dirty ratio以及本地節點分配等要求進行再次重試,這一步中如果分配頁時有指定GFP_NOFAIL標記,則分配失敗會一直等待重試。\3. 如果沒有GFP_NOFAIL標記,則會需開始進行page compact及page direct reclaim操作,之后如果仍然沒有可用內存,則進入OOM流程。
相關內容可以參閱內核代碼__alloc_pages函數的邏輯,另外無論page reclaim是由誰發起的,最終都會統一入口到shrink_zone,即針對每個zone獨立進行reclaim操作,最終會進入shrink_lruvec函數,進行每個zone相應page lru鏈表的掃描與回收操作。
頁回收大體流程會先在每個zone上掃描相應的page鏈表,主要包括inactive anon/active anon(匿名頁鏈表)以及inactive file/active file鏈表(file cache/映射頁鏈表),一共四條鏈表,我們所有使用過的page在被回收前基本是保存在這四條鏈表中的某一條中的(還有一部分在unevictable鏈表中,忽略),根據其被引用的次數會決定其處于active還是inactive鏈表中,根據其類型決定處于anon還是file鏈表中。
頁回收總體會掃描逐個內存節點的所有zone,然后先掃描active,將不頻繁訪問的頁挪到inactive鏈表中,隨后掃描inactive鏈表,會將其中被頻繁引用的頁重新挪回到active中,確認不頻繁的頁則最終被回收,如果是file based的頁則根據是否clean進行釋放或回寫(writeback,filecache則直接釋放),如果是anon則進行swap,所以本文實際關心的是swappiness參數對anon鏈表掃描的影響。
另外還需要了解前面描述的四個鏈表原來是放在zone數據結構上的,后來引入了mem_cgroup則,重新定義了一組mem_cgroup_per_zone/mem_cgroup_per_node的數據結構,這四個鏈表同時定義在這組數據結構上,如果系統開啟了mem cgroup則使用后者,否則用前者。
另外再重點說下swap只是page reclaim的一種處理措施,主要針對anon page,我們最終來看下swappiness的確切含義
page reclaim邏輯中對前面所述四個鏈表進行掃描的邏輯在vmscan.c中的get_scan_count函數內,該函數大部分邏輯注釋寫得非常清楚,我們簡單梳理下,主要關注scan_balance變量的取值:
\1. 首先如果系統禁用了swap或者沒有swap空間,則只掃描file based的鏈表,即不進行匿名頁鏈表掃描代碼如下:
?
if (!sc->may_swap || (get_nr_swap_pages()
\2. 如果當前進行的不是全局頁回收(cgroup資源限額引起的頁回收),并且swappiness設為0,則不進行匿名頁鏈表掃描,這個是沒得商量,這里swappiness值直接決定了是否有swap發生,設成0則肯定不會發生,另外需要注意,這種情況下需要設置的是cgroup配置文件memory.swappiness,而不是全局的sysctl vm.swappiness代碼如下:
?
if (!global_reclaim(sc) && !vmscan_swappiness(sc)) {scan_balance = SCAN_FILE;goto out;}
\3. 如果進行鏈表掃描前設置的priority(這個值決定掃描多少分之一的鏈表元素)為0,且swappiness非0,則可能會進行swap代碼如下:
?
if (!sc->priority && vmscan_swappiness(sc)) {scan_balance = SCAN_EQUAL;goto out;}
\4. 如果是全局頁回收,并且當前空閑內存和所有file based鏈表page數目的加和都小于系統的high watermark,則必須進行匿名頁回收,則必然會發生swap,可以看到這里swappiness的值如何設置是完全無關的,這也解釋了為什么其為0,系統也會進行swap的原因,另外最后我們會詳細解釋系統page watermark是如何計算的。代碼如下:
?
anon = get_lru_size(lruvec, LRU_ACTIVE_ANON) +get_lru_size(lruvec, LRU_INACTIVE_ANON);file = get_lru_size(lruvec, LRU_ACTIVE_FILE) +get_lru_size(lruvec, LRU_INACTIVE_FILE);
if (global_reclaim(sc)) {free = zone_page_state(zone, NR_FREE_PAGES);if (unlikely(file + free
\5. 如果系統inactive file鏈表比較充足,則不考慮進行匿名頁的回收,即不進行swap代碼如下:
?
if (!inactive_file_is_low(lruvec)) {scan_balance = SCAN_FILE;goto out;}
\6. 最后一種情況則要根據swappiness值與之前統計的file與anon哪個更有價值來綜合決定file和anon鏈表掃描的比例,這時如果swappiness設置成0,則也不會掃描anon鏈表,即不進行swap,代碼比較多,不再貼出。
前面看到系統內存watermark對頁回收機制是有決定影響的,其實在內存分配中也會頻繁用到這個值,確切的說它有三個值,分別是low,min和high,根據分配頁時來指定用哪個,如果系統空閑內存低于相應watermark則分配會失敗,這也是進入slow path或者wakeup kswapd的依據。
實際這個值的計算是通過sysctl里的vm.min_free_kbytes來決定的,大體的計算公式如下:
?
pages_min = min_free_kbytes >> (PAGE_SHIFT – 10);tmp = (u64)pages_min * zone->managed_pages;do_div(tmp, lowmem_pages);zone->watermark[WMARK_MIN] = tmp;zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + (tmp >> 2);zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1);
即根據min_free_kbytes的值按照每個zone管理頁面的比例算出zone的min_watermark,然后再加min的1/4就是low,加1/2就是high了
關于“linux中swappiness參數有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。