新聞中心
Linux操作系統(tǒng)作為一種開源的操作系統(tǒng),已經(jīng)在業(yè)界得到了廣泛的應(yīng)用和認(rèn)可。作為操作系統(tǒng)的核心,內(nèi)核的有效性和優(yōu)化對整個操作系統(tǒng)的性能和效率至關(guān)重要,而內(nèi)核物理頁分配機制則是內(nèi)核實現(xiàn)高效的關(guān)鍵之一。

內(nèi)核物理頁分配是指內(nèi)核在管理物理內(nèi)存時,對于進程請求的空間進行合理的分配。這個過程不僅關(guān)乎進程運行的效率,也與操作系統(tǒng)的安全性和穩(wěn)定性密切相關(guān)。
在Linux內(nèi)核中,物理頁分配是通過伙伴系統(tǒng)實現(xiàn)的。為了提高內(nèi)核物理頁分配的效率,Linux內(nèi)核引用了伙伴算法,這種算法能夠避免內(nèi)存碎片和浪費的問題。
伙伴系統(tǒng)中,內(nèi)存被分成一些等大小的塊,每個塊都有相應(yīng)的伙伴——一個相同大小的塊。當(dāng)塊被申請時,內(nèi)核會優(yōu)先選擇一組大小相同的伙伴,然后再把它們拼接成一個更大的塊,然后再次迭代,直到找到一個塊大于等于需要的大小。
隨著處理器速度和內(nèi)存大小的持續(xù)增長,對Linux內(nèi)核物理頁分配機制的優(yōu)化需求越來越高。而內(nèi)存分配與釋放是頻繁發(fā)生的事件,它們直接影響到操作系統(tǒng)的性能和用戶體驗。
有很多因素影響了Linux內(nèi)核物理頁分配的效率,其中最重要的因素是內(nèi)存分配的方式。內(nèi)存分配方式的不同,直接影響到操作系統(tǒng)的性能和效率,而采用的分配方式不同,會對操作系統(tǒng)的內(nèi)存管理、交換等部分造成不同的影響。
在低端服務(wù)器和桌面計算機上,直接內(nèi)存分配是最常用的分配方式。這種分配方式的優(yōu)勢在于速度很快,因為它不需要進行復(fù)雜的地址轉(zhuǎn)換和頁表查找。但是它的缺點也很明顯,它沒有按照邏輯分類的方式進行分配,可能會造成內(nèi)存碎片的問題。
另一種是池式內(nèi)存分配。這種分配方式與直接內(nèi)存分配方式類似,但它會根據(jù)需求動態(tài)地分配內(nèi)存。這種方式的優(yōu)點是可以盡量避免內(nèi)存碎片問題,然而,池式內(nèi)存分配不能很好地處理大塊內(nèi)存的申請請求。
雖然Linux內(nèi)核伙伴系統(tǒng)已經(jīng)為系統(tǒng)的內(nèi)存管理帶來了不小的提升,但是隨著計算機發(fā)展的迅速,對于內(nèi)核物理頁分配的要求也越來越高。
除了伙伴算法和內(nèi)存分配類型之外,需要考慮的其他因素包括內(nèi)存交換、進程的內(nèi)存使用情況和內(nèi)存管理策略。在內(nèi)核物理頁分配方面,需要考慮的關(guān)鍵要素包括使用的算法、內(nèi)存池的大小、分配和釋放的鎖等等。
Linux內(nèi)核物理頁分配是提高操作系統(tǒng)效率的一個非常重要的因素。盡管Linux內(nèi)核已經(jīng)引入了伙伴算法和池式內(nèi)存分配等多種方式來優(yōu)化物理頁分配機制,但是在選擇合適的分配方式時,還需根據(jù)實際需求情況靈活選擇。優(yōu)化物理頁分配機制不僅是內(nèi)核開發(fā)人員的責(zé)任,也需要操作系統(tǒng)的用戶和系統(tǒng)管理員參與協(xié)同。通過共同努力,才能讓Linux系統(tǒng)內(nèi)核物理頁分配機制變得更加有效和高效。
相關(guān)問題拓展閱讀:
- malloc()之后,內(nèi)核發(fā)生了什么?
malloc()之后,內(nèi)核發(fā)生了什么?
考慮這樣一種常見的情況:用戶進程調(diào)用malloc()動態(tài)分配了一塊內(nèi)存空間,悔亮再對這塊內(nèi)存進行訪問。這些用戶空間發(fā)生的事會引發(fā)內(nèi)核空間的那些反映?本文將簡單為您解答。1.brk系統(tǒng)調(diào)用服務(wù)例程malloc()是一個API,這個函數(shù)在庫中封裝了系統(tǒng)調(diào)用brk。因此如果調(diào)用malloc,那么首先會引發(fā)brk系統(tǒng)調(diào)用執(zhí)行的過程。brk()在內(nèi)核中對應(yīng)的系統(tǒng)調(diào)用服務(wù)例程為SYSCALL_DEFINE1(brk, unsigned long, brk),參數(shù)brk用來指定heap段新的結(jié)束地址,也就是重新指定mm_struct結(jié)構(gòu)中的brk字段。brk系統(tǒng)調(diào)用服務(wù)例程首先會確定heap段的起始地址min_brk,然后再檢查資源的限制問題。接著,將新老heap地址分別按枯渣照頁大小對齊,對齊后的地址分別存儲與newbrk和okdbrk中。brk()系統(tǒng)調(diào)用本身既可以縮小堆大小,又可以擴大堆大小。縮小堆這個功能是通過調(diào)用do_munmap()完成的。如果要擴大堆的大小,那么必須先通過find_vma_intersection()檢查擴大以后的堆是否與已經(jīng)存在的某個虛擬內(nèi)存重合,如何重合則直接退出。否則,調(diào)用do_brk()進行接下來擴大堆的各種工作。 SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; unsigned long newbrk, oldbrk; struct mm_struct *mm = current->mm; unsigned long min_brk; down_write(&mm->mmap_sem); #ifdef CONFIG_COMPAT_BRK min_brk = mm->end_code; #else min_brk = mm->start_brk; #endif if (brk start_brk) + (mm->end_data – mm->start_data) > rlim) newbrk = PAGE_ALIGN(brk); oldbrk = PAGE_ALIGN(mm->brk); if (oldbrk == newbrk) goto set_brk; if (brk brk) { if (!do_munmap(mm, newbrk, oldbrk-newbrk)) goto set_brk; goto out; } if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) goto out; if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) goto out; set_brk: mm->brk = brk; out: retval = mm->brk; up_write(&mm->mmap_sem); return retval; } brk系統(tǒng)調(diào)用服務(wù)例程最后將返回堆的新結(jié)束地址。2.擴大堆用戶進程調(diào)用malloc()會使得內(nèi)核調(diào)用brk系統(tǒng)調(diào)用服務(wù)例程,因為malloc總是動態(tài)的分配內(nèi)存空間,因此該服務(wù)例程此時會進入第二條執(zhí)行路徑中,即擴大堆。do_brk()主要完成以下工作:1.通過get_unmapped_area()在當(dāng)前進程的地址空間中查找一個符合len大小的線性區(qū)間,并且該線性區(qū)間的必須在addr地址之后。如果找到了這個空閑的線性區(qū)間,則返回該區(qū)間的起始地址,否則返回錯誤代碼-ENOMEM;2.通過find_vma_prepare()在當(dāng)前進程所有線性區(qū)組成的紅黑樹中依次遍歷每個vma,以確定上一步找到的新區(qū)間之前的線性區(qū)對象的位置。如果addr位于某個現(xiàn)存的vma中,則調(diào)用do_munmap()刪除這個線性區(qū)。如果刪除成功則繼續(xù)查找,否則返回錯誤代碼。3.目前已經(jīng)找到了一個合碧敗寬適大小的空閑線性區(qū),接下來通過vma_merge()去試著將當(dāng)前的線性區(qū)與臨近的線性區(qū)進行合并。如果合并成功,那么該函數(shù)將返回prev這個線性區(qū)的vm_area_struct結(jié)構(gòu)指針,同時結(jié)束do_brk()。否則,繼續(xù)分配新的線性區(qū)。4.接下來通過kmem_cache_zalloc()在特定的slab高速緩存vm_area_cachep中為這個線性區(qū)分配vm_area_struct結(jié)構(gòu)的描述符。5.初始化vma結(jié)構(gòu)中的各個字段。6.更新mm_struct結(jié)構(gòu)中的vm_total字段,它用來同級當(dāng)前進程所擁有的vma數(shù)量。7.如果當(dāng)前vma設(shè)置了VM_LOCKED字段,那么通過mlock_vma_pages_range()立即為這個線性區(qū)分配物理頁框。否則,do_brk()結(jié)束??梢钥吹?,do_brk()主要是為當(dāng)前進程分配一個新的線性區(qū),在沒有設(shè)置VM_LOCKED標(biāo)志的情況下,它不會立刻為該線性區(qū)分配物理頁框,而是通過vma一直將分配物理內(nèi)存的工作進行延遲,直至發(fā)生缺頁異常。3.缺頁異常的處理過程經(jīng)過上面的過程,malloc()返回了線性地址,如果此時用戶進程訪問這個線性地址,那么就會發(fā)生缺頁異常(Page Fault)。整個缺頁異常的處理過程非常復(fù)雜,我們這里只關(guān)注與malloc()有關(guān)的那一條執(zhí)行路徑。當(dāng)CPU產(chǎn)生一個異常時,將會跳轉(zhuǎn)到異常處理的整個處理流程中。對于缺頁異常,CPU將跳轉(zhuǎn)到page_fault異常處理程序中: //linux-2.6.34/arch/x86/kernel/entry_32.S ENTRY(page_fault) RING0_EC_FRAME pushl $do_page_fault CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: ………… jmp ret_from_exception CFI_ENDPROC END(page_fault) 該異常處理程序會調(diào)用do_page_fault()函數(shù),該函數(shù)通過讀取CR2寄存器獲得引起缺頁的線性地址,通過各種條件判斷以便確定一個合適的方案來處理這個異常。3.1.do_page_fault()該函數(shù)通過各種條件來檢測當(dāng)前發(fā)生異常的情況,但至少do_page_fault()會區(qū)分出引發(fā)缺頁的兩種情況:由編程錯誤引發(fā)異常,以及由進程地址空間中還未分配物理內(nèi)存的線性地址引發(fā)。對于后一種情況,通常還分為用戶空間所引發(fā)的缺頁異常和內(nèi)核空間引發(fā)的缺頁異常。內(nèi)核引發(fā)的異常是由vmalloc()產(chǎn)生的,它只用于內(nèi)核空間內(nèi)存的分配。顯然,我們這里需要關(guān)注的是用戶空間所引發(fā)的異常情況。這部分工作從do_page_fault()中的good_area標(biāo)號處開始執(zhí)行,主要通過handle_mm_fault()完成。 //linux-2.6.34/arch/x86/mm/fault.c dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { ………… good_area: write = error_code & PF_WRITE; if (unlikely(access_error(error_code, write, vma))) { bad_area_access_error(regs, error_code, address); return; } fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); ………… } 3.2.handle_mm_fault()該函數(shù)的主要功能是為引發(fā)缺頁的進程分配一個物理頁框,它先確定與引發(fā)缺頁的線性地址對應(yīng)的各級頁目錄項是否存在,如何不存在則分進行分配。具體如何分配這個頁框是通過調(diào)用handle_pte_fault()完成的。 int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, unsigned int flags) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; ………… pgd = pgd_offset(mm, address); pud = pud_alloc(mm, pgd, address); if (!pud) return VM_FAULT_OOM; pmd = pmd_alloc(mm, pud, address); if (!pmd) return VM_FAULT_OOM; pte = pte_alloc_map(mm, pmd, address); if (!pte) return VM_FAULT_OOM; return handle_pte_fault(mm, vma, address, pte, pmd, flags); } 3.3.handle_pte_fault()該函數(shù)根據(jù)頁表項pte所描述的物理頁框是否在物理內(nèi)存中,分為兩大類:請求調(diào)頁:被訪問的頁框不再主存中,那么此時必須分配一個頁框。寫時復(fù)制:被訪問的頁存在,但是該頁是只讀的,內(nèi)核需要對該頁進行寫操作,此時內(nèi)核將這個已存在的只讀頁中的數(shù)據(jù)復(fù)制到一個新的頁框中。用戶進程訪問由malloc()分配的內(nèi)存空間屬于之一種情況。對于請求調(diào)頁,handle_pte_fault()仍然將其細(xì)分為三種情況: static inline int handle_pte_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, unsigned int flags) { ………… if (!pte_present(entry)) { if (pte_none(entry)) { if (vma->vm_ops) { if (likely(vma->vm_ops->fault)) return do_linear_fault(mm, vma, address, pte, pmd, flags, entry); } return do_anonymous_page(mm, vma, address, pte, pmd, flags); } if (pte_file(entry)) return do_nonlinear_fault(mm, vma, address, pte, pmd, flags, entry); return do_swap_page(mm, vma, address, pte, pmd, flags, entry); } ………… } 1.如果頁表項確實為空(pte_none(entry)),那么必須分配頁框。如果當(dāng)前進程實現(xiàn)了vma操作函數(shù)中的fault鉤子函數(shù),那么這種情況屬于基于文件的內(nèi)存映射,它調(diào)用do_linear_fault()進行分配物理頁框。否則,內(nèi)核將調(diào)用針對匿名映射分配物理頁框的函數(shù)do_anonymous_page()。2.如果檢測出該頁表項為非線性映射(pte_file(entry)),則調(diào)用do_nonlinear_fault()分配物理頁。3.如果頁框事先被分配,但是此刻已經(jīng)由主存換出到了外存,則調(diào)用do_swap_page()完成頁框分配。由malloc分配的內(nèi)存將會調(diào)用do_anonymous_page()分配物理頁框。3.4.do_anonymous_page()此時,缺頁異常處理程序終于要為當(dāng)前進程分配物理頁框了。它通過alloc_zeroed_user_highpage_movable()來完成這個過程。我們層層撥開這個函數(shù)的外衣,發(fā)現(xiàn)它最終調(diào)用了alloc_pages()。 static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *page_table, pmd_t *pmd, unsigned int flags) { ………… if (unlikely(anon_vma_prepare(vma))) goto oom; page = alloc_zeroed_user_highpage_movable(vma, address); if (!page) goto oom; ………… } 經(jīng)過這樣一個復(fù)雜的過程,用戶進程所訪問的線性地址終于對應(yīng)到了一塊物理內(nèi)存。參考:1.《深入理解LINUX內(nèi)核》2.《深入LINUX內(nèi)核架構(gòu)》
linux 內(nèi)核為進程分配物理頁的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux 內(nèi)核為進程分配物理頁,Linux內(nèi)核物理頁分配,提升進程運行效率,malloc()之后,內(nèi)核發(fā)生了什么?的信息別忘了在本站進行查找喔。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機、虛擬主機、域名注冊、VPS主機、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
當(dāng)前標(biāo)題:Linux內(nèi)核物理頁分配,提升進程運行效率(linux內(nèi)核為進程分配物理頁)
網(wǎng)站鏈接:http://www.dlmjj.cn/article/cdsssgs.html


咨詢
建站咨詢
