ANON VS PAGE CACHE WORK SHEET
AXIOM: The struct page Anonymous Union (Listing 2-3)
- DEFINITION:
struct page is packed. Fields reuse memory.
- AXIOM:
mapping field (Offset 24) is OVERLOADED.
- Pointer to
struct address_space is ALWAYS aligned to 4 bytes (ends in 00).
- Kernel uses bottom bits for FLAGS.
- Bit 0 = 1 →
PAGE_MAPPING_ANON (Anonymous Page).
- Bit 0 = 0 → File Page (Page Cache).
- Bit 1 = 1 →
PAGE_MAPPING_MOVABLE (KSM/Movable).
EXERCISE 1: The Anonymous Mapping
- RUN:
./anon_user. Copy target_pid and anon_addr.
- RUN:
sudo insmod anon_file_hw.ko target_pid=... anon_addr=....
- READ dmesg. Only look at “ANONYMOUS” section.
DERIVATION 1: The Mapping Pointer
- READ:
raw mapping = 0x______.
- CALCULATE:
bit_0 = raw_mapping & 1 = ____.
- CHECK: Is
bit_0 == 1? ✓/✗ (Expected: 1 for Anon).
- DERIVE:
real_mapping = raw_mapping & ~3 (Clear bottom 2 bits).
- 0x______ & ~3 = 0x______.
- IMPORTANT: If you use
raw_mapping as a pointer, CPU crashes (Odd Address).
real_mapping points to anon_vma (Kernel Structure).
DERIVATION 2: The Index
- READ:
index = ____.
- QUESTION: For Anonymous page, what is index?
- It’s the “Linear Page Index” within the VMA.
- Formula:
(addr - vma->vm_start) >> PAGE_SHIFT + vma->vm_pgoff.
- Try to verify:
index should match offset from start of mmap.
EXERCISE 2: The File Mapping
- LOOK at “FILE-BACKED” section in dmesg.
- READ:
raw mapping = 0x______.
- CHECK: Is
bit_0 == 0? ✓/✗ (Expected: 0 for File).
- DERIVE:
real_mapping = raw_mapping. No masking needed!
- Points to
inode->i_mapping.
- READ:
index = ____.
- VERIFY: We mapped file at offset 0. Index should be 0.
EXERCISE 3: The Union (LRU vs Mlock)
- LOOK at
lru.next / lru.prev.
- LOOK at
mlock_count.
- DISCOVERY: If page is on LRU list,
lru pointers are valid kernel addresses (0xffff…).
mlock_count will look like garbage integer (huge number).
- CHALLENGE: If
anon_user successfully MLOCKED the page…
- Does it leave LRU? (Unevictable LRU).
- Modern approach: Unevictable IS an LRU list.
mlock_count might be valid inside a different struct (page->mlock_count)?
- Listing 2-3 says:
union { struct list_head lru; ... mlock_count; }.
- This implies MUTUALLY EXCLUSIVE.
- If
mlock_count is used, lru is NOT used?
- WAIT. Check kernel source
include/linux/mm_types.h matching 6.14.
- CRITICAL: Sometimes documentation lags behind code.
- TASK: Look at the values. If
lru.next looks like a pointer, it’s LRU.
FAILURE PREDICTIONS (Don’t fall for these!)
- F1: Using
page->mapping directly in C code for Anon pages.
- Result:
Oops: general protection fault. Address ends in 1.
- F2: Assuming
file_mapping has bits set.
- Result: Usually clean pointer (ends in 0).
- F3: Mistaking
index for File Descriptor.
- Result: Index is logical page offset, not FD.
YOUR MISSION
- Fill
TODO blocks in anon_file_hw.c.
- Correctly mask the mapping pointer.
- Recompile and verify
bit_0 matches expectation.