page->ptl용 slub 캐시
DEBUG_SPINLOCK과 DEBUG_LOCK_ALLOC이 활성화된 경우 x86_64 아키텍처에서 spinlock_t는 72 바이트가 사용되고 slab(slub) 캐시를 통해 할당되는 경우 근접한 사이즈인 kmalloc-96이 사용되고 24바이트의 사이즈가 낭비된다. 수 만개 이상의 페이지에 사용되는 page->ptl에 대해 너무 많은 메모리가 낭비된다 판단하여 spinlock_t 사이즈에 딱 맞는 캐시를 별도로 만들어 사용하게 되었다.
pgtable_init()
include/linux/mm.h
static inline void pgtable_init(void) { ptlock_cache_init(); pgtable_cache_init(); }
- ptlock_cache_init()
- page->ptl에 사용하는 spinlock_t 타입용 slab(slub) 캐시를 생성한다.
- pgtable_cache_init()
- x86, arm, arm64에서는 빈 함수이다.
ptlock_cache_init()
mm/memory.c
#if USE_SPLIT_PTE_PTLOCKS && ALLOC_SPLIT_PTLOCKS static struct kmem_cache *page_ptl_cachep; void __init ptlock_cache_init(void) { page_ptl_cachep = kmem_cache_create("page->ptl", sizeof(spinlock_t), 0, SLAB_PANIC, NULL); } #endif
페이지 테이블의 spinlock에 사용할 ptlock 캐시를 생성한다.
include/linux/mm_types.h
#define USE_SPLIT_PTE_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)
include/linux/mm_types.h
#define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8)
ptlock_alloc()
mm/memory.c
bool ptlock_alloc(struct page *page) { spinlock_t *ptl; ptl = kmem_cache_alloc(page_ptl_cachep, GFP_KERNEL); if (!ptl) return false; page->ptl = ptl; return true; }
spinlock에 사용할 slub object를 할당받아 page->ptl에 대입한다.
ptlock_free()
mm/memory.c
void ptlock_free(struct page *page) { kmem_cache_free(page_ptl_cachep, page->ptl); }
page->ptl에서 사용한 spinlock이 사용한 slub object를 해제한다.
CONFIG_SPLIT_PTLOCK_CPUS 커널 옵션
# Heavily threaded applications may benefit from splitting the mm-wide # page_table_lock, so that faults on different parts of the user address # space can be handled with less contention: split it at this NR_CPUS. # Default to 4 for wider testing, though 8 might be more appropriate. # ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock. # PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes. # DEBUG_SPINLOCK and DEBUG_LOCK_ALLOC spinlock_t also enlarge struct page. # config SPLIT_PTLOCK_CPUS int default "999999" if !MMU default "999999" if ARM && !CPU_CACHE_VIPT default "999999" if PARISC && !PA20 default "4"