[커널 18차] 53주차

2022.05.29 01:10

kkr 조회 수:90

git : https://github.com/iamroot18/5.10/commit/1df6d368c598731e85740c8b7171a4d4c0fd7a26


diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 22bf14ab2d16..8cc43d6cfa8a 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -47,6 +47,12 @@ static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
  * since fd_wqh.lock is taken by aio_poll() while it's holding a lock that's
  * also taken in IRQ context.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - userfaultfd
+ *   참고 : https://blog.daum.net/tlos6733/189
+ * - userland측에서 memory fault시 on-demand paging 구현이 가능하게 하는 기능.
+ */
 struct userfaultfd_ctx {
     /* waitqueue head for the pending (i.e. not read) userfaults */
     wait_queue_head_t fault_pending_wqh;
diff --git a/include/linux/list.h b/include/linux/list.h
index c81cf6afcece..550607bb9c35 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -355,6 +355,10 @@ static inline void list_rotate_to_front(struct list_head *list,
  * list_is_singular - tests whether a list has just one entry.
  * @head: the list to test.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - @head가 딱 한개짜리인지 확인한다.
+ */
 static inline int list_is_singular(const struct list_head *head)
 {
     return !list_empty(head) && (head->next == head->prev);
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 210f38d82753..832c653ab561 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -98,6 +98,11 @@ static inline void mpol_get(struct mempolicy *pol)
 }
 
 extern bool __mpol_equal(struct mempolicy *a, struct mempolicy *b);
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - @a, @b의 memory policy가 일치하는지 확인한다.
+ */
 static inline bool mpol_equal(struct mempolicy *a, struct mempolicy *b)
 {
     if (a == b)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a782ddc7723b..de268e6571e4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2909,6 +2909,10 @@ static inline unsigned long vm_end_gap(struct vm_area_struct *vma)
     return vm_end;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma pglen를 구한다.
+ */
 static inline unsigned long vma_pages(struct vm_area_struct *vma)
 {
     return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 685cdb6268f1..4c1cd5f90b7b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -469,6 +469,17 @@ struct vm_area_struct {
      * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack
      * or brk vma (with NULL file) can only be in an anon_vma list.
      */
+/*
+ * IAMROOT, 2022.05.28:
+ * 
+ * - vma list 구조
+ *        parent     child
+ *        prcoess    process
+ *         av1      av2 
+ *          |        |  
+ * vma =>  avc1 <-> avc2
+ * (child)
+ */
     struct list_head anon_vma_chain; /* Serialized by mmap_lock &
                       * page_table_lock */
     struct anon_vma *anon_vma;    /* Serialized by page_table_lock */
@@ -515,6 +526,10 @@ struct mm_struct {
     struct {
         struct vm_area_struct *mmap;        /* list of VMAs */
         struct rb_root mm_rb;
+/*
+ * IAMROOT, 2022.05.28:
+ * - vma가 바뀌었다는걸 ++로 해서 표시.
+ */
         u64 vmacache_seqnum;                   /* per-thread vmacache */
 #ifdef CONFIG_MMU
         unsigned long (*get_unmapped_area) (struct file *filp,
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 6ec3e8ee0591..e79cc927b0f9 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -58,6 +58,11 @@ struct anon_vma {
      */
 
     /* Interval tree of private "related" vmas */
+/*
+ * IAMROOT, 2022.05.28:
+ * - av와 연결된 avc들은 rb tree로 관리한다.
+ *   avc는 vma와 1:1로 연결되있으므로, av는 rb tree를 통해 vma를 관리하게된다.
+ */
     struct rb_root_cached rb_root;
 };
 
@@ -74,10 +79,48 @@ struct anon_vma {
  * The "rb" field indexes on an interval tree the anon_vma_chains
  * which link all the VMAs associated with this anon_vma.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - avc --> vma 
+ *   vma 로 직접 연결
+ *
+ * - avc <-- vma
+ *   같은 vma를 가리키는 avc끼리 vma의 anon_vma_chain을 통해 list로 연결.
+ *
+ * - avc --> av
+ *   anon_vma로 직접 연결
+ *
+ * - avc <-- av
+ *   av에 속한 avc를 rb_root를 통해 rb tree로 관리
+ */
 struct anon_vma_chain {
+/*
+ * IAMROOT, 2022.05.28:
+ * - avc와 연결되는 vma.
+ */
     struct vm_area_struct *vma;
+/*
+ * IAMROOT, 2022.05.28:
+ * - avc와 연결되는 av
+ */
     struct anon_vma *anon_vma;
+/*
+ * IAMROOT, 2022.05.28:
+ * - same_vma를 통해서 같은 vma를 가리키고있는 avc를 list로 연결한다.
+ *       
+ *                                                            
+ * vma                              avc1       avc2           avc3
+ *  ^   anon_vma_chain =========> same_vma <-> same_vma <-> same_vma
+ *  \--------------------------------vma           vma         vma
+ *   \----------------------------------------------+          |
+ *    \--------------------------------------------------------+
+ */
     struct list_head same_vma;   /* locked by mmap_lock & page_table_lock */
+/*
+ * IAMROOT, 2022.05.28:
+ * - avc가 속한 av의 rb root에 들어갈 node.
+ *   av는 여러개의 avc를 rb로 관리한다.
+ */
     struct rb_node rb;            /* locked by anon_vma->rwsem */
     unsigned long rb_subtree_last;
 #ifdef CONFIG_DEBUG_VM_RB
@@ -109,6 +152,10 @@ static inline void get_anon_vma(struct anon_vma *anon_vma)
 
 void __put_anon_vma(struct anon_vma *anon_vma);
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @anon_vma ref drop
+ */
 static inline void put_anon_vma(struct anon_vma *anon_vma)
 {
     if (atomic_dec_and_test(&anon_vma->refcount))
@@ -153,6 +200,10 @@ static inline int anon_vma_prepare(struct vm_area_struct *vma)
     return __anon_vma_prepare(vma);
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @next와 link되있는 anon_vma에서 unlink한다.
+ */
 static inline void anon_vma_merge(struct vm_area_struct *vma,
                   struct vm_area_struct *next)
 {
diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
index 33cea484d1ad..9de3ec5b8b15 100644
--- a/include/linux/userfaultfd_k.h
+++ b/include/linux/userfaultfd_k.h
@@ -72,6 +72,10 @@ extern int mwriteprotect_range(struct mm_struct *dst_mm,
                    bool enable_wp, atomic_t *mmap_changing);
 
 /* mm helpers */
+/*
+ * IAMROOT, 2022.05.28:
+ * - userfaultfd를 사용하는 상황에서, 같은 context를 가지고 있는지 확인한다.
+ */
 static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma,
                     struct vm_userfaultfd_ctx vm_ctx)
 {
diff --git a/include/linux/vmacache.h b/include/linux/vmacache.h
index 6fce268a4588..c57e8c1d1400 100644
--- a/include/linux/vmacache.h
+++ b/include/linux/vmacache.h
@@ -20,6 +20,11 @@ extern struct vm_area_struct *vmacache_find_exact(struct mm_struct *mm,
                           unsigned long end);
 #endif
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - vma가 변경됬을때 ++함으로써 변경됬음을 표시한다.
+ *   후에 무효화시킬것.
+ */
 static inline void vmacache_invalidate(struct mm_struct *mm)
 {
     mm->vmacache_seqnum++;
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index af24dc3febbe..e47abfef4f0a 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1358,6 +1358,12 @@ static int delayed_ref_ctr_inc(struct vm_area_struct *vma)
  * Currently we ignore all errors and always return 0, the callers
  * can't handle the failure anyway.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - 참고
+ *   https://www.brendangregg.com/blog/2015-06-28/linux-ftrace-uprobe.html
+ *   https://docs.kernel.org/trace/uprobetracer.html
+ */
 int uprobe_mmap(struct vm_area_struct *vma)
 {
     struct list_head tmp_list;
diff --git a/kernel/fork.c b/kernel/fork.c
index 38681ad44c76..69364b5dfe7a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -370,6 +370,10 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
     return new;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma free
+ */
 void vm_area_free(struct vm_area_struct *vma)
 {
     kmem_cache_free(vm_area_cachep, vma);
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index d729ac325cf4..56819031e78d 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2369,6 +2369,11 @@ struct mempolicy *__mpol_dup(struct mempolicy *old)
 }
 
 /* Slow path of a mempolicy comparison */
+/*
+ * IAMROOT, 2022.05.28:
+ * - @a, @b의 mempolicy가 일치하는지 확인한다.
+ *   (mode, flags, user_nodemask, nodes)
+ */
 bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
 {
     if (!a || !b)
@@ -2380,7 +2385,10 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
     if (mpol_store_user_nodemask(a))
         if (!nodes_equal(a->w.user_nodemask, b->w.user_nodemask))
             return false;
-
+/*
+ * IAMROOT, 2022.05.28:
+ * - @a, @b의 mode는 일치하는 상태. nodes가 일치하는지 확인한다.
+ */
     switch (a->mode) {
     case MPOL_BIND:
     case MPOL_INTERLEAVE:
diff --git a/mm/mmap.c b/mm/mmap.c
index 5fbaec5b13dd..1f236de74033 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -292,6 +292,10 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
     return origbrk;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - gap 재조정
+ */
 static inline unsigned long vma_compute_gap(struct vm_area_struct *vma)
 {
     unsigned long gap, prev_end;
@@ -446,6 +450,12 @@ RB_DECLARE_CALLBACKS_MAX(static, vma_gap_callbacks,
  * vma->vm_prev->vm_end values changed, without modifying the vma's position
  * in the rbtree.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma의 start나 @vma->prev의 end주소가 변경됬을시 관련값(gap)을
+ *   재조정해줘야된다.
+ * - @vma가 속한 rb부터 시작해 root까지 올라가며 vma_compute_gap()함수를 호출한다.
+ */
 static void vma_gap_update(struct vm_area_struct *vma)
 {
     /*
@@ -512,6 +522,11 @@ static __always_inline void vma_rb_erase(struct vm_area_struct *vma,
  * The entire update must be protected by exclusive mmap_lock and by
  * the root anon_vma's mutex.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma와 연결되있는 avc list를 iterate하여 avc와 연결되있는 각각의 av rb_tree
+ *   에서 avc를 제거한다.
+ */
 static inline void
 anon_vma_interval_tree_pre_update_vma(struct vm_area_struct *vma)
 {
@@ -521,6 +536,12 @@ anon_vma_interval_tree_pre_update_vma(struct vm_area_struct *vma)
         anon_vma_interval_tree_remove(avc, &avc->anon_vma->rb_root);
 }
 
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma와 연결되있는 avc list를 iterate하여 avc와 연결되있는 각각의 av rb_tree
+ *   에 avc를 넣는다.
+ */
 static inline void
 anon_vma_interval_tree_post_update_vma(struct vm_area_struct *vma)
 {
@@ -763,6 +784,10 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
  * Helper for vma_adjust() in the split_vma insert case: insert a vma into the
  * mm's list and rbtree.  It has already been inserted into the interval tree.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - TODO
+ */
 static void __insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
 {
     struct vm_area_struct *prev;
@@ -775,6 +800,12 @@ static void __insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
     mm->map_count++;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @mm에서 @vma를 unlink한다.
+ * - @mm이 관리하는 mm rb tree에서 @vma를 제거한다.
+ * - @mm이 관리하는 mm list에서 @vma를 제거한다.
+ */
 static __always_inline void __vma_unlink(struct mm_struct *mm,
                         struct vm_area_struct *vma,
                         struct vm_area_struct *ignore)
@@ -792,6 +823,14 @@ static __always_inline void __vma_unlink(struct mm_struct *mm,
  * are necessary.  The "insert" vma (if any) is to be inserted
  * before we drop the necessary locks.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * @vma adjust 시작 vma
+ * @expand 통합의 기준이 되는 vma
+ *
+ * - @insert는 vma_adjust()에서만 사용한다.
+ *   @expand는 vma_merge()에서만 사용한다.
+ */
 int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
     unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert,
     struct vm_area_struct *expand)
@@ -806,9 +845,17 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
     long adjust_next = 0;
     int remove_next = 0;
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - adjust 시작 vma의 next가 존재
+ */
     if (next && !insert) {
         struct vm_area_struct *exporter = NULL, *importer = NULL;
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - next가 adjust 대상이 되는 상황.
+ */
         if (end >= next->vm_end) {
             /*
              * vma expands, overlapping all the next, and
@@ -816,6 +863,10 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
              * The only other cases that gets here are
              * case 1, case 7 and case 8.
              */
+/*
+ * IAMROOT, 2022.05.28:
+ * - next가 기준이 되는 상황.
+ */
             if (next == expand) {
                 /*
                  * The only case where we don't expand "vma"
@@ -827,10 +878,43 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
                  * removing "vma" and that to do so we
                  * swapped "vma" and "next".
                  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - case8 => remove_next == 3
+ *       AAAA
+ *   PPPPNNNNXXXX -> PPPPXXXXXXXX
+ * 중간에 있는 NNNN(vma)이 삭제되는 상황이다.
+ * code의 흐름상 next 변수를 지워야되기때문에 지워야되는 NNNN(vma)를 next 변수로
+ * swap하는것이다.
+ */
                 remove_next = 3;
                 VM_WARN_ON(file != next->vm_file);
                 swap(vma, next);
             } else {
+/*
+ * IAMROOT, 2022.05.28:
+ * - 시작 @vma가 기준이 되는 상황.
+ * @vma == PPPP, @expand == PPPP
+ * expoter = NNNN
+ * impoter = PPPP
+ *
+ * - case1 => remove_next == 1
+ *       AAAA    
+ *   PPPP    NNNN -> PPPPPPPPPPPP 
+ *              |end
+ *
+ * - case6 => remove_next == 2
+ *       AAAA 
+ *   PPPPNNNNXXXX -> PPPPPPPPPPPP 
+ *          |   |end
+ *          |next.end
+ *
+ * - case7 => remove_next == 1
+ *       AAAA
+ *   PPPPNNNNXXXX -> PPPPPPPPXXXX
+ *          |end
+ *          |next.end
+ */
                 VM_WARN_ON(expand != vma);
                 /*
                  * case 1, 6, 7, remove_next == 2 is case 6,
@@ -850,10 +934,30 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
              * If next doesn't have anon_vma, import from vma after
              * next, if the vma overlaps with it.
              */
+/*
+ * IAMROOT, 2022.05.28:
+ * - case6 => remove_next == 2
+ *       AAAA 
+ *   PPPPNNNNXXXX -> PPPPPPPPPPPP 
+ *          |   |end
+ *          |next.end
+ *
+ * 이 경우 expoter는 XXXX가 된다.
+ */
             if (remove_next == 2 && !next->anon_vma)
                 exporter = next->vm_next;
 
         } else if (end > next->vm_start) {
+/*
+ * IAMROOT, 2022.05.28:
+ * - next의 일부가 겹치는 상황. case5
+ *
+ * - case5
+ *        AAAA
+ *  PPPPPPNNNNNN -> PPPPPPPPPPNN
+ *        |  |
+ *        <-->adjust_next
+ */
             /*
              * vma expands, overlapping part of the next:
              * mprotect case 5 shifting the boundary up.
@@ -863,6 +967,19 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
             importer = vma;
             VM_WARN_ON(expand != importer);
         } else if (end < vma->vm_end) {
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - case4
+ *    AAAA      
+ *  PPPPPPNNNNNN -> PPNNNNNNNNNN 
+ *    |  |vm_end    
+ *    |end
+ *    <-->adjust_next
+ *
+ * expoter == PPPP
+ * impoter == NNNN
+ */
             /*
              * vma shrinks, and !insert tells it's not
              * split_vma inserting another: so it must be
@@ -874,11 +991,28 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
             VM_WARN_ON(expand != importer);
         }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - case2
+ *     AAAA     
+ * PPPP    NNNN -> PPPPPPPPNNNN 
+ *
+ * - case3
+ *     AAAA     
+ * PPPP    NNNN -> PPPPNNNNNNNN
+ *
+ * case2, case3의 경우 삭제하는게 없다.
+ * remove_vma == 0
+ */
         /*
          * Easily overlooked: when mprotect shifts the boundary,
          * make sure the expanding vma has anon_vma set if the
          * shrinking vma had, to cover any anon pages imported.
          */
+/*
+ * IAMROOT, 2022.05.28:
+ * - expoter가 anon이고 importer가 anon이 아닌경우 copy
+ */
         if (exporter && exporter->anon_vma && !importer->anon_vma) {
             int error;
 
@@ -930,6 +1064,10 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
             vma_interval_tree_remove(next, root);
     }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma 확장이 시작된다.
+ */
     if (start != vma->vm_start) {
         vma->vm_start = start;
         start_changed = true;
@@ -956,6 +1094,10 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
          * vma_merge has merged next into vma, and needs
          * us to remove next before dropping the locks.
          */
+/*
+ * IAMROOT, 2022.05.28:
+ * - next가 제거 되는상황. mm에서 next를 unlink해놓는다.
+ */
         if (remove_next != 3)
             __vma_unlink(mm, next, next);
         else
@@ -979,8 +1121,19 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
          */
         __insert_vm_struct(mm, insert);
     } else {
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma의 start가 변경됬으면 rb tree의 gap정보를 갱신한다.
+ */
         if (start_changed)
             vma_gap_update(vma);
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma end가 바뀌었다면, end vma일 경우 highest_vm_end만 바꾸면되고,
+ *   adjust_next가 있는 상황이면 겹치는 vma를 처리하는 상황이라 gap 정보를
+ *   update할 필요가없다.
+ */
         if (end_changed) {
             if (!next)
                 mm->highest_vm_end = vm_end_gap(vma);
@@ -989,6 +1142,10 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
         }
     }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - 위에서 anon_vma_interval_tree_pre_update_vma()를 상황이면 post를 한다.
+ */
     if (anon_vma) {
         anon_vma_interval_tree_post_update_vma(vma);
         if (adjust_next)
@@ -1004,11 +1161,20 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
             uprobe_mmap(next);
     }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - 위에서 remove_next잇는 상황에서 @mm에서 vma를 unlink만 했었다.
+ *   실제 삭제를 수행한다.
+ */
     if (remove_next) {
         if (file) {
             uprobe_munmap(next, next->vm_start, next->vm_end);
             fput(file);
         }
+/*
+ * IAMROOT, 2022.05.28:
+ * - next에 anon_vma가 존재하면 anon_vma를 unlnk한다.
+ */
         if (next->anon_vma)
             anon_vma_merge(vma, next);
         mm->map_count--;
@@ -1082,6 +1248,12 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
  * If the vma has a ->close operation then the driver probably needs to release
  * per-vma resources, so we don't attempt to merge those.
  */
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - vma가 merge 가능한지 확인한다.
+ *   (flag, file, ops등 확인)
+ */
 static inline int is_mergeable_vma(struct vm_area_struct *vma,
                 struct file *file, unsigned long vm_flags,
                 struct vm_userfaultfd_ctx vm_userfaultfd_ctx)
@@ -1094,8 +1266,16 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma,
      * the kernel to generate new VMAs when old one could be
      * extended instead.
      */
+/*
+ * IAMROOT, 2022.05.28:
+ * - softdirty를 제외한 flag가 동일한지 확인.
+ */
     if ((vma->vm_flags ^ vm_flags) & ~VM_SOFTDIRTY)
         return 0;
+/*
+ * IAMROOT, 2022.05.28:
+ * - anon일경우 file, vma->vm_ops == NULL 일것이다.
+ */
     if (vma->vm_file != file)
         return 0;
     if (vma->vm_ops && vma->vm_ops->close)
@@ -1105,6 +1285,15 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma,
     return 1;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - 해당 vma가 anon으로 만들어졌으면 anon_vma를 가리키게된다.
+ * - anon_vma1과 anon_vma2가 같은지를 return한다.
+ * - 예외 case
+ *   @anon_vma1, @anon_vma2 둘중하나라도 anon이 아니면(NULL이면),
+ *   vma가 한개 이하 인 경우(아직 memory를 할당하지 않은 상황)이거나
+ *   fork가 안된 상황.(fork process가 아닌상황. AV, AVC관련 참고)) return 1.
+ */
 static inline int is_mergeable_anon_vma(struct anon_vma *anon_vma1,
                     struct anon_vma *anon_vma2,
                     struct vm_area_struct *vma)
@@ -1130,6 +1319,14 @@ static inline int is_mergeable_anon_vma(struct anon_vma *anon_vma1,
  * indices (16TB on ia32) because do_mmap() does not permit mmap's which
  * wrap, nor mmaps which cover the final page at index -1UL.
  */
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - 기준 vma가 before에 있을경우에 호출된다. : (기준 vma), (비교대상 vma)
+ *   기준 vma가 before에 있으니 기준 vma의 end주소가 비교대상 vma의 시작주소와
+ *   일치하는지를 확인하면된다.
+ * - mergeable 검사방식은 can_vma_merge_after와 동일한다.
+ */
 static int
 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
              struct anon_vma *anon_vma, struct file *file,
@@ -1151,6 +1348,23 @@ can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
  * We cannot merge two vmas if they have differently assigned (non-NULL)
  * anon_vmas, nor if same anon_vma is assigned but offsets incompatible.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - papgo
+ *  vma보다 더 높은 가상 주소 및 파일 오프셋에서 이 값(vm_flags,anon_vma,file,
+ *   vm_pgoff)을 병합할 수 있으면 true를 반환합니다.
+ *
+ * 서로 다르게 할당된(NULL이 아닌) 것처럼 두 개의 VM을 병합할 수 없으며, 동일한
+ * non_vma가 할당되었지만 오프셋이 호환되지 않는 경우에도 병합할 수 없습니다. 
+ *
+ * - mmap_region->vma_merge->can_vma_merge_after를 통한 함수 호출시
+ *   @vma : prev, 
+ *   @anon_vma : NULL
+ *   @file : new vma(AAAA (vma_merge 주석에서 표현했던 새로운 vma라는 뜻))
+ *   @vm_userfaultfd_ctx : NULL_VM_UFFD_CTX
+ *
+ * - 기준 vma가 after에 있을경우 : (비교대상 vma), (기준 vma) 
+ */
 static int
 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
             struct anon_vma *anon_vma, struct file *file,
@@ -1161,6 +1375,10 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
         is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
         pgoff_t vm_pglen;
         vm_pglen = vma_pages(vma);
+/*
+ * IAMROOT, 2022.05.28:
+ * - file mapping되있는 영역이 연속이 되는 vma인지 확인한다.
+ */
         if (vma->vm_pgoff + vm_pglen == vm_pgoff)
             return 1;
     }
@@ -1230,6 +1448,17 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
 
     next = vma_next(mm, prev);
     area = next;
+/*
+ * IAMROOT, 2022.05.28:
+ * - next가 존재하고 next end가 @end와 일치하면 next를 갱신한다
+ *   (case 6,7,8)
+ *      AAAA 
+ *  PPPPNNNNXXXX <-- XXXX가 next가 됨.
+ *  might become
+ *  PPPPPPPPPPPP 6
+ *  PPPPPPPPXXXX 7
+ *  PPPPXXXXXXXX 8
+ */
     if (area && area->vm_end == end)        /* cases 6, 7, 8 */
         next = next->vm_next;
 
@@ -1241,6 +1470,14 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
     /*
      * Can it merge with the predecessor?
      */
+/*
+ * IAMROOT, 2022.05.28:
+ * 1. prev와 addr이 연결되있는지 확인.
+ * 2. mpol이 같은지 확인.
+ * 3. merge가 가능하고 @prev와 시작주소(pgoff)가 연속되있는지 확인한다.
+ *
+ * prev <- (closed) -> @vma <- (미확인) -> next
+ */
     if (prev && prev->vm_end == addr &&
             mpol_equal(vma_policy(prev), policy) &&
             can_vma_merge_after(prev, vm_flags,
@@ -1249,6 +1486,20 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
         /*
          * OK, it can.  Can we now merge in the successor as well?
          */
+/*
+ * IAMROOT, 2022.05.28:
+ * - case 1,6
+ *   P + A + N + X가 전부 merge 되는 상황
+ *
+ * - next && end == nexte->vm_start를 통해서 next와 연결되있는게 맞다면 case 1,6
+ * 의 상황으로, PANX 전부 인접한 상황인것이다.
+ * prev <- (closed) -> @vma <- (close) -> next
+ *
+ * - prev, vma와의 속성비교(anon + flags)를 직전 if문에서 했으니
+ *   prev, next와의 anon속성만 비교를 한다.
+ *   (prev, next의 flag비교는 can_vma_merge_before에서 됬다.)
+ *
+ */
         if (next && end == next->vm_start &&
                 mpol_equal(policy, vma_policy(next)) &&
                 can_vma_merge_before(next, vm_flags,
@@ -1261,6 +1512,14 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
             err = __vma_adjust(prev, prev->vm_start,
                      next->vm_end, prev->vm_pgoff, NULL,
                      prev);
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - case 2,5,7
+ *   P + A 만 merge 되는 상황
+ *
+ * prev <- (closed) -> @vma <- (merge 불가) -> next
+ */
         } else                    /* cases 2, 5, 7 */
             err = __vma_adjust(prev, prev->vm_start,
                      end, prev->vm_pgoff, NULL, prev);
@@ -1270,6 +1529,15 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
         return prev;
     }
 
+
+/*
+ * IAMROOT, 2022.05.28:
+ * 위 if문에 진입을 못했으면 이상황.
+ *
+ * prev <- (merge 불가) -> @vma <- (미확인) -> next
+ *
+ * case 4, 3, 8이 남았다.
+ */
     /*
      * Can this new request be merged in front of next?
      */
@@ -1278,10 +1546,22 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
             can_vma_merge_before(next, vm_flags,
                          anon_vma, file, pgoff+pglen,
                          vm_userfaultfd_ctx)) {
+/*
+ * IAMROOT, 2022.05.28:
+ *
+ * - prev 와 겹친상황. 즉 case 4.
+ *
+ * prev <- (겹침) -> @vma <- (closed) -> next
+ */
         if (prev && addr < prev->vm_end)    /* case 4 */
             err = __vma_adjust(prev, prev->vm_start,
                      addr, prev->vm_pgoff, NULL, next);
         else {                    /* cases 3, 8 */
+
+/*
+ * IAMROOT, 2022.05.28:
+ * prev <- (merge 불가) -> @vma <- (closed) -> next
+ */
             err = __vma_adjust(area, addr, next->vm_end,
                      next->vm_pgoff - pglen, NULL, next);
             /*
diff --git a/mm/rmap.c b/mm/rmap.c
index 8eb113daa2db..3b8e975f2960 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -102,6 +102,10 @@ static inline struct anon_vma *anon_vma_alloc(void)
     return anon_vma;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @anon_vma free.
+ */
 static inline void anon_vma_free(struct anon_vma *anon_vma)
 {
     VM_BUG_ON(atomic_read(&anon_vma->refcount));
@@ -142,13 +146,27 @@ static void anon_vma_chain_free(struct anon_vma_chain *anon_vma_chain)
     kmem_cache_free(anon_vma_chain_cachep, anon_vma_chain);
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @avc를 avc가 속한 @vma와 @anon_vma에 link한다.
+ *   vma <--(avc)--> anon_vma
+ */
 static void anon_vma_chain_link(struct vm_area_struct *vma,
                 struct anon_vma_chain *avc,
                 struct anon_vma *anon_vma)
 {
     avc->vma = vma;
     avc->anon_vma = anon_vma;
+/*
+ * IAMROOT, 2022.05.28:
+ * - 같은 vma를 가리키는 avc끼리는 list.
+ */
     list_add(&avc->same_vma, &vma->anon_vma_chain);
+
+/*
+ * IAMROOT, 2022.05.28:
+ * - av에 속한 avc는 rb tree로 관리한다.
+ */
     anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 }
 
@@ -236,6 +254,10 @@ int __anon_vma_prepare(struct vm_area_struct *vma)
  * Such anon_vma's should have the same root, so you'd expect to see
  * just a single mutex_lock for the whole traversal.
  */
+/*
+ * IAMROOT, 2022.05.28:
+ * - @anon_vma가 속한 vma(@root)에서 lock을 획득한다.
+ */
 static inline struct anon_vma *lock_anon_vma_root(struct anon_vma *root, struct anon_vma *anon_vma)
 {
     struct anon_vma *new_root = anon_vma->root;
@@ -277,6 +299,11 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
     struct anon_vma_chain *avc, *pavc;
     struct anon_vma *root = NULL;
 
+/*
+ * IAMROOT, 2022.05.28:
+ * 
+ * src => avc3 <-> avc2 <-> avc1
+ */
     list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
         struct anon_vma *anon_vma;
 
@@ -289,6 +316,10 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
                 goto enomem_failure;
         }
         anon_vma = pavc->anon_vma;
+/*
+ * IAMROOT, 2022.05.28:
+ * - anon_vma의 root로부터 lock을 획득하며 anon_vma의 root로 root를 갱신한다.
+ */
         root = lock_anon_vma_root(root, anon_vma);
         anon_vma_chain_link(dst, avc, anon_vma);
 
@@ -300,6 +331,19 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
          * will always reuse it. Root anon_vma is never reused:
          * it has self-parent reference and at least one child.
          */
+/*
+ * IAMROOT, 2022.05.28:
+ * - papgo
+ *   기존 anon_vma가 2보다 낮은 경우 재사용합니다. 즉, vma에는 vma가 없고 하나의
+ *   anon_vma 자식만 있습니다.
+ *
+ *   부모 anon_vma를 선택하지 마십시오. 즉 첫 번째 자식이 항상 다시 사용됩니다.
+ *   root anon_vma는 재사용되지 않습니다
+ *   자기 부모 참조와 적어도 한 명의 자녀가 있습니다. 
+ *
+ * - src만 anon_vma가 있는 상황에서, src가 root가 아니고 차수가 2미만이라면
+ *   anon_vma를 재활용한다.
+ */
         if (!dst->anon_vma && src->anon_vma &&
             anon_vma != src->anon_vma && anon_vma->degree < 2)
             dst->anon_vma = anon_vma;
@@ -387,6 +431,11 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
     return -ENOMEM;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @vma를 anon_vma와 unlink한다. unlink하면서 중간역할을 하는 avc들을 해제한다.
+ *   만약 anon_vma가 비어있다면, anon_vma도 삭제한다.
+ */
 void unlink_anon_vmas(struct vm_area_struct *vma)
 {
     struct anon_vma_chain *avc, *next;
@@ -396,6 +445,13 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
      * Unlink each anon_vma chained to the VMA.  This list is ordered
      * from newest to oldest, ensuring the root anon_vma gets freed last.
      */
+/*
+ * IAMROOT, 2022.05.28:
+ * @vma와 연결된 avc를 순회
+ * 1. av rbtree에서 해당 avc node 삭제.
+ * 2. avc vma list에서 vma node 제거.
+ * 3. avc free
+ */
     list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
         struct anon_vma *anon_vma = avc->anon_vma;
 
@@ -406,6 +462,11 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
          * Leave empty anon_vmas on the list - we'll need
          * to free them outside the lock.
          */
+/*
+ * IAMROOT, 2022.05.28:
+ * - 빈 av인경우 parent av의 degree를 감소키고 다음 avc로 이동.
+ *   lock을 푼후에 삭제할것이다.
+ */
         if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) {
             anon_vma->parent->degree--;
             continue;
@@ -430,10 +491,18 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
      * anon_vmas, destroy them. Could not do before due to __put_anon_vma()
      * needing to write-acquire the anon_vma->root->rwsem.
      */
+/*
+ * IAMROOT, 2022.05.28:
+ * - 비어있던 것들을 마저 삭제한다.
+ */
     list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
         struct anon_vma *anon_vma = avc->anon_vma;
 
         VM_WARN_ON(anon_vma->degree);
+/*
+ * IAMROOT, 2022.05.28:
+ * - 비어있는 것들 이므로 참조를 줄인다.
+ */
         put_anon_vma(anon_vma);
 
         list_del(&avc->same_vma);
@@ -2339,6 +2408,10 @@ int make_device_exclusive_range(struct mm_struct *mm, unsigned long start,
 EXPORT_SYMBOL_GPL(make_device_exclusive_range);
 #endif
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @anon_vma 해제. ref가 0라면 root도 같이 해제한다.
+ */
 void __put_anon_vma(struct anon_vma *anon_vma)
 {
     struct anon_vma *root = anon_vma->root;
diff --git a/mm/util.c b/mm/util.c
index 4e11aca574cb..aa2a8e7dc3ec 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -289,6 +289,10 @@ void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
         next->vm_prev = vma;
 }
 
+/*
+ * IAMROOT, 2022.05.28:
+ * - @mm의 vma list에서 @vma를 제거한다.
+ */
 void __vma_unlink_list(struct mm_struct *mm, struct vm_area_struct *vma)
 {
     struct vm_area_struct *prev, *next;
 

 
번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 617
142 [커널 18차] 63주차 kkr 2022.08.06 94
141 [커널 17차] 99주차 ㅇㅇㅇ 2022.07.31 35
140 [커널 18차] 62주차 kkr 2022.07.30 26
139 [커널 17차] 97~98주차 ㅇㅇㅇ 2022.07.24 52
138 [커널 18차] 61주차 kkr 2022.07.23 112
137 [커널 18차] 60주차 kkr 2022.07.16 118
136 [커널 17차] 95~96주차 ㅇㅇㅇ 2022.07.10 102
135 [커널 18차] 59주차 kkr 2022.07.09 123
134 [커널 19차] 8주차 kanlee 2022.07.02 159
133 [커널 19차] 7주차 kanlee 2022.07.02 89
132 [커널 19차] 6주차 kanlee 2022.07.02 42
131 [커널 19차] 5주차 kanlee 2022.07.02 38
130 [커널 19차] 4주차 kanlee 2022.07.02 106
129 [커널 18차] 57주차 kkr 2022.06.25 127
128 [커널 17차] 94주차 ㅇㅇㅇ 2022.06.19 80
127 [커널 18차] 56주차 kkr 2022.06.18 71
126 [커널 17차] 92~93주차 ㅇㅇㅇ 2022.06.11 92
125 [커널 18차] 54주차 kkr 2022.06.04 77
124 [커널 19차] 3주차 리턴 2022.06.04 215
» [커널 18차] 53주차 kkr 2022.05.29 90
XE Login