- Linux की process memory संरचना को वास्तविक कामकाज के स्तर पर समझाया गया है, और virtual address space तथा physical memory के बीच संबंध को चरण-दर-चरण बताया गया है
- page table, VMA, mmap, page fault, CoW जैसे मुख्य mechanisms के आधार पर यह विस्तार से बताया गया है कि process memory को कैसे own और access करती है
/proc file system के जरिए प्रत्येक process की memory स्थिति को देखने के तरीके, और pagemap, kpageflags जैसे उन्नत diagnostic tools की भूमिका का परिचय दिया गया है
- Transparent Huge Pages (THP), userfaultfd, PAGEMAP_SCAN जैसी आधुनिक kernel features के माध्यम से performance optimization और user-space dirty tracking तकनीकों पर चर्चा की गई है
- Meltdown mitigation PTI, TLB flush, W^X policy जैसी security और performance से जुड़ी kernel design principles को भी समझाया गया है, ताकि Linux memory management की समग्र समझ मिल सके
process memory की बुनियादी संरचना
- जब कोई program चलता है, तो ऐसा लगता है जैसे उसके पास एक बहुत बड़ी continuous memory हो, लेकिन वास्तव में Linux kernel इसे page units में dynamically बनाता है
- CPU page table को देखकर virtual address को physical frame में बदलता है
- यदि mapping नहीं हो, तो page fault होता है, और kernel नया page allocate करता है या error लौटाता है
- यदि physical RAM कम पड़ जाए, तो kernel unused pages को disk पर भेजता है या file pages हटाकर जगह बनाता है
/proc एक virtual file system है जिसे kernel memory में बनाता है, और यह process तथा kernel state को files के रूप में दिखाता है
address space और VMA
- हर process के पास एक address space object होता है, जिसके अंदर कई VMA (Virtual Memory Area) होते हैं
- VMA एक continuous address range है, जिसमें समान permissions (R/W/X) और समान backend (anonymous memory या file) होता है
- page table वह संरचना है जिसे hardware refer करता है, और इसमें virtual pages और physical pages के बीच mapping information (PTE) stored रहती है
- address space में बदलाव तीन system calls से किया जाता है
mmap: नया region बनाना
mprotect: permissions बदलना
munmap: mapping हटाना
- page का basic unit 4KiB होता है, और कुछ systems 2MiB·1GiB के बड़े pages भी support करते हैं
/proc/self/maps से memory layout देखना
cat /proc/self/maps command से process की memory map देखी जा सकती है
- इसमें executable की code·data·bss, heap, anonymous mappings, shared libraries, stack आदि दिखते हैं
[vdso] और [vvar] regions kernel द्वारा map किए गए तेज़ system calls के लिए code और data हैं
mmap कैसे काम करता है
mmap वास्तविक memory allocation नहीं करता, बल्कि address space के लिए एक वादा दर्ज करता है
- page पहली access के समय allocate होते हैं
- file mapping के समय
offset page-aligned होना चाहिए, और file end से आगे access करने पर SIGBUS होता है
MAP_SHARED सीधे file में reflect होता है, जबकि MAP_PRIVATE copy-on-write (CoW) के जरिए अलग page बनाता है
MAP_FIXED_NOREPLACE यह सुनिश्चित करता है कि अगर दिए गए address पर पहले से mapping हो तो call fail हो जाए, जिससे सुरक्षा बढ़ती है
पहली access और page fault
- नई mapping पर पहली access के समय अगर CPU को page table entry न मिले, तो page fault होता है
- kernel address validity, access permissions, और existence की जाँच करता है
- anonymous mapping हो तो 0 से भरा नया page allocate होता है, file mapping हो तो page cache से पढ़ा जाता है
- minor fault तब होता है जब data पहले से RAM में हो, और major fault तब जब disk I/O की ज़रूरत हो
- stack को guard page से सुरक्षित रखा जाता है, इसलिए बहुत नीचे की ओर access करने पर
SIGSEGV हो सकता है
fork() और MAP_PRIVATE का Copy-on-Write
fork के समय parent और child एक ही physical pages share करते हैं, और दोनों को read-only mark किया जाता है
- write होने पर ही नया page copy किया जाता है ताकि दोनों अलग बने रहें
MAP_PRIVATE file mapping भी इसी सिद्धांत पर काम करती है
- संबंधित options
vfork: parent address space share करना
clone(CLONE_VM): thread बनाना
MADV_DONTFORK, MADV_WIPEONFORK: child process में mapping को exclude करना या 0 से initialize करना
permissions बदलना और TLB invalidation
mprotect से page permissions बदलने पर kernel VMA को split करता है और page table modify करता है, फिर TLB invalidate करता है
- W^X policy के अनुसार कोई page एक ही समय पर writable और executable नहीं हो सकता
- TLB (Translation Lookaside Buffer) हाल की address translations का cache है, और invalidation होने पर थोड़ी देरी हो सकती है
/proc के जरिए विस्तार से निरीक्षण
/proc/<pid>/maps, smaps, smaps_rollup से region-wise permissions, RSS, HugePage usage देखी जा सकती है
/proc/<pid>/pagemap page-level state (present, swapped, PFN आदि) देता है, लेकिन PFN सामान्य users के लिए छिपा रहता है
/proc/kpagecount, /proc/kpageflags हर PFN के लिए mapping count और page properties (anonymous, file, dirty आदि) दिखाते हैं
mincore, SEEK_DATA/SEEK_HOLE से sparse files के data/hole regions की पहचान की जा सकती है
PAGEMAP_SCAN और userfaultfd को जोड़कर user-space dirty tracking लागू की जा सकती है
Transparent Huge Pages (THP) और mTHP
- THP बार-बार access होने वाली memory को अपने-आप बड़े pages (जैसे 2MiB) में समेटता है, जिससे TLB efficiency बेहतर होती है
khugepaged thread पास-पास के pages को merge करता है
- mTHP 16KiB·64KiB आदि आकारों के variable large pages (folio) को support करता है
/proc/self/smaps में AnonHugePages, FilePmdMapped से उपयोग की जाँच की जा सकती है
/sys/kernel/mm/transparent_hugepage/ में system-wide settings manage की जाती हैं
MADV_HUGEPAGE, MADV_NOHUGEPAGE से region-level control संभव है
user-space dirty tracking
userfaultfd और PAGEMAP_SCAN का उपयोग करके सिर्फ बदले हुए pages को copy किया जा सकता है
- kernel एक atomic operation में scan और write-protect दोनों करता है
- snapshot, live migration जैसी स्थितियों में यह उपयोगी है
TLB flush mechanism
- x86 में TLB invalidation के दो तरीके हैं
INVLPG: एक single page को invalidate करना
- page table root को reload करके full flush करना
PCID और INVPCID process-wise TLB tag management के जरिए अनावश्यक flush कम करते हैं
tlb_single_page_flush_ceiling वह threshold है जिसके आधार पर kernel page-wise या full flush चुनता है
Meltdown mitigation: Page Table Isolation (PTI)
- Meltdown एक ऐसी vulnerability है जिसमें speculative execution के दौरान kernel data cache के माध्यम से leak हो सकता है
- Linux PTI (Page Table Isolation) के जरिए user और kernel address spaces को अलग करता है
- entry के समय
CR3 switch करके kernel-only page table का उपयोग किया जाता है
PCID का उपयोग कर TLB flush को न्यूनतम रखा जाता है
- यह default रूप से enabled रहता है, और
nopti से disable किया जा सकता है
kernel की सुरक्षित mapping change प्रक्रिया
- mapping बदलते समय क्रम यह होता है
- cache rules लागू करना
- page table modify करना
- TLB invalidate करना
- kernel internal mappings (
vmap, vmalloc) में भी I/O से पहले और बाद में cache·TLB synchronization किया जाता है
- कुछ architectures में code copy करने के बाद instruction cache flush की आवश्यकता होती है
x86 का stack और call structure
- 64-bit mode में RIP, RSP, RBP registers उपयोग होते हैं, और stack नीचे की ओर बढ़ता है
- System V AMD64 ABI के अनुसार arguments RDI, RSI, RDX, RCX, R8, R9 में जाते हैं, और return value RAX में आती है
- user mode ring 3 में चलता है, kernel ring 0 में, और system calls तथा interrupts gates के जरिए switch होते हैं
error situations और diagnosis
mmap → EINVAL: file offset alignment error
mmap → ENOMEM: virtual space की कमी या overcommit limit
- file mapping access पर
SIGBUS: EOF के पार access
mprotect(PROT_EXEC) → EACCES: noexec mount या W^X policy
fork() के बाद RSS बढ़ना: CoW के कारण page copies
MAP_FIXED से existing mapping overwrite होना → MAP_FIXED_NOREPLACE recommended
practical checklist
- तुरंत memory reserve करनी हो:
mmap + PROT_READ|PROT_WRITE + MAP_PRIVATE|MAP_ANONYMOUS
- code generation के समय: W^X बनाए रखें,
mprotect(PROT_READ|PROT_EXEC)
- file mapping के समय:
offset को page-align करें, EOF के आगे access न करें
- page faults अधिक हों:
MADV_WILLNEED या pre-touch का उपयोग करें
- memory usage analysis:
/proc/<pid>/smaps_rollup → /proc/<pid>/maps
- बड़े process पर fork: CoW को ध्यान में रखें, child में
exec उपयोग करें
- latency-sensitive environment: THP/mTHP,
mlock, और TLB behavior observe करें
अभी कोई टिप्पणी नहीं है.