[커널 18차] 54주차

2022.06.04 22:16

kkr 조회 수:81

git : https://github.com/iamroot18/5.10/commit/24e45c907359ac476d61210dc26d32493bd9b030

 

diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
index e3e28f7daf62..b244001b9c4e 100644
--- a/arch/arm64/include/asm/mman.h
+++ b/arch/arm64/include/asm/mman.h
@@ -35,6 +35,10 @@ static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
 }
 #define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vm_flags에 더 추가할 arch prot flags가 있으면 추가한다.
+ */
 static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
 {
     pteval_t prot = 0;
@@ -74,6 +78,10 @@ static inline bool arch_validate_prot(unsigned long prot,
 }
 #define arch_validate_prot(prot, addr) arch_validate_prot(prot, addr)
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vm_flags validate 검사.
+ */
 static inline bool arch_validate_flags(unsigned long vm_flags)
 {
     if (!system_supports_mte())
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 70e69efd6c6c..1fc7fb41d3a0 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -257,6 +257,10 @@
 /*
  * Level 3 descriptor (PTE).
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - hardware mapping이 되있는지 확인.
+ */
 #define PTE_VALID        (_AT(pteval_t, 1) << 0)
 #define PTE_TYPE_MASK        (_AT(pteval_t, 3) << 0)
 #define PTE_TYPE_PAGE        (_AT(pteval_t, 3) << 0)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 8dc627583876..d1cf47554d58 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -15,8 +15,18 @@
  */
 #define PTE_WRITE        (PTE_DBM)         /* same as DBM (51) */
 #define PTE_DIRTY        (_AT(pteval_t, 1) << 55)
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - TODO
+ *   특수하게 관리한다. (zero page등)
+ */
 #define PTE_SPECIAL        (_AT(pteval_t, 1) << 56)
 #define PTE_DEVMAP        (_AT(pteval_t, 1) << 57)
+/*
+ * IAMROOT, 2022.06.04:
+ * - PTE_PROT_NONE : numa fault인지 여부.
+ */
 #define PTE_PROT_NONE        (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
 
 /*
@@ -84,6 +94,12 @@ extern bool arm64_use_ng_mappings;
         __val;                            \
      })
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - PTE_PXN : kernel 공간에서 실행 불가
+ *   PTE_UXN : user 공간에서 실행 불가.
+ *   PTE_NG  : not global. 다른 cpu core에서도 mapping을 사용안하겠다는것.
+ */
 #define PAGE_NONE        __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
 /* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */
 #define PAGE_SHARED        __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 40ff1acb6d27..841f99e0849a 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -81,6 +81,10 @@
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - zero page.
+ */
 extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 #define ZERO_PAGE(vaddr)    phys_to_page(__pa_symbol(empty_zero_page))
 
@@ -123,6 +127,10 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 /*
  * The following only work if pte_present(). Undefined behaviour otherwise.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - hardware mapping이나 numa fault가 되있으면 mapping이 됬다는것을 의미한다.
+ */
 #define pte_present(pte)    (!!(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)))
 #define pte_young(pte)        (!!(pte_val(pte) & PTE_AF))
 #define pte_special(pte)    (!!(pte_val(pte) & PTE_SPECIAL))
@@ -215,6 +223,10 @@ static inline pmd_t set_pmd_bit(pmd_t pmd, pgprot_t prot)
     return pmd;
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @pte에 PTE_WRITE를 set한다.
+ */
 static inline pte_t pte_mkwrite(pte_t pte)
 {
     pte = set_pte_bit(pte, __pgprot(PTE_WRITE));
@@ -230,6 +242,10 @@ static inline pte_t pte_mkclean(pte_t pte)
     return pte;
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @pte에 PTE_DIRTY bit를 set한다.
+ */
 static inline pte_t pte_mkdirty(pte_t pte)
 {
     pte = set_pte_bit(pte, __pgprot(PTE_DIRTY));
@@ -259,6 +275,11 @@ static inline pte_t pte_mkold(pte_t pte)
     return clear_pte_bit(pte, __pgprot(PTE_AF));
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - ARM8.0까지는 software적으로 af flag를 설정해줘야되고, 8.1은 hardware
+ *   적으로 해준다.
+ */
 static inline pte_t pte_mkyoung(pte_t pte)
 {
     return set_pte_bit(pte, __pgprot(PTE_AF));
@@ -474,6 +495,10 @@ static inline pgprot_t mk_pmd_sect_prot(pgprot_t prot)
 /*
  * See the comment in include/linux/pgtable.h
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - numa balancing으로 인해서 fault가 발생한 상태.
+ */
 static inline int pte_protnone(pte_t pte)
 {
     return (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) == PTE_PROT_NONE;
@@ -1190,11 +1215,24 @@ static inline bool arch_wants_old_prefaulted_pte(void)
 }
 #define arch_wants_old_prefaulted_pte    arch_wants_old_prefaulted_pte
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - system등에 따라 @prot 변경 여부를 반영한다.
+ */
 static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
 {
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - Enhanced Privileged Access Never 
+ */
     if (cpus_have_const_cap(ARM64_HAS_EPAN))
         return prot;
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - PAGE_EXECONLY -> PAGE_READONLY_EXEC로 변경.
+ */
     if (pgprot_val(prot) != pgprot_val(PAGE_EXECONLY))
         return prot;
 
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 31c4bb332c05..1dbd51918b25 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -54,6 +54,10 @@
  *
  * read, write 권한이 있는 vma라는것을 알수있다.
  * malloc을 호출하면 항상 위와같은 prot, flag를 사용한다.
+ *
+ * - 최종적으로 vma가 새로 생길시 다음과 같은 flag로 완성된다.
+ * VmFlags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE |
+ * VM_MAYEXEC | VM_ACCOUNT | VM_SOFTDIRTY
  */
 SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
         unsigned long, prot, unsigned long, flags,
diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
index c1eb47753650..d67c4b9403c2 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -51,6 +51,10 @@ void copy_highpage(struct page *to, struct page *from)
 }
 EXPORT_SYMBOL(copy_highpage);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - from을 to로 복사후 PG_dcache_clean bit clear
+ */
 void copy_user_highpage(struct page *to, struct page *from,
             unsigned long vaddr, struct vm_area_struct *vma)
 {
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index f095016edcbf..d1c152666a43 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -194,6 +194,11 @@ static void show_pte(unsigned long addr)
  *
  * Returns whether or not the PTE actually changed.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - af flag를 set한다. ARM8.1의 경우 자동 기록이 되므로 pte_same을통해서
+ *   skip된다.
+ */
 int ptep_set_access_flags(struct vm_area_struct *vma,
               unsigned long address, pte_t *ptep,
               pte_t entry, int dirty)
@@ -201,6 +206,10 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
     pteval_t old_pteval, pteval;
     pte_t pte = READ_ONCE(*ptep);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - hardware에서 af를 기록했을수도있다. 같으면 skip.
+ */
     if (pte_same(pte, entry))
         return 0;
 
@@ -220,6 +229,11 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
         pteval ^= PTE_RDONLY;
         pteval |= pte_val(entry);
         pteval ^= PTE_RDONLY;
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - atomic 기록.
+ */
         pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval);
     } while (pteval != old_pteval);
 
@@ -919,6 +933,11 @@ NOKPROBE_SYMBOL(do_debug_exception);
 /*
  * Used during anonymous page fault handling.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - anon page의 write fault으로 인해 0으로 초기화된 사용자 메모리를
+ *   할당한다.
+ */
 struct page *alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
                         unsigned long vaddr)
 {
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index 2aaf950b906c..fa4d8275a97d 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -66,6 +66,10 @@ EXPORT_SYMBOL_GPL(__sync_icache_dcache);
  * it as dirty for later flushing when mapped in user space (if executable,
  * see __sync_icache_dcache).
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - PG_dcache_clean bit을 clear한다.
+ */
 void flush_dcache_page(struct page *page)
 {
     if (test_bit(PG_dcache_clean, &page->flags))
diff --git a/include/linux/highmem-internal.h b/include/linux/highmem-internal.h
index da3723c960c7..42001f186d17 100644
--- a/include/linux/highmem-internal.h
+++ b/include/linux/highmem-internal.h
@@ -88,6 +88,10 @@ static inline void __kunmap_local(void *vaddr)
     kunmap_local_indexed(vaddr);
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * return page_address(page);
+ */
 static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 {
     if (IS_ENABLED(CONFIG_PREEMPT_RT))
@@ -99,6 +103,14 @@ static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
     return __kmap_local_page_prot(page, prot);
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * 32bit에서는 kmap공간을 이용해서 highmem영역을 mapping하고 접근하지만
+ * 64bit에서는 이미 linear mapping이 전부 되있기때문에 별도의 mapping을
+ * 하지 않고 즉시 접근할수있다.
+ *
+ * return page_address(page);
+ */
 static inline void *kmap_atomic(struct page *page)
 {
     return kmap_atomic_prot(page, kmap_prot);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index de268e6571e4..480d688db1a9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -139,6 +139,15 @@ extern int mmap_rnd_compat_bits __read_mostly;
  * s390 does this to prevent multiplexing of hardware bits
  * related to the physical page in case of virtualization.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - papgo
+ *   읽기 오류에 대해 0 페이지 매핑을 설정하는 일반적인 메모리 관리
+ *   코드를 방지합니다.
+ *   이 매크로는 <asm/pgtable> 내에 정의되어야 합니다.
+ *   s390은 가상화 시 물리적 페이지와 관련된 하드웨어 비트의 다중화를
+ *   방지하기 위해 이를 수행한다.
+ */
 #ifndef mm_forbids_zeropage
 #define mm_forbids_zeropage(X)    (0)
 #endif
@@ -685,6 +694,10 @@ struct vm_operations_struct {
                       unsigned long addr);
 };
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 기본초기화.
+ */
 static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
 {
     static const struct vm_operations_struct dummy_vm_ops = {};
@@ -695,6 +708,11 @@ static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
     INIT_LIST_HEAD(&vma->anon_vma_chain);
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - anon일경우 ops를 null로 한다. 최초 init일때는 dummy_vm_ops와 연결되
+ *   있었을것이다.
+ */
 static inline void vma_set_anonymous(struct vm_area_struct *vma)
 {
     vma->vm_ops = NULL;
@@ -2413,6 +2431,10 @@ static inline void pgtable_pte_page_dtor(struct page *page)
     dec_lruvec_page_state(page, NR_PAGETABLE);
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @pmd page에서 ptl을 spinlock 걸면서 pte를 return한다.
+ */
 #define pte_offset_map_lock(mm, pmd, address, ptlp)    \
 ({                            \
     spinlock_t *__ptl = pte_lockptr(mm, pmd);    \
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index eea1188203d3..1cfae2931135 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -106,6 +106,8 @@ struct page {
  * IAMROOT, 2022.02.05:
  * - pcpu에서 사용하는 경우 : 해당 struct page에 대항하는 struct pcpu_chunk가 set된다.
  * - buddy에서 사용하는경우 : migratetype
+ * - anon으로 사용하는 경우 : page가 속한 vma내에서의
+ *                            pgoff(__page_set_anon_rmap() 참고)
  */
             pgoff_t index;        /* Our offset within mapping. */
             /**
@@ -416,6 +418,15 @@ struct vm_userfaultfd_ctx {};
  * space that has a special rule for the page-fault handlers (ie a shared
  * library, the executable area etc).
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * ex) vm_start = 0x1000, len = 4k라면
+ *        vm_end(vm_start + len) = 0x2000
+ * -----+  
+ * vma  |
+ * -----+ vm_start = 0x1000
+ */
 struct vm_area_struct {
     /* The first cache line has the info for VMA tree walking. */
 
@@ -485,6 +496,11 @@ struct vm_area_struct {
     struct anon_vma *anon_vma;    /* Serialized by page_table_lock */
 
     /* Function pointers to deal with this struct. */
+/*
+ * IAMROOT, 2022.06.04:
+ * - 최초 초기화시 dummy로 연결되있다.(vma_init() 참고)
+ * - anon일 경우 null(vma_set_anonymous() 참고)
+ */
     const struct vm_operations_struct *vm_ops;
 
     /* Information about our backing store: */
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 94a095d02e03..6396174c24aa 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -119,6 +119,23 @@ static inline bool mm_is_oom_victim(struct mm_struct *mm)
  *
  * Return 0 when the PF is safe VM_FAULT_SIGBUS otherwise.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - papgo
+ *   지정된 mm의 페이지 결함이 여전히 신뢰할 수 있는지 확인합니다.
+ *   만약 oom reaper가 mm에 설정된 MMF_UNSTABLE 플래그에 의해 반영되는
+ *   주소 공간을 수집하기 시작했다면 이것은 더 이상 사실이 아니다. 이 때
+ *   !shared 매핑은 내용을 잃어버리고 메모리 손상을 일으킬 수 있습니다
+ *   (원래 내용 대신 0페이지).
+ *
+ *   사용자는 !shared 매핑에 대한 페이지 테이블 항목을 설정하기 전에
+ *   적절한 페이지 테이블 잠금 아래에서 이 항목을 호출해야 합니다.
+ *
+ *   그렇지 않으면 PF가 안전한 VM_FAULT_SIGBUS일 때 0을 반환한다.
+ *
+ * - oom 진행중인 @mm인 경우 MMF_UNSTABLE이 set되있을것이다.
+ *   (__oom_reap_task_mm() 참고)
+ */
 static inline vm_fault_t check_stable_address_space(struct mm_struct *mm)
 {
     if (unlikely(test_bit(MMF_UNSTABLE, &mm->flags)))
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 101ed57cc72f..1c26570de016 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -579,6 +579,12 @@ PAGEFLAG(XenRemapped, xen_remapped, PF_NO_COMPOUND)
 PAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
     __CLEARPAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
     __SETPAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
+/*
+ * IAMROOT, 2022.06.04:
+ * - anon page들은 일반적으로 만들어질때 SwapBacked가 set된다.
+ *   (page_add_new_anon_rmap() 참고)
+ *   clean anon일 경우 flag가 제거된다.
+ */
 PAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)
     __CLEARPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)
     __SETPAGEFLAG(SwapBacked, swapbacked, PF_NO_TAIL)
@@ -794,6 +800,10 @@ static inline int PageUptodate(struct page *page)
     return ret;
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 최근에 page를 갱신했다는 flag.
+ */
 static __always_inline void __SetPageUptodate(struct page *page)
 {
     VM_BUG_ON_PAGE(PageTail(page), page);
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index b03012e0b632..8420f9d0c78e 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -524,6 +524,19 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
  * To be differentiate with macro pte_mkyoung, this macro is used on platforms
  * where software maintains page access bit.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * -papago
+ *  일부 아키텍처에서는 메모리 페이지에 액세스할 때 하드웨어가 페이지
+ *  액세스 비트를 설정하지 않으며, 소프트웨어가 이 비트를 설정하는 것이
+ *  책임입니다. 페이지 액세스 비트를 추적하기 위해 추가적인 페이지 폴트
+ *  패널티를 발생시킨다. 페이지 최적화를 위해 액세스 비트는 이러한
+ *  아치의 모든 페이지 오류 흐름 중에 설정할 수 있습니다.
+ *  macro pte_mkyoung과 차별화하기 위해, 이 매크로는 소프트웨어가 페이지
+ *  액세스 비트를 유지하는 플랫폼에서 사용된다.
+ *
+ * - mips에서만 사용
+ */
 #ifndef pte_sw_mkyoung
 static inline pte_t pte_sw_mkyoung(pte_t pte)
 {
@@ -1030,6 +1043,10 @@ static inline void ptep_modify_prot_commit(struct vm_area_struct *vma,
 #ifdef CONFIG_MMU
 #ifndef pgprot_modify
 #define pgprot_modify pgprot_modify
+/*
+ * IAMROOT, 2022.06.04:
+ * - @oldprot의 cache속성대로 @newprot에 cache속성을 대입한다.
+ */
 static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
 {
     if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot)))
@@ -1239,6 +1256,10 @@ static inline int is_zero_pfn(unsigned long pfn)
     return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - zero page pfn을 가져온다.
+ */
 #define my_zero_pfn(addr)    page_to_pfn(ZERO_PAGE(addr))
 
 #else
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index e79cc927b0f9..e2c87be3ef66 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -27,6 +27,10 @@
  * pointing to this anon_vma once its vma list is empty.
  */
 struct anon_vma {
+/*
+ * IAMROOT, 2022.06.04:
+ * - 최초생성시 root는 자기자신.
+ */
     struct anon_vma *root;        /* Root of this anon_vma tree */
     struct rw_semaphore rwsem;    /* W: modification, R: walking the list */
     /*
@@ -44,8 +48,16 @@ struct anon_vma {
      * This counter is used for making decision about reusing anon_vma
      * instead of forking new one. See comments in function anon_vma_clone.
      */
+/*
+ * IAMROOT, 2022.06.04:
+ * - 최초 할당시 1로 시작한ㄷ.(anon_vma_alloc() 참고)
+ */
     unsigned degree;
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 최초 할당시 parent는 자기자신.
+ */
     struct anon_vma *parent;    /* Parent of this anon_vma */
 
     /*
@@ -192,6 +204,11 @@ void unlink_anon_vmas(struct vm_area_struct *);
 int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
 int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vma가 av이면 prepare가 필요없다.
+ *   reuse가능한 av를 찾거나 av를 할당하고 vma에 연결한다.
+ */
 static inline int anon_vma_prepare(struct vm_area_struct *vma)
 {
     if (likely(vma->anon_vma))
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index ac0394087f7d..5ef47fa24296 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -95,6 +95,10 @@ static inline void force_uaccess_end(mm_segment_t oldfs)
  * as usual) and both source and destination can trigger faults.
  */
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - user영역(@from)을 kernel영역(@to)에 복사한다.
+ */
 static __always_inline __must_check unsigned long
 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
 {
diff --git a/kernel/fork.c b/kernel/fork.c
index 69364b5dfe7a..fb567db57b97 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -342,6 +342,10 @@ static struct kmem_cache *vm_area_cachep;
 /* SLAB cache for mm_struct structures (tsk->mm) */
 static struct kmem_cache *mm_cachep;
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @mm에 추가할 vma를 하나 생성한다.
+ */
 struct vm_area_struct *vm_area_alloc(struct mm_struct *mm)
 {
     struct vm_area_struct *vma;
diff --git a/mm/highmem.c b/mm/highmem.c
index 74df99a370e7..d69452f31634 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -536,6 +536,10 @@ void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
 }
 EXPORT_SYMBOL_GPL(__kmap_local_pfn_prot);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - arm64경우 highmem이 없으므로 page_address(page)로 바로 직행할것이다.
+ */
 void *__kmap_local_page_prot(struct page *page, pgprot_t prot)
 {
     void *kmap;
diff --git a/mm/memory.c b/mm/memory.c
index 362aee2c067e..7d1250c81605 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -607,18 +607,73 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
  * PFNMAP mappings in order to support COWable mappings.
  *
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - papgo
+ *   vm_normal_page - 이 함수는 a pte와 연결된 "struct page"를 가져옵니다.
+ *
+ *   "special" 매핑은 "struct page"와 연관되는 것을 원하지 않습니다
+ *   (struct page가 존재하지 않거나 존재하지만 터치하기를 원하지 않습니다).
+ *   이 경우 NULL이 반환됩니다. "일반" 매핑에는 struct page가 있습니다.  
+ *
+ *   두 가지 광범위한 사례가 있습니다. 첫째로, 아키텍처는 a pte_special()
+ *   pte 비트를 정의할 수 있는데, 이 경우 이 함수는 사소하다. 둘째로,
+ *   아키텍처는 예비 pte 비트를 갖지 않을 수 있으며, 이는 아래에서 설명되는
+ *   더 복잡한 체계를 필요로 한다.
+ *
+ *   원시 VM_PFNMAP 매핑(즉, COWed가 아닌 매핑)은 항상 특수 매핑으로
+ *   간주됩니다(기본 및 유효한 "struct page"가 있더라도).
+ *   VM_PFNMAP의 COWed 페이지는 항상 정상입니다.
+ *
+ *   VM_PFNMAP 매핑 내에서 COWed 페이지를 인식하는 방법은
+ *   "remap_pfn_range()"에서 설정한 규칙을 통해 다음과 같이 인식합니다.
+ *   vma는 VM_PFNMAP 비트를 설정하고 vm_pgoff는 매핑된 첫 번째 PFN을
+ *   가리킵니다.
+ *   따라서 모든 특수 매핑은 항상 규
+ *    pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT)
+ *   를 준수합니다. 일반 매핑의 경우 이는 false입니다.
+ *
+ *   이렇게 하면 이러한 매핑이 가상 주소에서 PFN으로 선형 변환되는 것으로
+ *   제한됩니다. 이 제한을 피하기 위해 vma가 COW 매핑이 아닌 한 임의 매핑을
+ *   허용한다. 이 경우 모든 pte가 특별하다는 것을 안다(COWed가 될 수 없기
+ *   때문이다).
+ *
+ *   임의 특수 매핑의 COW를 지원하기 위해 VM_MIXEDMAP이 있습니다.
+ *
+ *   VM_MIXEDMAP 매핑도 마찬가지로 "struct page" 백업이 있든 없든 메모리를
+ *   포함할 수 있지만, 차이점은 struct page가 있는 _all_ 페이지
+ *   (즉, pfn_valid가 true인 페이지)가 리카운트되고 VM에서 일반 페이지로
+ *   간주된다는 점입니다. 단점은 페이지 카운트가 재설정된다는 것이다
+ *   (이것은 더 느릴 수 있고 일부 PFNMAP 사용자에게는 옵션이 아닐 수 있다). 
+ *   장점은 COWable 매핑을 지원하기 위해 PFNMAP 매핑의 엄격한 선형성
+ *   규칙을 따를 필요가 없다는 것이다.
+ */
+/*
+ * IAMROOT, 2022.06.04:
+ * - special이 아닌 경우 pfn을 return 한다.
+ * - zero page인 경우 NULL을 retun 한다.
+ * - 나머지는 생략
+ */
 struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
                 pte_t pte)
 {
     unsigned long pfn = pte_pfn(pte);
 
     if (IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL)) {
+/*
+ * IAMROOT, 2022.06.04:
+ * - special이 없으면 check_pfn으로 이동.
+ */
         if (likely(!pte_special(pte)))
             goto check_pfn;
         if (vma->vm_ops && vma->vm_ops->find_special_page)
             return vma->vm_ops->find_special_page(vma, addr);
         if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
             return NULL;
+/*
+ * IAMROOT, 2022.06.04:
+ * - zero page mapping이면 여기서 걸릴것.
+ */
         if (is_zero_pfn(pfn))
             return NULL;
         if (pte_devmap(pte))
@@ -645,6 +700,11 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
         }
     }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - CONFIG_ARCH_HAS_PTE_SPECIAL이 없으면, 여기서 zero page mapping일 경우
+ *   걸릴것이다.
+ */
     if (is_zero_pfn(pfn))
         return NULL;
 
@@ -2794,6 +2854,10 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
     struct mm_struct *mm = vma->vm_mm;
     unsigned long addr = vmf->address;
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @src가 존재할경우 @dst로 복사하고 끝낸다.
+ */
     if (likely(src)) {
         copy_user_highpage(dst, src, addr, vma);
         return true;
@@ -2805,6 +2869,10 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
      * just copying from the original user address. If that
      * fails, we just zero-fill it. Live with it.
      */
+/*
+ * IAMROOT, 2022.06.04:
+ * - src가 지정되지 않았으면 user address를 dst로 복사한다.
+ */
     kaddr = kmap_atomic(dst);
     uaddr = (void __user *)(addr & PAGE_MASK);
 
@@ -3024,10 +3092,19 @@ static inline void wp_page_reuse(struct vm_fault *vmf)
  *   held to the old page, as well as updating the rmap.
  * - In any case, unlock the PTL and drop the reference we took to the old page.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - write fault(2차 fault) 발생시 user page(new page)를 할당하고 copy를
+ *   한다.
+ */
 static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 {
     struct vm_area_struct *vma = vmf->vma;
     struct mm_struct *mm = vma->vm_mm;
+/*
+ * IAMROOT, 2022.06.04:
+ * - do_wp_page()에서 호출시 zero page일 경우 vmf->page는 NULL.
+ */
     struct page *old_page = vmf->page;
     struct page *new_page = NULL;
     pte_t entry;
@@ -3037,6 +3114,11 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
     if (unlikely(anon_vma_prepare(vma)))
         goto oom;
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - zero page에 mapping됬엇을 경우 zero로 memset하여 할당되고 아니면
+ *   그냥 할당.
+ */
     if (is_zero_pfn(pte_pfn(vmf->orig_pte))) {
         new_page = alloc_zeroed_user_highpage_movable(vma,
                                   vmf->address);
@@ -3283,6 +3365,10 @@ static vm_fault_t wp_page_shared(struct vm_fault *vmf)
  * but allow concurrent faults), with pte both mapped and locked.
  * We return with mmap_lock still held, but pte unmapped and unlocked.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - do write protect page
+ */
 static vm_fault_t do_wp_page(struct vm_fault *vmf)
     __releases(vmf->ptl)
 {
@@ -3301,6 +3387,10 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf)
              mm_tlb_flush_pending(vmf->vma->vm_mm)))
         flush_tlb_page(vmf->vma, vmf->address);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - zero page에 mapping되있었을 경우 NULL.
+ */
     vmf->page = vm_normal_page(vma, vmf->address, vmf->orig_pte);
     if (!vmf->page) {
         /*
@@ -3310,6 +3400,11 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf)
          * We should not cow pages in a shared writeable mapping.
          * Just mark the pages writable and/or call ops->pfn_mkwrite.
          */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - shared일경우 wp_pfn_shared(), 아닐경우 wp_page_copy로 간다.
+ */
         if ((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
                      (VM_WRITE|VM_SHARED))
             return wp_pfn_shared(vmf);
@@ -3758,6 +3853,11 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 /*
  * IAMROOT, 2022.05.21:
  * - anon page fault시 이 함수로 진입하게 될것이다.
+ * 1. write fault가 아닐 경우(read fault)
+ *   zero page에 mapping된다.
+ * 
+ * 2. write fault일 경우.
+ *   사용자 memory에 할당해주고, rmap에 등록한다.
  */
 static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 {
@@ -3780,6 +3880,10 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
      *
      * Here we only have mmap_read_lock(mm).
      */
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vmf->pmd가 0이면 pte 할당을 한다.
+ */
     if (pte_alloc(vma->vm_mm, vmf->pmd))
         return VM_FAULT_OOM;
 
@@ -3788,12 +3892,30 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
         return 0;
 
     /* Use the zero-page for reads */
+/*
+ * IAMROOT, 2022.06.04:
+ * - read시 fault.
+ */
     if (!(vmf->flags & FAULT_FLAG_WRITE) &&
             !mm_forbids_zeropage(vma->vm_mm)) {
+/*
+ * IAMROOT, 2022.06.04:
+ * - zero page의 pte entry를 구해온다.
+ */
         entry = pte_mkspecial(pfn_pte(my_zero_pfn(vmf->address),
                         vma->vm_page_prot));
+/*
+ * IAMROOT, 2022.06.04:
+ * - pmd ptl에 spinlock을 걸면서 해당 lcok을 vmf->pfl에 넣고, pte를
+ *   가져온다.
+ */
         vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
                 vmf->address, &vmf->ptl);
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - mapping이 되있다면 update_mmu_tlb만 하고 unlock으로 이동한다.
+ */
         if (!pte_none(*vmf->pte)) {
             update_mmu_tlb(vma, vmf->address, vmf->pte);
             goto unlock;
@@ -3802,6 +3924,10 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
         if (ret)
             goto unlock;
         /* Deliver the page fault to userland, check inside PT lock */
+/*
+ * IAMROOT, 2022.06.04:
+ * - userfaultfd인지 확인.
+ */
         if (userfaultfd_missing(vma)) {
             pte_unmap_unlock(vmf->pte, vmf->ptl);
             return handle_userfault(vmf, VM_UFFD_MISSING);
@@ -3809,6 +3935,10 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
         goto setpte;
     }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 이쪽으로 왔다는것은 write fault상태일 것이다.
+ */
     /* Allocate our own private page. */
     if (unlikely(anon_vma_prepare(vma)))
         goto oom;
@@ -3828,6 +3958,11 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
     __SetPageUptodate(page);
 
     entry = mk_pte(page, vma->vm_page_prot);
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - mips를 제외하곤 entry 변동이 없다.
+ */
     entry = pte_sw_mkyoung(entry);
     if (vma->vm_flags & VM_WRITE)
         entry = pte_mkwrite(pte_mkdirty(entry));
@@ -3852,8 +3987,18 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 
     inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
     page_add_new_anon_rmap(page, vma, vmf->address, false);
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - file이든 anon이든 inactive부터 시작한다.
+ */
     lru_cache_add_inactive_or_unevictable(page, vma);
 setpte:
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - entry가 실제 pte에 mapping.
+ */
     set_pte_at(vma->vm_mm, vmf->address, vmf->pte, entry);
 
     /* No need to invalidate - it was non-present before */
@@ -4608,6 +4753,11 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
         }
     }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 마지막 pte에서 fault가 발생햇을때.
+ *   첫 fault가 발생한 상황으로, pte가 null인, 즉 mapping이 안된상황이다.
+ */
     if (!vmf->pte) {
         if (vma_is_anonymous(vmf->vma))
             return do_anonymous_page(vmf);
@@ -4615,15 +4765,27 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
             return do_fault(vmf);
     }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - vmf->pte가 있지만 present가 안된. 즉 invalid. swap 상태라는의미.
+ */
     if (!pte_present(vmf->orig_pte))
         return do_swap_page(vmf);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - numa_balancing으로 fault가 발생한지 확인한다.
+ */
     if (pte_protnone(vmf->orig_pte) && vma_is_accessible(vmf->vma))
         return do_numa_page(vmf);
 
     vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
     spin_lock(vmf->ptl);
     entry = vmf->orig_pte;
+/*
+ * IAMROOT, 2022.06.04:
+ * - 같지 않으면 tlb update 요청.
+ */
     if (unlikely(!pte_same(*vmf->pte, entry))) {
         update_mmu_tlb(vmf->vma, vmf->address, vmf->pte);
         goto unlock;
@@ -4633,6 +4795,11 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
             return do_wp_page(vmf);
         entry = pte_mkdirty(entry);
     }
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - af flag set.
+ */
     entry = pte_mkyoung(entry);
     if (ptep_set_access_flags(vmf->vma, vmf->address, vmf->pte, entry,
                 vmf->flags & FAULT_FLAG_WRITE)) {
diff --git a/mm/mmap.c b/mm/mmap.c
index 935d13fa677f..4cf34b594c4c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -100,6 +100,12 @@ static void unmap_region(struct mm_struct *mm,
  *                                w: (no) no
  *                                x: (yes) yes
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - vm_flags의 flags들을 arch prot flag로 변환할때 사용한다.
+ *   작명 : __[Private/Shared][exec, write, read]
+ */
 pgprot_t protection_map[16] __ro_after_init = {
     __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
     __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
@@ -112,6 +118,10 @@ static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
 }
 #endif
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vm_flags를 arch prot flag로 변환한다.
+ */
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
     pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
@@ -122,18 +132,31 @@ pgprot_t vm_get_page_prot(unsigned long vm_flags)
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @oldprot의 cache속성을 return값에 적용한다.
+ */
 static pgprot_t vm_pgprot_modify(pgprot_t oldprot, unsigned long vm_flags)
 {
     return pgprot_modify(oldprot, vm_get_page_prot(vm_flags));
 }
 
 /* Update vma->vm_page_prot to reflect vma->vm_flags. */
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vma에 page prot를 설정한다.
+ */
 void vma_set_page_prot(struct vm_area_struct *vma)
 {
     unsigned long vm_flags = vma->vm_flags;
     pgprot_t vm_page_prot;
 
     vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, vm_flags);
+/*
+ * IAMROOT, 2022.06.04:
+ * - write가능한 shared memory에 tracking이 필요한경우 shared flag를
+ *   제외한다.
+ */
     if (vma_wants_writenotify(vma, vm_page_prot)) {
         vm_flags &= ~VM_SHARED;
         vm_page_prot = vm_pgprot_modify(vm_page_prot, vm_flags);
@@ -750,6 +773,10 @@ static void __vma_link_file(struct vm_area_struct *vma)
     }
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @prev와 @vma를 연결하고 rb tree에 vma를 추가한다.
+ */
 static void
 __vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
     struct vm_area_struct *prev, struct rb_node **rb_link,
@@ -759,6 +786,10 @@ __vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
     __vma_link_rb(mm, vma, rb_link, rb_parent);
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vma를 link하고 @mm에 map_count를 증가시킨다.
+ */
 static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
             struct vm_area_struct *prev, struct rb_node **rb_link,
             struct rb_node *rb_parent)
@@ -830,6 +861,10 @@ static __always_inline void __vma_unlink(struct mm_struct *mm,
  *
  * - @insert는 vma_adjust()에서만 사용한다.
  *   @expand는 vma_merge()에서만 사용한다.
+ *
+ * - vma에 대해 변경(추가 및 확장)이 일어 날시 vma에 관련된 자료구조들을
+ *   갱신한다.  실제 삭제해야될 vma를 삭제하고, vma의 범위를 새로 고치며,
+ *   avc를 새로 정렬한다.
  */
 int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
     unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert,
@@ -1199,6 +1234,10 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
          * we must remove another next too. It would clutter
          * up the code too much to do both in one go.
          */
+/*
+ * IAMROOT, 2022.06.04:
+ * remove_next의 값에 따라 next를 정한다.
+ */
         if (remove_next != 3) {
             /*
              * If "next" was removed and vma->vm_end was
@@ -1220,6 +1259,12 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
              */
             next = vma;
         }
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - remove_next 2의 경우 remove_next 1의 방법으로 한번 더 삭제해야된다
+ *   (2개통합)
+ */
         if (remove_next == 2) {
             remove_next = 1;
             end = next->vm_end;
@@ -1442,6 +1487,10 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
  * parameter) may establish ptes with the wrong permissions of NNNN
  * instead of the right permissions of XXXX.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - @addr ~ @end의 범위의 vma를 하나의 기준 vma로 merge를 진행한다.
+ */
 struct vm_area_struct *vma_merge(struct mm_struct *mm,
             struct vm_area_struct *prev, unsigned long addr,
             unsigned long end, unsigned long vm_flags,
@@ -1607,6 +1656,33 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
  * driver is doing some kind of reference counting. But that doesn't
  * really matter for the anon_vma sharing case.
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - papgo
+ *   anon_vma를 공유할 가치가 있는지 여부를 빠르게 확인할 수 있는 대략적인
+ *   호환성 검사입니다.
+ *
+ *   vm_file이 동일해야 하며 플래그는 mprotect가 변경할 수 있는 항목에서만
+ *   다를 수 있습니다.
+ *
+ *   NOTE! anon_vma를 공유한다는 사실이 두 vma를 병합할 수 있다는 것을
+ *   의미하지는 않습니다. 예를 들어, vm_ops->close() 함수가 있으면
+ *   드라이버가 어떤 종류의 참조 카운트를 수행 중임을 나타내기 때문에 vma
+ *   병합을 거부합니다. 그러나 anon_vma 공유 사례의 경우에는 문제가 되지
+ *   않습니다.
+ *
+ * - @a와 @b를 통합할수있는지 확인한다.
+ * - @a가 before, @b가 after.
+ * 1. a->vm_end = b->vm_stgart
+ *    vma끼리 연속되있는지.
+ * 2. mpol_equal(...)
+ *    memory policy가 같은지 확인
+ * 3. vm_file, vm_flags
+ *    file과 vm_flags가 같은지.
+ * 4. b->vm_pgoff == a->vm_pgoff + ...
+ *    a(before vma)와 b의 pg가 연속되있는지.
+ */
 static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b)
 {
     return a->vm_end == b->vm_start &&
@@ -1638,6 +1714,29 @@ static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *
  * and with the same memory policies). That's all stable, even with just
  * a read lock on the mm_sem.
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - papago
+ *   'old'의 anon_vma를 다시 사용할 수 있는지 확인하기 위해 몇 가지
+ *   기본적인 건전성 검사를 수행합니다. 'a'/'b' vma는 VM 순서로 되어
+ *   있습니다. 이 중 하나는 '이전'과 같고, 다른 하나는 anon_vma를
+ *   공유하려는 새 VM입니다.
+ *
+ *   NOTE! 읽기 위해 mm_sem이 보류된 상태에서 실행되므로, 'old'의
+ *   anon_vma가 병합하려는 다른 페이지 오류로 인해 동시에 설정될 수
+ *   있습니다. 하지만 괜찮습니다: 설정 중이면 자동으로 병합에 사용할 수
+ *   있는 singleton이 되므로 이 모든 것을 낙관적으로 수행할 수 있습니다.
+ *   그러나 포인터를 다시 로드하지 않도록 하기 위해 READ_ONES()를
+ *   수행합니다.
+ *
+ *   IOW(in other word): anon_vma_chain에 대한 "list_is_vma()" 테스트는
+ *   'follow anon_vma' 사례에 대해서만 문제가 됩니다(즉, 포크를 통과했기
+ *   때문에 "복잡한" anon_vma를 반환하는 것을 방지하고자 합니다.
+ *
+ *   또한 두 vma가 호환되는지(인접적이고 동일한 메모리 정책과) 확인합니다.
+ *   mm_sem에 읽기 잠금만 있어도 안정적입니다.
+ */
 static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b)
 {
     if (anon_vma_compatible(a, b)) {
@@ -1657,6 +1756,13 @@ static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_
  * anon_vmas being allocated, preventing vma merge in subsequent
  * mprotect.
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - next가 있으면 next를 기준으로, prev가 있으면 prev를 기준으로 merge가
+ *   가능한지 확인한다.
+ *   가능하면 기존 vma의 av를 재사용한다.
+ */
 struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
 {
     struct anon_vma *anon_vma = NULL;
@@ -1750,6 +1856,12 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,
 /*
  * The caller must write-lock current->mm->mmap_lock.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - user malloc호출시 flag
+ *   prot = PROT_READ|PROT_WRITE
+ *   flags = MAP_PRIVATE|MAP_ANONYMOUS
+ */
 unsigned long do_mmap(struct file *file, unsigned long addr,
             unsigned long len, unsigned long prot,
             unsigned long flags, unsigned long pgoff,
@@ -1819,6 +1931,11 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
 /*
  * IAMROOT, 2022.05.21:
  * - prot, flags를 vm_flags로 변환하여 추가한다.
+ *
+ * - user malloc호출시 flag
+ *   @prot = PROT_READ|PROT_WRITE 
+ *   @flags = MAP_PRIVATE|MAP_ANONYMOUS
+ *   vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
  */
     vm_flags = calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) |
             mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
@@ -1943,6 +2060,10 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
  * IAMROOT, 2022.05.21:
  * - user에서 호출한 malloc인 경우 if문 해당사항이 없어(file이 아닌경우)
  *   vm_mmap_pgoff를 바로 호출할것이다.
+ *
+ * - user malloc호출시 flag
+ *   prot = PROT_READ|PROT_WRITE
+ *   flags = MAP_PRIVATE|MAP_ANONYMOUS
  */
 unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len,
                   unsigned long prot, unsigned long flags,
@@ -2029,6 +2150,20 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
  * to the private version (using protection_map[] without the
  * VM_SHARED bit).
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - write event에 대해 tracking을 하기 위해 확인한다.
+ *   (shared memory)
+ *
+ * -- write notify를 하는 상황.
+ * 반드시 VM_WRITE|VM_SHARED가 둘다 존재해야된다.
+ *
+ * 1. vm_ops에 page_mkwrite or pfn_mkwrite가 존재한다.
+ * (이하는 @vm_page_prot와 vma의 cache속성이 같아야됨.)
+ * 2. soft_dirty기능이 있는 상태에서 VM_SOFTDIRTY가 없는 상황
+ * 3. VM_FPNMAP이 없으면서 writeback을 할수잇는 상황.
+ *
+ */
 int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot)
 {
     vm_flags_t vm_flags = vma->vm_flags;
@@ -2077,6 +2212,11 @@ static inline int accountable_mapping(struct file *file, vm_flags_t vm_flags)
     return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE;
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - user malloc호출시 flag
+ *   @vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
+ */
 unsigned long mmap_region(struct file *file, unsigned long addr,
         unsigned long len, vm_flags_t vm_flags, unsigned long pgoff,
         struct list_head *uf)
@@ -2112,6 +2252,13 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
     /*
      * Private writable mapping: check memory availability
      */
+/*
+ * IAMROOT, 2022.06.04:
+ * - user malloc호출시 flag
+ *   @vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE |
+ *   VM_MAYEXEC | VM_ACCOUNT
+ * shared memory가 아닌 write가 가능한 memory인 경우 VM_ACCOUNT가 추가된다.
+ */
     if (accountable_mapping(file, vm_flags)) {
         charged = len >> PAGE_SHIFT;
         if (security_vm_enough_memory_mm(mm, charged))
@@ -2132,6 +2279,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
      * specific mapper. the address has already been validated, but
      * not unmapped, but the maps are removed from the list.
      */
+/*
+ * IAMROOT, 2022.06.04:
+ * - merge가 안되는 경우이므로 vma를 새로 만든다.
+ */
     vma = vm_area_alloc(mm);
     if (!vma) {
         error = -ENOMEM;
@@ -2234,6 +2385,13 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
      * then new mapped in-place (which must be aimed as
      * a completely new data area).
      */
+/*
+ * IAMROOT, 2022.06.04:
+ * - user malloc호출시 flag
+ *   @vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE |
+ *   VM_MAYEXEC | VM_ACCOUNT | VM_SOFTDIRTY
+ * 최종적으로 vma가 새로 생길시 위와 같은 flag로 완성된다.
+ */
     vma->vm_flags |= VM_SOFTDIRTY;
 
     vma_set_page_prot(vma);
diff --git a/mm/rmap.c b/mm/rmap.c
index 3b8e975f2960..0fdd51ca6763 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -83,6 +83,10 @@
 static struct kmem_cache *anon_vma_cachep;
 static struct kmem_cache *anon_vma_chain_cachep;
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - av를 생성한다.
+ */
 static inline struct anon_vma *anon_vma_alloc(void)
 {
     struct anon_vma *anon_vma;
@@ -198,6 +202,14 @@ static void anon_vma_chain_link(struct vm_area_struct *vma,
  *
  * This must be called with the mmap_lock held for reading.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - av를 만든다.
+ *   만들어진 av와 @vma를 연결하기 위해 avc를 하나 생성해서
+ *   rb tree에 넣는다.
+ *   만약 merge가능한 av가 있다면 merge를 하고 그게 아니면 새로운 av를
+ *   생성한다.
+ */
 int __anon_vma_prepare(struct vm_area_struct *vma)
 {
     struct mm_struct *mm = vma->vm_mm;
@@ -213,6 +225,10 @@ int __anon_vma_prepare(struct vm_area_struct *vma)
     anon_vma = find_mergeable_anon_vma(vma);
     allocated = NULL;
     if (!anon_vma) {
+/*
+ * IAMROOT, 2022.06.04:
+ * - merge가 가능한 av가 없으면 할당을 시도한다.
+ */
         anon_vma = anon_vma_alloc();
         if (unlikely(!anon_vma))
             goto out_enomem_free_avc;
@@ -222,6 +238,10 @@ int __anon_vma_prepare(struct vm_area_struct *vma)
     anon_vma_lock_write(anon_vma);
     /* page_table_lock to protect against threads */
     spin_lock(&mm->page_table_lock);
+/*
+ * IAMROOT, 2022.06.04:
+ * - @vma에 연결되있던 av가 없으면 현재 생성되었거나 reuse하는 av로 넣는다.
+ */
     if (likely(!vma->anon_vma)) {
         vma->anon_vma = anon_vma;
         anon_vma_chain_link(vma, avc, anon_vma);
@@ -370,6 +390,14 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
  * the corresponding VMA in the parent process is attached to.
  * Returns 0 on success, non-zero on failure.
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * @vma : @pvma로부터 복사된 새로만들어진 child vma
+ * @pvma : parent vma
+ *
+ * - dup_mmap()에서 부모의 전체 vma수만큼 호출된다.
+ */
 int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
 {
     struct anon_vma_chain *avc;
@@ -510,6 +538,10 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
     }
 }
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 생성자.
+ */
 static void anon_vma_ctor(void *data)
 {
     struct anon_vma *anon_vma = data;
@@ -1185,6 +1217,12 @@ void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma)
  * @address:    User virtual address of the mapping    
  * @exclusive:    the page is exclusively owned by the current process
  */
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - @page->mapping에 anon_vma + PAGE_MAPPING_ANON을 set하고,
+ *   @page->index에 @page가속한 @vma에서의 pgoff를 set한다.
+ */
 static void __page_set_anon_rmap(struct page *page,
     struct vm_area_struct *vma, unsigned long address, int exclusive)
 {
@@ -1192,6 +1230,10 @@ static void __page_set_anon_rmap(struct page *page,
 
     BUG_ON(!anon_vma);
 
+/*
+ * IAMROOT, 2022.06.04:
+ * - 이미 되있으면 return.
+ */
     if (PageAnon(page))
         return;
 
@@ -1320,12 +1362,20 @@ void do_page_add_anon_rmap(struct page *page,
  * This means the inc-and-test can be bypassed.
  * Page does not have to be locked.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - @page가 anon_vma를 가리키게 만든다.
+ */
 void page_add_new_anon_rmap(struct page *page,
     struct vm_area_struct *vma, unsigned long address, bool compound)
 {
     int nr = compound ? thp_nr_pages(page) : 1;
 
     VM_BUG_ON_VMA(address < vma->vm_start || address >= vma->vm_end, vma);
+/*
+ * IAMROOT, 2022.06.04:
+ * - anon page는 SetPageSwapBacked이 set된다.
+ */
     __SetPageSwapBacked(page);
     if (compound) {
         VM_BUG_ON_PAGE(!PageTransHuge(page), page);
@@ -1339,6 +1389,10 @@ void page_add_new_anon_rmap(struct page *page,
         /* Anon THP always mapped first with PMD */
         VM_BUG_ON_PAGE(PageTransCompound(page), page);
         /* increment count (starts at -1) */
+/*
+ * IAMROOT, 2022.06.04:
+ * - page->_mapcount의 초기값은 -1. 사용시 0으로 set.
+ */
         atomic_set(&page->_mapcount, 0);
     }
     __mod_lruvec_page_state(page, NR_ANON_MAPPED, nr);
diff --git a/mm/swap.c b/mm/swap.c
index 9b7261fa3629..c6154b714d81 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -547,6 +547,12 @@ EXPORT_SYMBOL(lru_cache_add);
  * Place @page on the inactive or unevictable LRU list, depending on its
  * evictability.
  */
+/*
+ * IAMROOT, 2022.06.04:
+ * - 처음 생성된 page는 file이든 anon이든 inactive부터 시작한다.
+ *   원래는 active부터 시작햇는데 refault distance계산때문에 이렇게
+ *   변경됬다.
+ */
 void lru_cache_add_inactive_or_unevictable(struct page *page,
                      struct vm_area_struct *vma)
 {
diff --git a/mm/util.c b/mm/util.c
index aa2a8e7dc3ec..6e01fdf9e8d6 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -507,6 +507,13 @@ int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc)
 }
 EXPORT_SYMBOL_GPL(account_locked_vm);
 
+
+/*
+ * IAMROOT, 2022.06.04:
+ * - user malloc호출시 flag
+ *   prot = PROT_READ|PROT_WRITE
+ *   flags = MAP_PRIVATE|MAP_ANONYMOUS
+ */
 unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
     unsigned long len, unsigned long prot,
     unsigned long flag, unsigned long pgoff)
 

XE Login