拆分頁表鎖¶
最初,mm->page_table_lock 自旋鎖保護了 mm_struct 的所有頁表。但是,由於鎖上的高競爭,這種方法導致多執行緒應用程式的頁面錯誤可伸縮性較差。為了提高可伸縮性,引入了拆分頁表鎖。
使用拆分頁表鎖,我們有單獨的每表鎖來序列化對錶的訪問。目前,我們對 PTE 和 PMD 表使用拆分鎖。對更高級別表的訪問受 mm->page_table_lock 保護。
有一些輔助函式可以鎖定/解鎖表和其他訪問器函式
- pte_offset_map_lock()
對映 PTE 並獲取 PTE 表鎖,返回指向 PTE 的指標以及指向其 PTE 表鎖的指標,如果不存在 PTE 表則返回 NULL;
- pte_offset_map_ro_nolock()
對映 PTE,返回指向 PTE 的指標以及指向其 PTE 表鎖的指標(未獲取),如果不存在 PTE 表則返回 NULL;
- pte_offset_map_rw_nolock()
對映 PTE,返回指向 PTE 的指標以及指向其 PTE 表鎖的指標(未獲取)及其 pmd 條目的值,如果不存在 PTE 表則返回 NULL;
- pte_offset_map()
對映 PTE,返回指向 PTE 的指標,如果不存在 PTE 表則返回 NULL;
- pte_unmap()
取消對映 PTE 表;
- pte_unmap_unlock()
解鎖並取消對映 PTE 表;
- pte_alloc_map_lock()
如果需要,分配 PTE 表並獲取其鎖,返回指向 PTE 的指標以及指向其鎖的指標,如果分配失敗則返回 NULL;
- pmd_lock()
獲取 PMD 表鎖,返回指向獲取的鎖的指標;
- pmd_lockptr()
返回指向 PMD 表鎖的指標;
如果 CONFIG_SPLIT_PTLOCK_CPUS(通常為 4)小於或等於 NR_CPUS,則編譯時啟用 PTE 表的拆分頁表鎖。如果停用拆分鎖,則所有表都由 mm->page_table_lock 保護。
如果 PTE 表啟用了 PMD 表的拆分頁表鎖,並且該架構支援它(見下文)。
Hugetlb 和拆分頁表鎖¶
Hugetlb 可以支援多種頁面大小。我們僅對 PMD 級別使用拆分鎖,而不對 PUD 使用。
Hugetlb 特定輔助函式
- huge_pte_lock()
獲取 PMD_SIZE 頁面的 pmd 拆分鎖,否則獲取 mm->page_table_lock;
- huge_pte_lockptr()
返回指向表鎖的指標;
架構對拆分頁表鎖的支援¶
無需特別啟用 PTE 拆分頁表鎖:所有必需的操作都由 pagetable_pte_ctor() 和 pagetable_dtor() 完成,必須在 PTE 表分配/釋放時呼叫它們。
確保架構不使用 slab 分配器進行頁表分配:slab 對其頁面使用 page->slab_cache。此欄位與 page->ptl 共享儲存。
如果您有超過兩個頁表級別,PMD 拆分鎖才有意義。
啟用 PMD 拆分鎖需要在 PMD 表分配時呼叫 pagetable_pmd_ctor(),在釋放時呼叫 pagetable_dtor()。
分配通常發生在 pmd_alloc_one() 中,釋放在 pmd_free() 和 pmd_free_tlb() 中,但請確保您涵蓋所有 PMD 表分配/釋放路徑:即 X86_PAE 在 pgd_alloc() 上預分配少量 PMD。
完成所有設定後,您可以設定 CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK。
注意:pagetable_pte_ctor() 和 pagetable_pmd_ctor() 可能會失敗 - 必須正確處理。
page->ptl¶
page->ptl 用於訪問拆分頁表鎖,其中“page”是包含該表的頁面的 struct page。它與 page->private(以及聯合中的其他幾個欄位)共享儲存。
為了避免增加 struct page 的大小並獲得最佳效能,我們使用了一個技巧
如果 spinlock_t 適合 long 型別,我們使用 page->ptr 作為自旋鎖,這樣我們可以避免間接訪問並節省一個快取行。
如果 spinlock_t 的大小大於 long 的大小,我們使用 page->ptl 作為指向 spinlock_t 的指標並動態分配它。這允許使用啟用 DEBUG_SPINLOCK 或 DEBUG_LOCK_ALLOC 的拆分鎖,但會為間接訪問增加一個快取行;
spinlock_t 在 PTE 表的 pagetable_pte_ctor() 中分配,在 PMD 表的 pagetable_pmd_ctor() 中分配。
請不要直接訪問 page->ptl - 使用適當的輔助函式。