Linux 7.0 기준 · 마지막 갱신: 2026-06-26
Linux 7.0은 메모리 관리 서브시스템에서 여러 가지 주요 변경사항을 도입했습니다. 가장 두드러진 변경은 MGLRU(Multi-Generational LRU)의 완전한 통합, folio 기반 API의 확산, 새로운 시스템 콜(mseal, memfd_secret) 추가, SLUB 할당자의 Sheaf/Barn 아키텍처 재설계 등입니다. 이러한 변경들은 커널의 메모리 관리 효율성, 보안성, 확장성을 크게 향상시켰습니다.
이 문서에서는 Linux 6.x(6.1~6.15)에서 7.0으로의 주요 변경사항을 아키텍처, 서브시스템, 시스템 콜별로 분석합니다. 각 변경사항의 배경, 영향, 마이그레이션 고려사항을 다룹니다.
소스 파일 경로:
mm/memory.c ← 메모리 관리 핵심 (folio, MGLRU 통합)
mm/page_alloc.c ← 페이지 할당 (Per-CPU PCP 개선)
mm/vmscan.c ← 페이지 회수 (MGLRU 완전 통합)
mm/mmap.c ← 가상 메모리 (VMA 반복자 API)
mm/memblock.c ← 초기 메모리 할당 (KHO 지원)
mm/slub.c ← SLAB 할당자 (Sheaf/Barn 재설계)
mm/mseal.c ← 메모리 실링 (신규)
mm/memfd.c ← memfd_create / 파일 시일링
mm/secretmem.c ← memfd_secret / 비밀 메모리
mm/huge_memory.c ← THP (mTHP 다중 크기 지원)
mm/memory-tiers.c ← 메모리 티어링
mm/mmu_notifier.c ← MMU 알림
mm/execmem.c ← 실행 메모리 (ROX 캐시)
mm/mm_inline.h ← MGLRU 관리 유틸리티
include/linux/mm_types.h ← mm 타입 정의 (softleaf, mm_id)
include/linux/mmzone.h ← MGLRU 구조체 정의
include/linux/mm.h ← VMA 플래그 시스템
include/linux/swap.h ← swappiness 변경
include/linux/page-flags.h ← 페이지 플래그 확장
# 현재 커널 버전 확인
uname -r
# MGLRU 활성화 여부 확인
cat /sys/kernel/mm/lru_gen/enabled
# MGLRU 통계 확인
cat /sys/kernel/debug/lru_gen
# MGLRU 생성별 상세 정보
cat /sys/kernel/debug/lru_gen_full 2>/dev/null
# mseal 시스템 콜 존재 여부 확인
man 2 mseal 2>/dev/null && echo "mseal 지원" || echo "mseal 미지원"
# memfd_secret 지원 확인
man 2 memfd_secret 2>/dev/null && echo "secretmem 지원" || echo "secretmem 미지원"
# 커널 설정에서 MGLRU 확인
cat /boot/config-$(uname -r) | grep LRU_GEN
# 커널 설정에서 Per-VMA Lock 확인
cat /boot/config-$(uname -r) | grep PER_VMA_LOCK
# 커널 설정에서 KHO(Kexec Hand-Over) 확인
cat /boot/config-$(uname -r) | grep KEXEC_HANDOVER
# swappiness 현재 값 및 최대값 확인
cat /proc/sys/vm/swappiness
# mTHP 활성화 상태 확인
ls /sys/kernel/mm/transparent_hugepage/hugepages-*kB/ 2>/dev/null
# SLUB Sheaf/Barn 통계 확인
cat /sys/kernel/slab/kmalloc-*/sheaf_flush 2>/dev/null | head -5
# 메모리 티어 정보 확인
ls /sys/devices/system/memory_tier/ 2>/dev/null
# 커널 로그에서 MGLRU 관련 메시지 확인
dmesg | grep -i "lru_gen\|mglru"
# 커널 모듈 목록에서 mm 관련 모듈 확인
lsmod | grep -E "ksm|ksmthp|zswap|zram"
# KHO 상태 확인
dmesg | grep -i "kho\|kexec_handover"
| 기능 | Linux 6.x | Linux 7.0 | 변경 유형 |
|---|---|---|---|
| **MGLRU** | 실험적 (CONFIG_LRU_GEN) | 완전 통합, Bloom 필터 추가 | 확장 |
| **folio API** | 점진적 전환 중 | 대부분 folio 기반으로 전환 | 완성 |
| **mseal()** | 없음 | VMA 실링 시스템 콜 추가 | 신규 |
| **memfd_secret** | 기본 구현 | direct map 격리 강화 | 개선 |
| **mTHP** | PMD 크기만 지원 (2MB) | 다중 크기 지원 (order 기반) | 확장 |
| **SLUB** | per-CPU freelist | Sheaf/Barn 아키텍처 | 재설계 |
| **KHO** | 없음 | Kexec Hand-Over 지원 | 신규 |
| **Per-VMA Lock** | 실험적 | 기본 활성화 | 안정화 |
| **swappiness** | 최대 100 | 최대 200 (익명 전용 201) | 확장 |
| **VMA 플래그** | 제한적 | VM_SEALED, VM_SHADOW_STACK 등 | 확장 |
| **MMU Notifier** | 기본 구현 | interval tree 기반 프로토콜 | 개선 |
| **execmem** | 제한적 | ROX 캐시, maple tree 기반 | 확장 |
| **Memory Tiers** | 실험적 | 안정화, auto_movable | 개선 |
| **softleaf_t** | 없음 | 페이지 테이블 소프트웨어 리프 | 신규 |
| 시스템 콜 | Linux 6.x | Linux 7.0 | 비고 |
|---|---|---|---|
| `mseal(2)` | 없음 | VMA 실링 | Google 개발, 2023 |
| `memfd_secret(2)` | 기본 지원 | direct map 격리 강화 | 보안 강화 |
| `memfd_create(2)` | 기본 지원 | MEMFD_TAG_PINNED 추가 | 메모리 고정 |
mseal(2)는 VMA(Virtual Memory Area)의 메모리 메타데이터를 특정 시스템 호출로부터 보호하는 새로운 시스템 콜입니다.
차단되는 VMA 연산:
munmap(), mremap()에 의한 언매핑/크기 축소mremap()로 다른 VMA를 현재 위치로 이동/확장mmap(MAP_FIXED)로 VMA 수정mprotect / pkey_mprotectMADV_DONTNEED 등 파괴적 madv 동작실행 흐름:
mseal() → mmap_write_lock_killable()
→ range_contains_unmapped() // 1차 pass: hole 검증
→ mseal_apply() // 2차 pass: VM_SEALED 설정
→ vma_modify_flags()
Linux 7.0 특징:
VM_SEALED 플래그로 VMA에 봉인 적용memfd_secret(2)은 커널 메모리 매핑에서 완전히 격리된 메모리 영역을 생성합니다.
핵심 메커니즘:
secretmem_fault(): 페이지 폴트 시 set_direct_map_invalid_noflush()로 커널 direct 매핑에서 페이지 제거-EBUSY 반환)Linux 7.0 특징:
__folio_mark_uptodate() 사용folio_address() 기반 주소 추출VM_LOCKED | VM_DONTDUMP 자동 설정MGLRU는 기존 active/inactive 2-STATE LRU를 대체하는 다세대 LRU 시스템입니다. Linux 7.0에서는 완전히 통합되어 기본 활성화됩니다.
변경 사항:
CONFIG_LRU_GEN_ENABLED: 정적 키 기반 활성화/비활성화BLOOM_FILTER_SHIFT = 15lru_gen_look_around(): rmap walk 시 인접 PTE 스캔으로 spatial locality 활용MAX_NR_GENS = 4, MIN_NR_GENS = 2, MAX_NR_TIERS = 4SWAPPINESS_ANON_ONLY = MAX_SWAPPINESS + 1핵심 구조체 (include/linux/mmzone.h:490-518):
// include/linux/mmzone.h:490-518
struct lru_gen_folio {
/* aging은 가장 젊은 세대 번호를 증가시킨다 */
unsigned long max_seq;
/* eviction은 가장 오래된 세대 번호를 증가시킨다 */
unsigned long min_seq[ANON_AND_FILE];
/* 각 세대의 jiffies 기준 생성 시각 */
unsigned long timestamps[MAX_NR_GENS];
/* 회수 시 느슨하게 정렬되는 multi-gen LRU 목록 */
struct list_head folios[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
/* eventually consistent한 multi-gen LRU 크기 */
long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
/* refault의 지수 이동 평균 */
unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS];
/* evicted+protected의 지수 이동 평균 */
unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS];
/* LRU lock 아래에서만 수정 가능 */
unsigned long protected[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
/* LRU lock 없이 수정 가능 */
atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
/* multi-gen LRU 활성화 여부 */
bool enabled;
/* 이 lru_gen_folio가 속한 memcg 세대 */
u8 gen;
/* 이 lru_gen_folio가 속한 목록 세그먼트 */
u8 seg;
/* global reclaim용 per-node lru_gen_folio 목록 */
struct hlist_nulls_node list;
};
핵심 함수 (mm/vmscan.c):
lru_gen_add_mm() (line 2903): mm_struct를 MGLRU 리스트에 추가lru_gen_del_mm() (line 2930): mm_struct를 MGLRU 리스트에서 제거walk_mm() (line 3775): 페이지 테이블 walk하여 younger generation으로 승격inc_max_seq() (line 3956): 최고 생성 증가 (aging 핵심)try_to_inc_min_seq() (line 3899): oldest generation 증가 (eviction 최적화)evict_folios() (line 4686): isolated folios 실제로 해제get_swappiness() (line 2730): MGLRU에서 사용하는 swappiness 값 결정get_type_to_scan() (line 4644): eviction 시 anon/file 스캔 순서 결정swappiness 변경 (include/linux/swap.h:377-381):
#define MIN_SWAPPINESS 0
#define MAX_SWAPPINESS 200 // 기존 100에서 200으로 확장
#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1) // 익명 페이지 전용 회수 (proactive reclaim용)
SLUB 할당자가 기존 per-CPU freelist 대신 Sheaf/Barn 모델로 재설계되었습니다. Linux 7.0에서 mm/slub.c(9839줄)에 Sheaf/Barn 구조가 완전히 구현되었으며, VMA slab에도 적용되었습니다(mm/vma_init.c에서 sheaf_capacity = 32).
새로운 구조체 (mm/slub.c:396-425):
// mm/slub.c:396-402 — NUMA 노드별 공유 barn
struct node_barn {
spinlock_t lock;
struct list_head sheaves_full;
struct list_head sheaves_empty;
unsigned int nr_full;
unsigned int nr_empty;
};
#define MAX_FULL_SHEAVES 10 // 최대 full sheaf 수
#define MAX_EMPTY_SHEAVES 10 // 최대 empty sheaf 수
// mm/slub.c:404-418 — 객체 포인터 캐싱 sheaf
struct slab_sheaf {
union {
struct rcu_head rcu_head;
struct list_head barn_list;
/* prefilled sheafs에서만 사용 */
struct {
unsigned int capacity;
bool pfmemalloc;
};
};
struct kmem_cache *cache;
unsigned int size;
int node; /* rcu_sheaf에서만 사용 */
void *objects[];
};
// mm/slub.c:420-425 — per-CPU sheaves
struct slub_percpu_sheaves {
local_trylock_t lock;
struct slab_sheaf *main; /* 잠금 해제 시 절대 NULL이 아님 */
struct slab_sheaf *spare; /* 비어 있거나 가득 찰 수 있으며 NULL 가능 */
struct slab_sheaf *rcu_free; /* kfree_rcu() 배치용 */
};
잠금 순서 (mm/slub.c):
1. cpu_hotplug_lock
2. slab_mutex (Global Mutex)
3a. cpu_sheaves->lock (Local trylock)
3b. node->barn->lock (Spinlock)
3c. node->list_lock (Spinlock)
4. slab_lock(slab)
핵심 함수 (mm/slub.c):
barn_get_empty_sheaf() (line 3086): barn에서 빈 sheaf 획득barn_put_full_sheaf() (line 3130): barn에 full sheaf 배치refill_sheaf() (line 2803): sheaf로 objects refillsheaf_flush_main() (line 2890): 메인 sheaf flushalloc_from_pcs() (line 4671): per-CPU sheaves에서 할당 (빠른 경로)free_to_pcs() (line 5763): per-CPU sheaves로 해제 (빠른 경로)kmem_cache_prefill_sheaf() (line 4960): sheaf 사전 채우기kmem_cache_alloc_from_sheaf() (line 5155): sheaf에서 할당__kfree_rcu_sheaf() (line 5862): RCU 기반 sheaf 해제3계층 구조:
Per-CPU Sheaves (main + spare)
↓ 실패 시
Per-NUMA-node Barn (full/empty sheaf 교환)
↓ 실패 시
Slab Pages (최종 fallback)
memblock에 Kexec Hand-Over를 위한 새로운 메커니즘이 추가되었습니다. kernel/liveupdate/kexec_handover.c에 구현되어 있으며, kexec 부팅 시 메모리를 보존하고 복원하는 기능을 제공합니다.
변경 사항:
CONFIG_KEXEC_HANDOVER 지원CONFIG_MEMBLOCK_KHO_SCRATCH: KHO 스크래치 메모리kho_scratch_only 플래그 (mm/memblock.c:116-121)KHO_PAGE_MAGIC = 0x4b484f50U (ASCII 'KHOP')핵심 구조체 (kernel/liveupdate/kexec_handover.c:43-120):
// kernel/liveupdate/kexec_handover.c:43-51
union kho_page_info {
unsigned long page_private;
struct {
unsigned int order;
unsigned int magic;
};
};
static_assert(sizeof(union kho_page_info) == sizeof(((struct page *)0)->private));
// kernel/liveupdate/kexec_handover.c:84-112
struct kho_mem_phys_bits {
DECLARE_BITMAP(preserve, PRESERVE_BITS);
};
struct kho_mem_phys {
struct xarray phys_bits;
};
struct kho_mem_track {
struct xarray orders;
};
struct kho_out {
void *fdt;
bool finalized;
struct mutex lock; /* KHO FDT 최종화 보호 */
struct kho_mem_track track;
struct kho_debugfs dbg;
};
공개 API (include/linux/kexec_handover.h:19-42):
bool kho_is_enabled(void); // KHO 활성화 여부
bool is_kho_boot(void); // KHO를 통한 kexec 부팅 여부
int kho_preserve_folio(struct folio *folio); // folio 보존 등록
int kho_preserve_pages(phys_addr_t base, unsigned int order); // 연속 페이지 보존
int kho_preserve_vmalloc(void *addr, unsigned long size); // vmalloc 영역 보존
void kho_restore_folio(struct folio *folio); // folio 복원
void kho_restore_pages(phys_addr_t base, unsigned int order); // 페이지 복원
int kho_add_subtree(const char *name, void *fdt, int size); // FDT 하위 트리 추가
int kho_retrieve_subtree(const char *name, void *fdt, int size); // FDT 하위 트리 검색
void kho_memory_init(void); // 메모리 초기화
void kho_populate(void); // KHO 데이터 채우기
memblock KHO 통합 (mm/memblock.c:2445-2632):
memblock_set_kho_scratch_only(): scratch 전용 모드 설정memblock_mark_kho_scratch(): 메모리 region에 KHO_SCRATCH 플래그 설정reserved_mem_preserve(): 예약된 메모리를 KHO로 보존prepare_kho_fdt(): memblock KHO FDT 생성reserve_mem_kho_revive(): KHO 부팅 시 이전 커널의 예약된 메모리 복원Per-VMA Lock이 실험적 기능에서 기본 활성화로 전환되었습니다.
변경 사항:
CONFIG_PER_VMA_LOCK 기본 활성화FAULT_FLAG_VMA_LOCK 플래그 처리THP(Two-Megabyte Huge Page)가 아닌 다양한 크기의 THP를 지원합니다. mm/huge_memory.c(4978줄)와 include/linux/huge_mm.h에 구현되어 있습니다.
변경 사항:
huge_anon_orders_always, huge_anon_orders_madvise, huge_anon_orders_inherit 변수 추가 (huge_memory.c:80-83)__thp_vma_allowable_orders(): VMA별 허용 order 계산 (huge_memory.c:103-211)THP_ORDERS_ALL_ANON 마스크: order 2부터 PMD_ORDER까지 (order 0, 1 제외)thp_anon= 부트 파라미터로 order별 정책 설정 (huge_memory.c:991-1074)핵심 매크로 (include/linux/huge_mm.h:74-95):
// include/linux/huge_mm.h:74-95
// Anonymous THP: order 2부터 PMD_ORDER까지 (order 0, 1 제외)
#define THP_ORDERS_ALL_ANON ((BIT(PMD_ORDER + 1) - 1) & ~(BIT(0) | BIT(1)))
// Special huge (DAX/PFNMAP): PMD + PUD order만 지원
#define THP_ORDERS_ALL_SPECIAL (BIT(PMD_ORDER) | BIT(PUD_ORDER))
// File THP: order 1부터 MAX_PAGECACHE_ORDER까지
#define THP_ORDERS_ALL_FILE_DEFAULT ((BIT(MAX_PAGECACHE_ORDER + 1) - 1) & ~BIT(0))
분기 로직:
1. vma_is_anonymous() → THP_ORDERS_ALL_ANON
2. vma_is_special_huge() → THP_ORDERS_ALL_SPECIAL
3. 그 외 → THP_ORDERS_ALL_FILE_DEFAULT
4. orders &= supported_orders — 교집합 계산
5. thp_disabled_by_hw() 또는 vma_thp_disabled() → 0 반환
mTHP 통계 (huge_memory.c:598-698):
DEFINE_PER_CPU(struct mthp_stat, mthp_stats) — per-CPU mTHP 통계MTHP_STAT_ANON_FAULT_ALLOC, MTHP_STAT_ANON_FAULT_FALLBACK 등 17개 항목swappiness 최대값이 기존 100에서 200으로 증가했습니다. 이는 MGLRU와의 통합으로 anon/file 비율 조절의 정밀도를 높이기 위함입니다.
새로운 상수 (include/linux/swap.h:377-381):
// include/linux/swap.h:377-381
#define MIN_SWAPPINESS 0
#define MAX_SWAPPINESS 200 // 기존 100에서 200으로 확장
#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1) // 익명 페이지 전용 회수 (proactive reclaim용)
MGLRU에서의 swappiness 사용 (mm/vmscan.c):
get_swappiness() (line 2730): MGLRU에서 사용하는 swappiness 값 결정swappiness <= MIN_SWAPPINESS + 1 → file 우선 스캔swappiness >= MAX_SWAPPINESS → anon 우선 스캔SWAPPINESS_ANON_ONLY → proactive reclaim에서 anon만 스캔전역 변수:
vm_swappiness (vmscan.c:201): 기본값 60, 범위 0~200새로운 VMA 플래그가 추가되었습니다.
새로운 플래그:
VM_SEALED: 메모리 실링 지원VM_MAYBE_GUARD: 가드 영역 마커VM_ALLOW_ANY_UNCACHED: 비캐시 메모리 허용VM_SHADOW_STACK: x86/RISC-V/ARM64용 섀도우 스택새로운 페이지 플래그가 추가되었습니다.
새로운 플래그:
PG_movable_ops_isolated: 마이그레이션 격리된 페이지PG_movable_ops: movable_ops 타입 페이지PG_anon_exclusive: 익명 전용 플래그 (별칭)PG_mappedtodisk: 디스크 매핑 플래그 (별칭)MMU Notifier가 interval tree 기반 프로토콜로 개선되었습니다.
변경 사항:
invalidate_seq 카운터로 2-STATE invalidate 프로토콜 구현invalidate_seq & 1 == trueinvalidate_seq & 1 == falsedeferred_list로 지연된 추가/제거 처리실행 메모리 할당이 ROX 캐시와 maple tree 기반으로 확장되었습니다.
변경 사항:
execmem_cache: maple tree 기반 할당 관리execmem_cache_free_slow(): 지연 해제(delayed_work)로 비동기 정리__free() cleanup 속성 활용Linux 7.0에서 새로운 softleaf_t 타입이 도입되었습니다.
정의:
// include/linux/mm_types.h:289-312
/**
* typedef softleaf_t - 페이지 테이블 소프트웨어 리프 엔트리를 설명하는
* 아키텍처 독립형 타입입니다.
*
* 페이지 테이블 리프 엔트리는 하위 페이지 테이블을 가리키지 않고,
* 데이터 페이지를 가리키거나, 비어 있는(none) 엔트리이거나, non-present
* 엔트리를 담는 항목입니다.
*
* 다른 페이지 테이블이나 데이터 페이지를 가리키는 경우에는 해당
* 페이지 테이블 엔트리가 하드웨어에 직접 의미를 갖습니다.
* 즉, 하드웨어가 이 엔트리를 어떻게 해석할지 알려줍니다.
*
* 그 외에는 소프트웨어가 정의한 리프 페이지 테이블 엔트리이며,
* 이 타입이 그 경우를 설명합니다. 가능한 소프트웨어 리프 종류는
* leafops.h의 @softleaf_type을 참고합니다.
*
* softleaf_t 엔트리는 하드웨어 페이지 테이블 엔트리에서 추상화되므로
* 아키텍처에 종속되지 않습니다.
*
* NOTE: 이 용도에 쓰이던 swp_entry_t 타입에서 전환 중이므로,
* 지금은 단순히 별칭으로 두었습니다. 전환이 끝나면 제거됩니다.
*/
typedef swp_entry_t softleaf_t;
용도:
pmd_huge_pte, pt_share_count 필드와 연동# 현재 커널 버전 확인
uname -r
# MGLRU 활성화 여부 확인
cat /sys/kernel/mm/lru_gen/enabled
# MGLRU 통계 확인
cat /sys/kernel/debug/lru_gen
# MGLRU 생성별 상세 정보
cat /sys/kernel/debug/lru_gen_full 2>/dev/null
# mseal 시스템 콜 존재 여부 확인
man 2 mseal 2>/dev/null && echo "mseal 지원" || echo "mseal 미지원"
# memfd_secret 지원 확인
man 2 memfd_secret 2>/dev/null && echo "secretmem 지원" || echo "secretmem 미지원"
# 커널 설정에서 MGLRU 확인
cat /boot/config-$(uname -r) | grep LRU_GEN
# 커널 설정에서 Per-VMA Lock 확인
cat /boot/config-$(uname -r) | grep PER_VMA_LOCK
# 커널 설정에서 KHO(Kexec Hand-Over) 확인
cat /boot/config-$(uname -r) | grep KEXEC_HANDOVER
# swappiness 현재 값 및 최대값 확인
cat /proc/sys/vm/swappiness
# mTHP 활성화 상태 확인
ls /sys/kernel/mm/transparent_hugepage/hugepages-*kB/ 2>/dev/null
# SLUB Sheaf/Barn 통계 확인
cat /sys/kernel/slab/kmalloc-*/sheaf_flush 2>/dev/null | head -5
# 메모리 티어 정보 확인
ls /sys/devices/system/memory_tier/ 2>/dev/null
# 커널 로그에서 MGLRU 관련 메시지 확인
dmesg | grep -i "lru_gen\|mglru"
# 커널 모듈 목록에서 mm 관련 모듈 확인
lsmod | grep -E "ksm|ksmthp|zswap|zram"
# KHO 상태 확인
dmesg | grep -i "kho\|kexec_handover"