Documentation/mm/split_page_table_lock.rst

Source file repositories/reference/linux-study-clean/Documentation/mm/split_page_table_lock.rst

File Facts

System
Linux kernel
Corpus path
Documentation/mm/split_page_table_lock.rst
Extension
.rst
Size
4114 bytes
Lines
108
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

=====================
Split page table lock
=====================

Originally, mm->page_table_lock spinlock protected all page tables of the
mm_struct. But this approach leads to poor page fault scalability of
multi-threaded applications due to high contention on the lock. To improve
scalability, split page table lock was introduced.

With split page table lock we have separate per-table lock to serialize
access to the table. At the moment we use split lock for PTE and PMD
tables. Access to higher level tables protected by mm->page_table_lock.

There are helpers to lock/unlock a table and other accessor functions:

 - pte_offset_map_lock()
	maps PTE and takes PTE table lock, returns pointer to PTE with
	pointer to its PTE table lock, or returns NULL if no PTE table;
 - pte_offset_map_ro_nolock()
	maps PTE, returns pointer to PTE with pointer to its PTE table
	lock (not taken), or returns NULL if no PTE table;
 - pte_offset_map_rw_nolock()
	maps PTE, returns pointer to PTE with pointer to its PTE table
	lock (not taken) and the value of its pmd entry, or returns NULL
	if no PTE table;
 - pte_offset_map()
	maps PTE, returns pointer to PTE, or returns NULL if no PTE table;
 - pte_unmap()
	unmaps PTE table;
 - pte_unmap_unlock()
	unlocks and unmaps PTE table;
 - pte_alloc_map_lock()
	allocates PTE table if needed and takes its lock, returns pointer to
	PTE with pointer to its lock, or returns NULL if allocation failed;
 - pmd_lock()
	takes PMD table lock, returns pointer to taken lock;
 - pmd_lockptr()
	returns pointer to PMD table lock;

Split page table lock for PTE tables is enabled compile-time if
CONFIG_SPLIT_PTLOCK_CPUS (usually 4) is less or equal to NR_CPUS.
If split lock is disabled, all tables are guarded by mm->page_table_lock.

Split page table lock for PMD tables is enabled, if it's enabled for PTE
tables and the architecture supports it (see below).

Hugetlb and split page table lock
=================================

Hugetlb can support several page sizes. We use split lock only for PMD
level, but not for PUD.

Hugetlb-specific helpers:

 - huge_pte_lock()
	takes pmd split lock for PMD_SIZE page, mm->page_table_lock
	otherwise;
 - huge_pte_lockptr()
	returns pointer to table lock;

Support of split page table lock by an architecture
===================================================

There's no need in special enabling of PTE split page table lock: everything
required is done by pagetable_pte_ctor() and pagetable_dtor(), which
must be called on PTE table allocation / freeing.

Make sure the architecture doesn't use slab allocator for page table
allocation: slab uses page->slab_cache for its pages.
This field shares storage with page->ptl.

Annotation

Implementation Notes