[커널 18차] 59주차

2022.07.09 22:32

kkr 조회 수:126

cma 관련 진행중.

 

git : https://github.com/iamroot18/5.10/commit/e0c9f62f6a6479e641d894de6ac277b94112ab6d

 

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 704ce595542c..22a4c7f2d99d 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -209,6 +209,10 @@ struct cma_device {
     refcount_t refcount;
     struct list_head    id_list;
     enum ib_gid_type    *default_gid_type;
+/*
+ * IAMROOT, 2022.07.09:
+ * - roce(RDMA용 프로토콜) 관련 정보.
+ */
     u8            *default_roce_tos;
 };
 
@@ -5105,6 +5109,10 @@ static struct pernet_operations cma_pernet_operations = {
     .size = sizeof(struct cma_pernet),
 };
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - cma 관련 자료구조를 생성한다.
+ */
 static int __init cma_init(void)
 {
     int ret;
@@ -5115,6 +5123,13 @@ static int __init cma_init(void)
      * must never be nested under lock so it can find these without having
      * to test with bonding.
      */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   본딩이 활성화된 경우에만 발생하는 드문 잠금 순서 종속성이
+ *   cma_netdev_callback()에 있습니다. lockdep에 rtnl이 잠금 상태에서 중첩되어서는
+ *   안 된다는 것을 가르쳐 본딩으로 테스트하지 않고도 찾을 수 있도록 합니다.
+ */
     if (IS_ENABLED(CONFIG_LOCKDEP)) {
         rtnl_lock();
         mutex_lock(&lock);
@@ -5122,6 +5137,10 @@ static int __init cma_init(void)
         rtnl_unlock();
     }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - workqueue, net susys, InfiniBand SA module client를 생성한다.
+ */
     cma_wq = alloc_ordered_workqueue("rdma_cm", WQ_MEM_RECLAIM);
     if (!cma_wq)
         return -ENOMEM;
diff --git a/include/linux/cma.h b/include/linux/cma.h
index 53fd8c3cdbd0..b420f279e46c 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -32,6 +32,12 @@ extern int __init cma_declare_contiguous_nid(phys_addr_t base,
             phys_addr_t alignment, unsigned int order_per_bit,
             bool fixed, const char *name, struct cma **res_cma,
             int nid);
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - cmdline or kernel config에 의한 cma 정보를 memblock reserved 영역을 할당하고
+ *   @res_cma(struct cma)에 등록한다.
+ */
 static inline int __init cma_declare_contiguous(phys_addr_t base,
             phys_addr_t size, phys_addr_t limit,
             phys_addr_t alignment, unsigned int order_per_bit,
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 4de2a24cadc9..d5ad084c3c5a 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -15,6 +15,11 @@ struct reserved_mem {
     const struct reserved_mem_ops    *ops;
     phys_addr_t            base;
     phys_addr_t            size;
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - cma : struct cma
+ */
     void                *priv;
 };
 
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index d989f030fae0..4b7a7284fae1 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -17,6 +17,11 @@
  * Upon receiving a device removal event, users must destroy the associated
  * RDMA identifier and release all resources allocated with the device.
  */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - InfiniBand를 동작하기 위한 remote DMA.
+ */
 enum rdma_cm_event_type {
     RDMA_CM_EVENT_ADDR_RESOLVED,
     RDMA_CM_EVENT_ADDR_ERROR,
diff --git a/init/main.c b/init/main.c
index c2215bb334c2..a04442f20429 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1341,6 +1341,14 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
      * timer interrupt). Full topology setup happens at smp_init()
      * time - but meanwhile we still have a functioning scheduler.
      */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * -papago
+ *  인터럽트(예: 타이머 인터럽트)를 시작하기 전에 스케줄러를 설정하십시오.
+ *  전체 토폴로지 설정은 smp_init() 시간에 발생하지만 그 동안에는 여전히 작동하는
+ *  스케줄러가 있습니다.
+ */
     sched_init();
 
     if (WARN(!irqs_disabled(),
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index e69c9771c5cc..a073366bf51d 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -57,6 +57,10 @@
 #define CMA_SIZE_MBYTES 0
 #endif
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - dma 할당 api가 사용할 기본 cma
+ */
 struct cma *dma_contiguous_default_area;
 
 /*
@@ -75,6 +79,13 @@ static phys_addr_t  size_cmdline __initdata = -1;
 static phys_addr_t base_cmdline __initdata;
 static phys_addr_t limit_cmdline __initdata;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - admin-guide/kernel-parameters.txt 참고
+ *   cma=nn[MG]@[start[MG][-end[MG]]]
+ *       ^size
+ * - size는 무조건 있어야 된다.
+ */
 static int __init early_cma(char *p)
 {
     if (!p) {
@@ -170,7 +181,11 @@ void __init dma_pernuma_cma_reserve(void)
  */
 /*
  * IAMROOT, 2021.12.18:
- * - TODO
+ * - cmdline에 cma정보가 있다면 해당정보로, 아니면 kernel default or config정보로
+ *   cma size를 정한후 초기화한다.
+ *   1. cmdline or kernel config로 default cma 정보를 초기화.
+ *   2. dt에 default cma가 있을시. 1번에서 초기화했다면 안하고,
+ *   아니면 dt default cma로 수행.
  */
 void __init dma_contiguous_reserve(phys_addr_t limit)
 {
@@ -187,12 +202,20 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
  *   지정이 안되면 CONFIG에 따라서 selected_size를 지정한다.
  */
     if (size_cmdline != -1) {
+/*
+ * IAMROOT, 2022.07.09:
+ * - cmdline
+ */
         selected_size = size_cmdline;
         selected_base = base_cmdline;
         selected_limit = min_not_zero(limit_cmdline, limit);
         if (base_cmdline + size_cmdline == limit_cmdline)
             fixed = true;
     } else {
+/*
+ * IAMROOT, 2022.07.09:
+ * - kernel config
+ */
 #ifdef CONFIG_CMA_SIZE_SEL_MBYTES
         selected_size = size_bytes;
 #elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE)
@@ -238,8 +261,9 @@ dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
  * reserve in range from @base to @limit.
  */
 /*
- * IAMROOT, 2021.10.23:
- * - cma memory allocator. TODO
+ * IAMROOT, 2022.07.09:
+ * - cmdline or kernel config에 의한 cma 정보를 memblock reserved 영역을 할당하고
+ *   @res_cma(struct cma)에 등록한다.
  */
 int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
                        phys_addr_t limit, struct cma **res_cma,
@@ -397,6 +421,10 @@ void dma_free_contiguous(struct device *dev, struct page *page, size_t size)
 #undef pr_fmt
 #define pr_fmt(fmt) fmt
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - rmem->priv에는 cma로 사용할때에 struct cma가 저장되있다.
+ */
 static int rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
 {
     dev->cma_area = rmem->priv;
@@ -414,8 +442,53 @@ static const struct reserved_mem_ops rmem_cma_ops = {
     .device_release = rmem_cma_device_release,
 };
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - ex) boot/dts/amlogic/meson-a1.dtsi
+ *   reserved-memory {
+ *    #address-cells = <2>;
+ *    #size-cells = <2>;
+ *    ranges; 
+ *
+ *    linux,cma {
+ *        compatible = "shared-dma-pool";
+ *        reusable;
+ *        size = <0x0 0x800000>;
+ *        alignment = <0x0 0x400000>;
+ *        linux,cma-default;
+ *    };
+ *  };
+ *
+ * - booting 시 순서
+ * loader -> SPL -> TPL -> UBOOT -> kernel
+ * uboot : DTB, config에서 아주 기본적인 정보를 읽어서 초기화
+ *
+ * - size = <0x0 0x800000>;
+ *   size 정보만 제공했고, 시작 주소는 안정해서 아무데서나 만들어도 된다는뜻.
+ *
+ * - ex)
+ *
+ * reserved-memory {
+ *    #address-cells = <1>;
+ *    #size-cells = <1>;
+ *    ranges;
+ *
+ *    default-pool {
+ *        compatible = "shared-dma-pool";
+ *        size = <0x6000000>;
+ *        alloc-ranges = <0x40000000 0x10000000>;
+ *        reusable;
+ *        linux,cma-default;
+ *    };
+ * };
+ * - alloc-ranges(x,y) : x ~ y 사이에  size만큼 할당하라는 뜻.
+ */
 static int __init rmem_cma_setup(struct reserved_mem *rmem)
 {
+/*
+ * IAMROOT, 2022.07.09:
+ * - 4K * 1024 = 4M 단위 align
+ */
     phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
     phys_addr_t mask = align - 1;
     unsigned long node = rmem->fdt_node;
@@ -423,12 +496,54 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
     struct cma *cma;
     int err;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - dt가 default cma인데 cmdline에 의해 이미 default cma 정보가 있을 경우
+ *   cmdline꺼를 우선으로 생각해서 dt를 안쓴다.
+ */
     if (size_cmdline != -1 && default_cma) {
         pr_info("Reserved memory: bypass %s node, using cmdline CMA params instead\n",
             rmem->name);
         return -EBUSY;
     }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - documentation
+ *   no-map (optional) - empty property
+ *    - Indicates the operating system must not create a virtual mapping
+ *    of the region as part of its standard mapping of system memory,
+ *    nor permit speculative access to it under any circumstances other
+ *    than under the control of the device driver using the region.
+ *   reusable (optional) - empty property
+ *      - The operating system can use the memory in this region with the
+ *      limitation that the device driver(s) owning the region need to be
+ *      able to reclaim it back. Typically that means that the operating
+ *      system can use that region to store volatile or cached data that
+ *      can be otherwise regenerated or migrated elsewhere.
+ * - papago
+ *   no-map (optional) - empty property
+ *   - 운영 체제가 시스템 메모리의 표준 매핑의 일부로 영역의 가상 매핑을
+ *   생성해서는 안 되며 영역을 사용하는 장치 드라이버의 제어 하에 있지 않은
+ *   상황에서 추측적인 액세스를 허용하지 않아야 함을 나타냅니다.
+ *
+ *   reusable (optional) - empty property
+ *   - 운영 체제는 영역을 소유한 장치 드라이버가 다시 회수할 수 있어야 하는
+ *   제한이 있는 이 영역의 메모리를 사용할 수 있습니다. 일반적으로 이는 운영
+ *   체제가 해당 영역을 사용하여 다른 곳에서 reclaim되거나 migrate될 수 있는
+ *   휘발성 또는 캐시된 데이터를 저장할 수 있음을 의미합니다.
+ *
+ * - reserved memory에서의 no-map의 이유
+ *   1. device가 직접 mapping을 하기때문이다. SRAM등 속도가 빠른 memory를 사용할때
+ *   cpu에 있는 l1, l2 cache를 사용하지 않기 위함이다.
+ *   2. device 전용 memory로 cpu개입 없이 사용하기 위함.
+ *
+ * -----------------------
+ *
+ * - 무조건 cma는 reusable, !no-map
+ *   reclaim, migrate가 가능해야 된다. 즉 system이 movable page로 사용하겠다는것.
+ *   (cpu 개입)
+ */
     if (!of_get_flat_dt_prop(node, "reusable", NULL) ||
         of_get_flat_dt_prop(node, "no-map", NULL))
         return -EINVAL;
@@ -446,6 +561,10 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
     /* Architecture specific contiguous memory fixup. */
     dma_contiguous_early_fixup(rmem->base, rmem->size);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - prop가 default_cma라면 default로 넣는다.
+ */
     if (default_cma)
         dma_contiguous_default_area = cma;
 
diff --git a/mm/cma.c b/mm/cma.c
index 995e15480937..b081ce39ae3e 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -92,6 +92,10 @@ static void cma_clear_bitmap(struct cma *cma, unsigned long pfn,
     spin_unlock_irqrestore(&cma->lock, flags);
 }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - @cma 영역의 bitmap을 초기화하고 cma page들을 reserved를 풀고 cma buddy로 옮긴다.
+ */
 static void __init cma_activate_area(struct cma *cma)
 {
     unsigned long base_pfn = cma->base_pfn, pfn;
@@ -107,6 +111,11 @@ static void __init cma_activate_area(struct cma *cma)
      * same zone.
      */
     WARN_ON_ONCE(!pfn_valid(base_pfn));
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - cma는 전부 같은 zone에 있어야된다.
+ */
     zone = page_zone(pfn_to_page(base_pfn));
     for (pfn = base_pfn + 1; pfn < base_pfn + cma->count; pfn++) {
         WARN_ON_ONCE(!pfn_valid(pfn));
@@ -139,6 +148,10 @@ static void __init cma_activate_area(struct cma *cma)
     return;
 }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - dt, cmline, kernel config등으로 미리 초기화된 cma_areas을 설정한다.
+ */
 static int __init cma_init_reserved_areas(void)
 {
     int i;
@@ -162,6 +175,12 @@ core_initcall(cma_init_reserved_areas);
  *
  * This function creates custom contiguous area from already reserved memory.
  */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - size, align, reserved 영역 범위 검사등을 수행하고 cma 정보를 하나 얻고
+ *   초기화한다.
+ */
 int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
                  unsigned int order_per_bit,
                  const char *name,
@@ -176,6 +195,10 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
         return -ENOSPC;
     }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - size가 없거나 이미 reserved 영역과 겹치는지 검사
+ */
     if (!size || !memblock_is_region_reserved(base, size))
         return -EINVAL;
 
@@ -231,6 +254,12 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
  * If @fixed is true, reserve contiguous area at exactly @base.  If false,
  * reserve in range from @base to @limit.
  */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - cmdline or kernel config에 의한 cma 정보를 memblock reserved 영역을 할당하고
+ *   @res_cma(struct cma)에 등록한다.
+ */
 int __init cma_declare_contiguous_nid(phys_addr_t base,
             phys_addr_t size, phys_addr_t limit,
             phys_addr_t alignment, unsigned int order_per_bit,
@@ -315,6 +344,12 @@ int __init cma_declare_contiguous_nid(phys_addr_t base,
 
     /* Reserve memory */
     if (fixed) {
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - start가 0이 아니면 해당 주소를 시작으로 할당한다.
+ * - 겹쳣거나 reserve 할당 실패면 error.
+ */
         if (memblock_is_region_reserved(base, size) ||
             memblock_reserve(base, size) < 0) {
             ret = -EBUSY;
@@ -323,6 +358,10 @@ int __init cma_declare_contiguous_nid(phys_addr_t base,
     } else {
         phys_addr_t addr = 0;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - start가 0이였으면 memblock의 lowmem 영역에서의 할당 정책을 따른다.
+ */
         /*
          * All pages in the reserved area must come from the same zone.
          * If the requested region crosses the low/high memory boundary,
@@ -343,6 +382,15 @@ int __init cma_declare_contiguous_nid(phys_addr_t base,
          * Avoid using first 4GB to not interfere with constrained zones
          * like DMA/DMA32.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   메모리가 충분하면 상향식 할당을 먼저 시도하십시오. 
+ *   새로운 cma 영역을 노드의 시작 부분에 가깝게 배치하고 compaction이 페이지를 cma
+ *   영역 밖으로 이동시키는 것이지 안으로 이동하지 않도록 보장합니다.
+ *   DMA/DMA32와 같은 제한된 영역을 방해하지 않으려면 처음 4GB를 사용하지 마십시오.
+ * - DMA가 충분하면 4GB 밖에 cma영역을 생성한다.
+ */
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
         if (!memblock_bottom_up() && memblock_end >= SZ_4G + size) {
             memblock_set_bottom_up(true);
@@ -453,7 +501,18 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
     if (bitmap_count > bitmap_maxno)
         goto out;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - config 할당을 시도한다. 실패하는 경우 align단위로 점프하면서 재시도한다.
+ */
     for (;;) {
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - cma는 bitmap으로 관리하기때문에 cma끼리 관리는 불가능하다. frag 되버리고
+ *   후에 큰 범위 요청이 오면 못한다.
+ * - 여기서 spinlock을 통해 bitmap을 관리하므로 cpu 경합을 피한다.
+ */
         spin_lock_irq(&cma->lock);
         bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap,
                 bitmap_maxno, start, bitmap_count, mask,
@@ -474,11 +533,19 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
         ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA,
                      GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0));
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - 성공하면 break.
+ */
         if (ret == 0) {
             page = pfn_to_page(pfn);
             break;
         }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - 실패한경우는 지금 정보를 clear하고 mask + 1(align)단위로 start를 바꾼다.
+ */
         cma_clear_bitmap(cma, pfn, count);
         if (ret != -EBUSY)
             break;
@@ -534,6 +601,10 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
  * It returns false when provided pages do not belong to contiguous area and
  * true otherwise.
  */
+/*
+ * IAMROOT, 2022.07.09:
+ * - buddy로 돌려보내고 cma bitmap clear한다.
+ */
 bool cma_release(struct cma *cma, const struct page *pages,
          unsigned long count)
 {
diff --git a/mm/cma.h b/mm/cma.h
index 2c775877eae2..00d7bd25d0c4 100644
--- a/mm/cma.h
+++ b/mm/cma.h
@@ -12,8 +12,16 @@ struct cma_kobject {
 
 struct cma {
     unsigned long   base_pfn;
+/*
+ * IAMROOT, 2022.07.09:
+ * - page count
+ */
     unsigned long   count;
     unsigned long   *bitmap;
+/*
+ * IAMROOT, 2022.07.09:
+ * - cma에서 관리할때는 0, huge_tlb에서 관리할때는 huge tlb order(9. 2MB)
+ */
     unsigned int order_per_bit; /* Order of pages represented by one bit */
     spinlock_t    lock;
 #ifdef CONFIG_CMA_DEBUGFS
@@ -35,6 +43,10 @@ struct cma {
 extern struct cma cma_areas[MAX_CMA_AREAS];
 extern unsigned cma_area_count;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - cma에서 관리할때는 0, huge_tlb에서 관리할때는 huge tlb order(9. 2MB)
+ */
 static inline unsigned long cma_bitmap_maxno(struct cma *cma)
 {
     return cma->count >> cma->order_per_bit;
diff --git a/mm/compaction.c b/mm/compaction.c
index f6400e2605aa..18ef483c37e1 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -89,6 +89,10 @@ static unsigned long release_freepages(struct list_head *freelist)
     return high_pfn;
 }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - page들의 order를 다 풀어서 single page로 만들어서 @list에 다시 넣는다.
+ */
 static void split_map_pages(struct list_head *list)
 {
     unsigned int i, order, nr_pages;
@@ -757,6 +761,26 @@ static bool compact_unlock_should_abort(spinlock_t *lock,
  * returning 0 on any invalid PFNs or non-free pages inside of the pageblock
  * (even though it may still end up isolating some pages).
  */
+/*
+ * IAMROOT, 2022.07.09:
+ * @strict true 면 무조건 1 page씩 하며 처음부터 끝가지 다 하겠다는 의미.
+ *         false 면 요청한 stride 만큼 page을 점프하면서 하고, migrate page보다
+ *         free page가 많아지면 종료한다.
+ * @stride @strict가 true면 의미없다. 1로 고정.
+ *         @strict가 false인 경우 요청값(1 ~ COMPACT_CLUSTER_MAX)으로 되며
+ *         @stride 단위로 page을 skip한다.
+ *
+ * - stride를 1보다 큰값으로 단위로 검색을 하기도하는데, 한번 실패하게되면
+ *   연속으로 실패가능성이 크므로, 1, 2, 4.. 단위로 점프하면서 isolate가 되는 page를
+ *   찾기 위함도있다. 한번찾아지면 다시 단위가 1로 작아질것이다. stride를 쓰는
+ *   함수면 어짜피 migrate page보다만 free를 얻어오면되서 적당히 빨리 하기위함도
+ *   있는거같다. (isolate_freepages() 참고)
+ * - cma contig에서 할당받을때는 무조건 성공을 해야되기때문에 strice이 true가되서
+ *   stride가 무조건 1로 고정으로되어 skip없이 모든 영역을 검사한다.
+ *
+ * - pageblock내에서 stride page 단위로 freelist에서 page를 제거한다. 제거된
+ *   page는 @freelist로 넣어진다.
+ */
 static unsigned long isolate_freepages_block(struct compact_control *cc,
                 unsigned long *start_pfn,
                 unsigned long end_pfn,
@@ -800,6 +824,11 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
          * The check is racy, but we can consider only valid values
          * and the only danger is skipping too much.
          */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - page가 compound page거나 buddy에 없으면 isolate fail.
+ */
         if (PageCompound(page)) {
             const unsigned int order = compound_order(page);
 
@@ -820,6 +849,10 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
          * so it is correct to skip the suitable migration target
          * recheck as well.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - zone lock을 하고 buddy에 있는지 계속있는지 한번더 검사한다.
+ */
         if (!locked) {
             locked = compact_lock_irqsave(&cc->zone->lock,
                                 &flags, cc);
@@ -830,6 +863,10 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
         }
 
         /* Found a free page, will break it into order-0 pages */
+/*
+ * IAMROOT, 2022.07.09:
+ * - buddy freelist에서 page를 제거한다.
+ */
         order = buddy_order(page);
         isolated = __isolate_free_page(page, order);
         if (!isolated)
@@ -838,8 +875,17 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 
         total_isolated += isolated;
         cc->nr_freepages += isolated;
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - buddy에서 제거한 page를 local freelist에 넣어놓는다.
+ */
         list_add_tail(&page->lru, freelist);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - @strict이 false면 free page를 migratge 했던 page이상이면 중단.
+ */
         if (!strict && cc->nr_migratepages <= cc->nr_freepages) {
             blockpfn += isolated;
             break;
@@ -901,6 +947,17 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
  * (which may be greater then end_pfn if end fell in a middle of
  * a free page).
  */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   non-free 페이지, 유효하지 않은 PFN 또는 [start_pfn, end_pfn) 범위 내의
+ *   영역 경계는 오류로 간주되어 함수가 해당 작업을 실행 취소하고 0을 반환하게
+ *   합니다.
+ *
+ *   그렇지 않으면 함수는 isolate 페이지의 마지막 PFN을 반환합니다(종료가
+ *   빈 페이지의 중간에 있는 경우 end_pfn보다 클 수 있음).
+ */
 unsigned long
 isolate_freepages_range(struct compact_control *cc,
             unsigned long start_pfn, unsigned long end_pfn)
@@ -956,9 +1013,18 @@ isolate_freepages_range(struct compact_control *cc,
     }
 
     /* __isolate_free_page() does not map the pages */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - single page로 나눈다.
+ */
     split_map_pages(&freelist);
 
     if (pfn < end_pfn) {
+/*
+ * IAMROOT, 2022.07.09:
+ * - 실패. buddy로 원복.
+ */
         /* Loop terminated early, cleanup. */
         release_freepages(&freelist);
         return 0;
@@ -1644,6 +1710,10 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
  * Returns -EAGAIN when contented, -EINTR in case of a signal pending, -ENOMEM
  * in case we could not allocate a page, or 0.
  */
+/*
+ * IAMROOT, 2022.07.09:
+ * - @cc->migratepages에 요청범위의 page를 옮긴다.
+ */
 int
 isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
                             unsigned long end_pfn)
@@ -1668,6 +1738,10 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
                     block_end_pfn, cc->zone))
             continue;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - ISOLATE_UNEVICTABLE : mlocked으로 잠긴 page조차 isolate시키라는 강제 명령.
+ */
         ret = isolate_migratepages_block(cc, pfn, block_end_pfn,
                          ISOLATE_UNEVICTABLE);
 
@@ -2210,6 +2284,12 @@ static void isolate_freepages(struct compact_control *cc)
             continue;
 
         /* Found a block suitable for isolating free pages from. */
+/*
+ * IAMROOT, 2022.07.09:
+ * - stride를 1보다 큰값으로 단위로 검색을 하기도하는데, 한번 실패하게되면
+ *   연속으로 실패가능성이 크므로, 1, 2, 4.. 단위로 점프하면서 isolate가 되는 page를
+ *   찾기 위함도있다. 한번찾아지면 다시 단위가 1로 작아질것이다.
+ */
         nr_isolated = isolate_freepages_block(cc, &isolate_start_pfn,
                     block_end_pfn, freelist, stride, false);
 
diff --git a/mm/migrate.c b/mm/migrate.c
index 207b1c53626b..f4ba07309f33 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1431,6 +1431,7 @@ int next_demotion_node(int node)
  */
 /*
  * IAMROOT, 2022.04.02:
+ * @ reason trace, debug 용
  * - 1. get_new_page를 통해서 new_page를 얻어온다.
  *   2. @page를 newpage로 속성들을 복사한다. @page따라서 contents까지
  *   복사한다.
@@ -1729,7 +1730,7 @@ static inline int try_split_thp(struct page *page, struct page **page2,
  */
 /*
  * IAMROOT, 2022.04.02:
- * @reason enum migrate_reason
+ * @reason enum migrate_reason. trace, debug 용
  */
 int migrate_pages(struct list_head *from, new_page_t get_new_page,
         free_page_t put_new_page, unsigned long private,
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c017a743e7a4..8bb9ff44d09b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2017,7 +2017,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
  * IAMROOT, 2022.05.14:
  * - buddy로 free.
  * - @zone에 isolate pageblock이 존재하거나, @page가 isolate일 경우
- *   대표 migratetype으로 변경한다.
+ *   해당 page를 대표 migratetype으로 변경후 buddy로 보낸다.
  */
 static void free_one_page(struct zone *zone,
                 struct page *page, unsigned long pfn,
@@ -2837,6 +2837,11 @@ void __init page_alloc_init_late(void)
 
 #ifdef CONFIG_CMA
 /* Free whole pageblock and set its migration type to MIGRATE_CMA. */
+/*
+ * IAMROOT, 2022.07.09:
+ * - migrate cma buddy로 보내기 위해 reserved clear후 migratetype cma로 pageblock
+ *   migratetype을 설정한다.
+ */
 void __init init_cma_reserved_pageblock(struct page *page)
 {
     unsigned i = pageblock_nr_pages;
@@ -2849,6 +2854,10 @@ void __init init_cma_reserved_pageblock(struct page *page)
 
     set_pageblock_migratetype(page, MIGRATE_CMA);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - ref up을 하고 MIGRATE_CMA buddy로 돌려보낸다.
+ */
     if (pageblock_order >= MAX_ORDER) {
         i = pageblock_nr_pages;
         p = page;
@@ -2863,6 +2872,11 @@ void __init init_cma_reserved_pageblock(struct page *page)
     }
 
     adjust_managed_page_count(page, pageblock_nr_pages);
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - 해당 존에 cma가 이제 생기는것이므로 카운팅 추가.
+ */
     page_zone(page)->cma_pages += pageblock_nr_pages;
 }
 #endif
@@ -4612,6 +4626,11 @@ void split_page(struct page *page, unsigned int order)
 }
 EXPORT_SYMBOL_GPL(split_page);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - @order 단위로 freelist에서 제거한다.
+ * - alloc_contig_pages()로 들어왔으면 @page의 pageblock mt는 isolate일 것이다.
+ */
 int __isolate_free_page(struct page *page, unsigned int order)
 {
     unsigned long watermark;
@@ -4623,6 +4642,11 @@ int __isolate_free_page(struct page *page, unsigned int order)
     zone = page_zone(page);
     mt = get_pageblock_migratetype(page);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - pageblock mt가 isolate가 아니라면 CMA에 할당가능한지 검사.
+ *
+ */
     if (!is_migrate_isolate(mt)) {
         /*
          * Obey watermarks as if the page was being allocated. We can
@@ -4630,6 +4654,13 @@ int __isolate_free_page(struct page *page, unsigned int order)
          * watermark, because we already know our high-order page
          * exists.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   페이지가 할당되는 것처럼 워터마크를 준수합니다. 상위 페이지가 존재한다는
+ *   것을 이미 알고 있기 때문에 상위 워터마크 검사를 제기된 0차 워터마크로
+ *   에뮬레이트할 수 있습니다.
+ */
         watermark = zone->_watermark[WMARK_MIN] + (1UL << order);
         if (!zone_watermark_ok(zone, 0, watermark, 0, ALLOC_CMA))
             return 0;
@@ -4645,6 +4676,11 @@ int __isolate_free_page(struct page *page, unsigned int order)
      * Set the pageblock if the isolated page is at least half of a
      * pageblock
      */
+/*
+ * IAMROOT, 2022.07.09:
+ * - order가 pageblock_order보다 클경우 pageblock단위로
+ *   UNMOVABLE, RECLAIM인 경우 MOVABLE로 변경할지 확인하고 변경한다.
+ */
     if (order >= pageblock_order - 1) {
         struct page *endpage = page + (1 << order) - 1;
         for (; page < endpage; page += pageblock_nr_pages) {
@@ -5198,6 +5234,7 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
 
 /*
  * IAMROOT, 2022.03.05:
+ * @return 할당가능하면 true.
  * - 가장 기본 형태의 free page 확인 함수.
  *   러프한 값을 가지고 @order에 대한 free page를 확인한다.
  */
@@ -10856,6 +10893,11 @@ static int __init cmdline_parse_movablecore(char *p)
 early_param("kernelcore", cmdline_parse_kernelcore);
 early_param("movablecore", cmdline_parse_movablecore);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - @page : buddy system으로 관리하게 될 page.
+ *   @page들을 counting한다.
+ */
 void adjust_managed_page_count(struct page *page, long count)
 {
     atomic_long_add(count, &page_zone(page)->managed_pages);
@@ -11657,6 +11699,22 @@ void *__init alloc_large_system_hash(const char *tablename,
  * cannot get removed (e.g., via memory unplug) concurrently.
  *
  */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papgo
+ *   이 함수는 pageblock에 움직일 수 없는 페이지가 포함되어 있는지 확인합니다.
+ *
+ *   isolate 또는 lru_lock이 없는 PageLRU 검사가 경합하여 MIGRATE_MOVABLE 블록에
+ *   이동할 수 없는 페이지가 포함될 수 있습니다. 또한 lock_page가 없는
+ *   __PageMovable 검사는 경쟁 조건에서 일부 이동 가능한 비 lru 페이지를
+ *   놓칠 수 있습니다. 따라서 이 함수가 정확해야 한다고 기대할 수는 없습니다.
+ *
+ *   참조를 보유하지 않고 페이지를 반환합니다. 호출자가 해당 페이지를
+ *   역참조(예: 덤프)하려는 경우 해당 페이지가 동시에 제거될 수
+ *   없도록(예: 메모리 분리를 통해) 확인해야 합니다.
+ *
+ * - page block내에서 이동불가인 page들이 있는지 확인한다. 있다면 return page
+ */
 struct page *has_unmovable_pages(struct zone *zone, struct page *page,
                  int migratetype, int flags)
 {
@@ -11670,6 +11728,12 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * isolate CMA pageblocks even when they are not movable in fact
          * so consider them movable here.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - unmovable이 요청 범위에 있는지 확인하는 api에서, @page의 pageblock이 cma인데
+ *   다른 migrate type으로 변경을 요청한다면 unmovable로 취급해서 해당
+ *   page를 return한다. 즉 변경 불가의 의미
+ */
         if (is_migrate_cma(migratetype))
             return NULL;
 
@@ -11685,6 +11749,10 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * allocations inside ZONE_MOVABLE, for example when
          * specifying "movablecore".
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - reserved는 변경불가. unmovable 취급.
+ */
         if (PageReserved(page))
             return page;
 
@@ -11693,6 +11761,10 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * pages then it should be reasonably safe to assume the rest
          * is movable.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - movable zone은 변경가능. skip
+ */
         if (zone_idx(zone) == ZONE_MOVABLE)
             continue;
 
@@ -11702,6 +11774,11 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * We need not scan over tail pages because we don't
          * handle each tail page individually in migration.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - huge page인데 migratge support안하면 return page.
+ *   lru도 아니고 non-lru도 아니면 movable 불가이므로 return page.
+ */
         if (PageHuge(page) || PageTransCompound(page)) {
             struct page *head = compound_head(page);
             unsigned int skip_pages;
@@ -11724,6 +11801,10 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * This check already skips compound tails of THP
          * because their page->_refcount is zero at all time.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - free가 되버린 page. continue.
+ */
         if (!page_ref_count(page)) {
             if (PageBuddy(page))
                 iter += (1 << buddy_order(page)) - 1;
@@ -11734,6 +11815,11 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * The HWPoisoned page may be not in buddy system, and
          * page_count() is not 0.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - buddy에 없는 offline page이면서 HWPoison 이거나 PageOfflinㅇ이면
+ *   움직일수있다고 판단.
+ */
         if ((flags & MEMORY_OFFLINE) && PageHWPoison(page))
             continue;
 
@@ -11750,6 +11836,10 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
         if ((flags & MEMORY_OFFLINE) && PageOffline(page))
             continue;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - non-lru movable이거나 lru면 이동가능.
+ */
         if (__PageMovable(page) || PageLRU(page))
             continue;
 
@@ -11758,6 +11848,10 @@ struct page *has_unmovable_pages(struct zone *zone, struct page *page,
          * it.  But now, memory offline itself doesn't call
          * shrink_node_slabs() and it still to be fixed.
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - 그외에는 이동불가 취급.
+ */
         return page;
     }
     return NULL;
@@ -11798,6 +11892,11 @@ static inline void alloc_contig_dump_pages(struct list_head *page_list)
 #endif
 
 /* [start, end) must belong to a single zone. */
+/*
+ * IAMROOT, 2022.07.09:
+ * - @start ~ @end까지 migrate를 수행한다. signal을 받거나 error가 나지 않는한은
+ *   될때까지 수행한다.
+ */
 static int __alloc_contig_migrate_range(struct compact_control *cc,
                     unsigned long start, unsigned long end)
 {
@@ -11819,6 +11918,10 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
             break;
         }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - cc->migratepages가 비어있다면 채운다.
+ */
         if (list_empty(&cc->migratepages)) {
             cc->nr_migratepages = 0;
             ret = isolate_migratepages_range(cc, pfn, end);
@@ -11831,10 +11934,19 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
             break;
         }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - cc->migratepages에 있는 page들 중 clean page들을 reclaim한다.
+ *   못한 page들은 남아있다.
+ */
         nr_reclaimed = reclaim_clean_pages_from_list(cc->zone,
                             &cc->migratepages);
         cc->nr_migratepages -= nr_reclaimed;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - cc->migratepages에 남아있는것들은 migratge한다.
+ */
         ret = migrate_pages(&cc->migratepages, alloc_migration_target,
             NULL, (unsigned long)&mtc, cc->mode, MR_CONTIG_RANGE, NULL);
 
@@ -11847,6 +11959,11 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
     }
 
     lru_cache_enable();
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - 실패했다면 원복후 dump debug 출력.
+ */
     if (ret < 0) {
         if (ret == -EBUSY)
             alloc_contig_dump_pages(&cc->migratepages);
@@ -11877,6 +11994,20 @@ static int __alloc_contig_migrate_range(struct compact_control *cc,
  * pages which PFN is in [start, end) are allocated for the caller and
  * need to be freed with free_contig_range().
  */
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   PFN 범위는 페이지 블록 또는 MAX_ORDER_NR_PAGES 정렬될 필요가 없습니다.
+ *   PFN 범위는 단일 영역에 속해야 합니다.
+ *   
+ *   이 루틴이 수행하는 첫 번째 작업은 범위의 모든 페이지 블록을
+ *   MIGRATE_ISOLATE하려고 시도하는 것입니다. 일단 격리되면 페이지 블록은
+ *   다른 사람이 수정해서는 안 됩니다.
+ *
+ * Return: 성공 또는 음수 오류 코드의 경우 0입니다. 성공하면 PFN이 [시작, 끝]에
+ * 있는 모든 페이지가 호출자에게 할당되고 free_contig_range()로 해제되어야 합니다.
+ */
 int alloc_contig_range(unsigned long start, unsigned long end,
                unsigned migratetype, gfp_t gfp_mask)
 {
@@ -11919,12 +12050,42 @@ int alloc_contig_range(unsigned long start, unsigned long end,
      * aligned range but not in the unaligned, original range are
      * put back to page allocator so that buddy can use them.
      */
-
+/*
+ * IAMROOT, 2022.07.09:
+ * -papago
+ *  여기에서는 범위 내의 모든 페이지 블록을 MIGRITE_ISOLATE로 표시합니다.
+ *  페이지 블록과 최대 순서 페이지는 크기가 다를 수 있으며 페이지 할당자의
+ *  작동 방식 때문에 페이지 할당자가 다른 페이지 블록의 buddy를 병합하거나
+ *  MIGRITE_ISOLATE를 다른 마이그레이션 유형으로 변경하지 않도록 두 페이지 중
+ *  가장 큰 페이지에 범위를 맞춥니다.
+ *
+ *  페이지 블록이 MIGRATE_ISOLATE로 표시되면 정렬되지 않은 범위(즉, 관심 있는
+ *  페이지)에서 페이지를 마이그레이션합니다. 이렇게 하면 범위 내의 모든 페이지가
+ *  다시 페이지 할당자로 MIGRIGHT_ISOLATE됩니다.
+ *
+ *  이 작업이 완료되면 페이지 할당기에서 범위 내의 페이지를 가져와 
+ *  버디 시스템에서 제거합니다. 이런 방식으로 페이지 할당자는 이러한 항목을
+ *  사용하는 것을 고려하지 않습니다.
+ *
+ *  이렇게 하면 페이지 블록을 다시 MIGRATE_CMA/MIGRATE_MOVIBLE로 표시하여
+ *  정렬된 범위에 있지만 정렬되지 않은 원래 범위에 있지 않은 사용 가능한
+ *  페이지가 다시 페이지 할당기에 표시되도록 하여 버디가 사용할 수 있도록 합니다.
+ */
+/*
+ * IAMROOT, 2022.07.09:
+ * - isolate 표식.
+ */
     ret = start_isolate_page_range(pfn_max_align_down(start),
                        pfn_max_align_up(end), migratetype, 0);
     if (ret)
         return ret;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - pcplist에 있는 page들은 사용중으로 취급하기 때문에 일단 buddy로 돌려보낸다.
+ * - 연속된 memory할당을 해야되기때문에 잘려져서 할당되있는 pcp memory들
+ *   방해가 될수있기 때문이다.
+ */
     drain_all_pages(cc.zone);
 
     /*
@@ -11937,7 +12098,26 @@ int alloc_contig_range(unsigned long start, unsigned long end,
      * allocated.  So, if we fall through be sure to clear ret so that
      * -EBUSY is not accidentally used or returned to caller.
      */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   -EBUSY의 경우, 어느 페이지에서 문제가 발생하는지 알고 싶습니다.
+ *   test_pages_isolated()에는 사용 중인 페이지를 보고할 추적점이 있습니다.
+ *
+ *   test_pages_isolated로 호출하기 전에 사용 중인 페이지를 사용할 수 있으며
+ *   범위가 실제로 할당될 수 있습니다. 따라서, 만약 우리가 실패한다면, -EBUSY가
+ *   실수로 사용되거나 호출자에게 반환되지 않도록 반드시 ret를 클리어해야
+ *   합니다.
+ *
+ * - isolate 표시만 해놨던 page들을 실제 isolate시킨다. 그리고 reclaim이 즉시
+ *   가능한것들은 수행하고, 아니면 migrate한다.
+ */
     ret = __alloc_contig_migrate_range(&cc, start, end);
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - !busy이면 error 처리.
+ */
     if (ret && ret != -EBUSY)
         goto done;
     ret = 0;
@@ -11959,8 +12139,31 @@ int alloc_contig_range(unsigned long start, unsigned long end,
      * isolated thus they won't get removed from buddy.
      */
 
+/*
+ * IAMROOT, 2022.07.09:
+ * -papago
+ *  [start, end)의 페이지는 MIGRATE_ISOLATE로 표시된 MAX_ORDER_NR_PAGES
+ *  aligned 블록 내에 있습니다. 또한 [start, end)의 모든 페이지는 페이지 할당자에서
+ *  free입니다.
+ *  우리가 할 일은 [시작, 끝)에서 모든 페이지를 할당하는 것입니다(즉,
+ *  페이지 할당자에서 제거).
+ *
+ *  유일한 문제는 관심 범위의 시작과 끝에 있는 페이지가 페이지 할당자가 보유하는
+ *  페이지와 정렬되지 않을 수 있다는 것입니다. 그들은 highorder 페이지의 일부가
+ *  될 수 있습니다. 이 때문에 더 큰 범위를 예약하고 이 작업이 완료되면 관심이 없는
+ *  페이지를 해제합니다.
+ *
+ *  페이지가 격리되어 buddy로부터 제거되지 않기 때문에 여기에서
+ *  zone->lock을 유지할 필요가 없습니다.
+ */
     order = 0;
     outer_start = start;
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - migrate 끝난 범위를 이제 cma로 쓰기 위해 할당을 시작한다.
+ * - start page가 buddy가 아니라면 order 단위로증가하면서 start를 조정해본다.
+ */
     while (!PageBuddy(pfn_to_page(outer_start))) {
         if (++order >= MAX_ORDER) {
             outer_start = start;
@@ -11969,6 +12172,10 @@ int alloc_contig_range(unsigned long start, unsigned long end,
         outer_start &= ~0UL << order;
     }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - start 지점이 옮겼다면, 해당 지점이 상위 buddy라면 하위 buddy로 변경한다.
+ */
     if (outer_start != start) {
         order = buddy_order(pfn_to_page(outer_start));
 
@@ -11978,17 +12185,33 @@ int alloc_contig_range(unsigned long start, unsigned long end,
          * in this case to report failed page properly
          * on tracepoint in test_pages_isolated()
          */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   outer_start 페이지는 small order buddy 페이지일 수 있으며 시작 페이지는
+ *   포함되지 않습니다. 이 경우 outer_start를 조정하여 test_pages_isolated()의
+ *   추적점에서 실패한 페이지를 제대로 보고합니다.
+ */
         if (outer_start + (1UL << order) <= start)
             outer_start = start;
     }
 
     /* Make sure the range is really isolated. */
+/*
+ * IAMROOT, 2022.07.09:
+ * - migrate해온 page들이 전부 buddy에 있는지 한번 test.
+ */
     if (test_pages_isolated(outer_start, end, 0)) {
         ret = -EBUSY;
         goto done;
     }
 
     /* Grab isolated pages from freelists. */
+/*
+ * IAMROOT, 2022.07.09:
+ * - buddy에 isolate pageorder type으로 들어가있던 page들을 isolate하여
+ *   single page로 가져온다.
+ */
     outer_end = isolate_freepages_range(&cc, outer_start, end);
     if (!outer_end) {
         ret = -EBUSY;
@@ -12104,6 +12327,10 @@ struct page *alloc_contig_pages(unsigned long nr_pages, gfp_t gfp_mask,
 }
 #endif /* CONFIG_CONTIG_ALLOC */
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - 이미 contig alloc을 했던(migrate통일, merge등) page이므로 free만 해준다.
+ */
 void free_contig_range(unsigned long pfn, unsigned long nr_pages)
 {
     unsigned long count = 0;
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index a95c2c6562d0..c7c023638775 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -15,6 +15,11 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/page_isolation.h>
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - @page가 소속된 page block단위로 @migratetype으로 이동이 가능한지 확인한다.
+ *   이동이 가능하다면 isolate한다.
+ */
 static int set_migratetype_isolate(struct page *page, int migratetype, int isol_flags)
 {
     struct zone *zone = page_zone(page);
@@ -37,6 +42,10 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_
      * FIXME: Now, memory hotplug doesn't call shrink_slab() by itself.
      * We just check MOVABLE pages.
      */
+/*
+ * IAMROOT, 2022.07.09:
+ * - page block내에 움직일수없는 page가 있는지 확인한다. 없다면 isolate한다.
+ */
     unmovable = has_unmovable_pages(zone, page, migratetype, isol_flags);
     if (!unmovable) {
         unsigned long nr_pages;
@@ -86,6 +95,15 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
      * approach in order to merge them. Isolation and free will make
      * these pages to be merged.
      */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   isolated pageblock에 pageblock_order 이상의 freepage가 있는 freepage는
+ *   freepage counting 문제로 merge가 제한되기 때문에 free buddy page가 있을
+ *   가능성이 있다.
+ *   move_freepages_block()은 병합을 신경 쓰지 않으므로 병합하려면 다른 접근
+ *   방식이 필요합니다. Isolation 및 free는 이러한 페이지를 병합하도록 합니다.
+ */
     if (PageBuddy(page)) {
         order = buddy_order(page);
         if (order >= pageblock_order && order < MAX_ORDER - 1) {
@@ -122,6 +140,10 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
     spin_unlock_irqrestore(&zone->lock, flags);
 }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - 첫번째 online page를 return.
+ */
 static inline struct page *
 __first_valid_page(unsigned long pfn, unsigned long nr_pages)
 {
@@ -179,6 +201,37 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages)
  *
  * Return: 0 on success and -EBUSY if any part of range cannot be isolated.
  */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papgo
+ *   페이지 할당 유형을 MIGRATE_ISOLATE로 설정하면 해당 범위의 사용 가능한
+ *   페이지가 할당되지 않습니다. 이후에 사용 가능한 페이지와 페이지는 다시
+ *   할당되지 않습니다. 지정된 범위에 MOVAL 또는 CMA가 아닌 마이그레이션 유형이
+ *   포함된 경우 -EBUSY에서 실패합니다. 범위의 모든 페이지를 마지막으로 분리하려면
+ *   호출자가 범위의 모든 페이지를 비워 두어야 합니다.
+ *   test_page_filename은 테스트에 사용할 수 있습니다.
+ *
+ *   두 스레드가 겹치는 범위를 분리하는 것을 방지하는 높은 수준의 동기화
+ *   메커니즘은 없습니다. 이 경우, 한 스레드는 이미 분리되도록 설정된 겹치는
+ *   범위의 페이지 블록을 인식합니다.
+ *   이 문제는 set_migratetype_isolate에서 발생하며 set_migratetype_isolate는
+ *   오류를 반환합니다. 그런 다음 수정한 페이지 블록의 마이그레이션 유형을
+ *   복원하여 정리하고 -EBUSY를 호출자에게 반환합니다. 이렇게 하면 두 개의
+ *   스레드가 겹치는 범위에서 동시에 작동하지 않습니다. 
+ *
+ *   페이지 할당기와의 강력한 동기화도 없습니다. 페이지 블록이 분리되어 있는
+ *   동안 페이지가 해제될 수 있습니다.
+ *   분리 후 drain_all_pages()를 호출하면 대부분의 페이지를 플러시할 수 있습니다.
+ *   그러나 경우에 따라서는 페이지가 pcp 목록에 남아 있을 수 있으며, 이는 페이지가
+ *   이미 격리되어 있는 경우에도 페이지 할당을 허용한다. 호출자에게 필요한 보증
+ *   강도에 따라 zone_pcp_disable/enable()을 사용하여 분리 전에 pcplist를 플러시
+ *   및 해제하고 분리 해제 후 활성화할 수 있습니다.
+ *
+ *   Return: 성공 시 0이고 범위의 어느 부분도 분리할 수 없는 경우 -EBUSY입니다.
+ *
+ * - pageblock단위로 요청범위만큼 @migratetype으로 이동이 가능한지 확인하고
+ *   isolate시킨다.
+ */
 int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
                  unsigned migratetype, int flags)
 {
@@ -189,6 +242,11 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
     BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
     BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages));
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - @start_pfn ~ @end_pfn 을 순회하며 online page가 있는지 확인한다.
+ *   online page들은 isolate를 시킨다.
+ */
     for (pfn = start_pfn;
          pfn < end_pfn;
          pfn += pageblock_nr_pages) {
@@ -202,6 +260,10 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
     }
     return 0;
 undo:
+/*
+ * IAMROOT, 2022.07.09:
+ * - 도중에 실패했다면 원복시킨다.
+ */
     for (pfn = start_pfn;
          pfn < undo_pfn;
          pfn += pageblock_nr_pages) {
@@ -242,6 +304,17 @@ void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
  *
  * Returns the last tested pfn.
  */
+/*
+ * IAMROOT, 2022.07.09:
+ * -papago
+ *  범위의 모든 페이지가 비어 있는지(격리됨을 의미) 테스트하십시오.
+ *  [start_pfn...end_pfn)의 모든 페이지는 동일한 영역에 있어야 합니다.
+ *  이것을 호출하기 전에 zone->lock을 유지해야 합니다.
+ *
+ *  마지막으로 테스트한 pfn을 반환합니다.
+ *
+ * - [pfn, end_pfn) 까지 buddy에 있는지 확인한다.
+ */
 static unsigned long
 __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
                   int flags)
@@ -256,6 +329,13 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
              * the correct MIGRATE_ISOLATE freelist. There is no
              * simple way to verify that as VM_BUG_ON(), though.
              */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   페이지가 사용 가능 목록에 있으면 올바른 MIGRATE_ISOLATE 사용 가능 목록에
+ *   있어야 합니다. 그러나 VM_BUG_ON()으로 이를 확인할 수 있는 간단한 방법은
+ *   없습니다. 
+ */
             pfn += 1 << buddy_order(page);
         else if ((flags & MEMORY_OFFLINE) && PageHWPoison(page))
             /* A HWPoisoned page cannot be also PageBuddy */
@@ -276,6 +356,10 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
 }
 
 /* Caller should ensure that requested range is in a single zone */
+/*
+ * IAMROOT, 2022.07.09:
+ * - 요청범위 page가 전부 buddy에 있는지 확인한다.
+ */
 int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
             int isol_flags)
 {
@@ -289,6 +373,12 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
      * are not aligned to pageblock_nr_pages.
      * Then we just check migratetype first.
      */
+/*
+ * IAMROOT, 2022.07.09:
+ * - papago
+ *   pageblock_nr_pages != MAX_ORDER. 그런 다음 사용 가능한 페이지 청크가
+ *   pageblock_nr_pages에 정렬되지 않습니다. 그런 다음 먼저 migratetype을 확인합니다.
+ */
     for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
         page = __first_valid_page(pfn, pageblock_nr_pages);
         if (page && !is_migrate_isolate_page(page))
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b9e511ee2594..20265b0a24bb 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1842,7 +1842,7 @@ static unsigned int shrink_page_list(struct list_head *page_list,
             if (!PageSwapCache(page)) {
 /*
  * IAMROOT, 2022.05.04:
- * - swap요청이 없다. kepp.
+ * - swap요청이 없다. keep.
  */
                 if (!(sc->gfp_mask & __GFP_IO))
                     goto keep_locked;
@@ -2012,7 +2012,7 @@ static unsigned int shrink_page_list(struct list_head *page_list,
                 SetPageReclaim(page);
 
                 goto activate_locked;
-            }
+        }
 
             if (references == PAGEREF_RECLAIM_CLEAN)
                 goto keep_locked;
@@ -2225,6 +2225,11 @@ static unsigned int shrink_page_list(struct list_head *page_list,
     return nr_reclaimed;
 }
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - 즉시 reclaim이 가능한 page들을 @page_list에서 찾아서 reclaim을 시도한다.
+ *   reclaim못한 page들은 @page_list에 남아있다.
+ */
 unsigned int reclaim_clean_pages_from_list(struct zone *zone,
                         struct list_head *page_list)
 {
@@ -2238,6 +2243,16 @@ unsigned int reclaim_clean_pages_from_list(struct zone *zone,
     LIST_HEAD(clean_pages);
     unsigned int noreclaim_flag;
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - !PageHuge : huge page가 아님
+ *   page_is_file_lru : clean anon page or file lru
+ *   !PageDirty : clean.
+ *   !__PageMovable : non-lru-movable이 아님.
+ *   !PageUnevictable : evictable
+ * - clean anon page or non dirty file cache 인 경우.
+ * - 특별한걸 안한 page라 바로 buddy로 넣을수있는 상태인지 확인.
+ */
     list_for_each_entry_safe(page, next, page_list, lru) {
         if (!PageHuge(page) && page_is_file_lru(page) &&
             !PageDirty(page) && !__PageMovable(page) &&
@@ -2254,10 +2269,19 @@ unsigned int reclaim_clean_pages_from_list(struct zone *zone,
      * change in the future.
      */
     noreclaim_flag = memalloc_noreclaim_save();
+
+/*
+ * IAMROOT, 2022.07.09:
+ * - clean_pages에 잇는 page들을 reclaim 한다.
+ */
     nr_reclaimed = shrink_page_list(&clean_pages, zone->zone_pgdat, &sc,
                     &stat, true);
     memalloc_noreclaim_restore(noreclaim_flag);
 
+/*
+ * IAMROOT, 2022.07.09:
+ * - relcaim에 실패하고 남은 page들은 page_list에 옮긴다.
+ */
     list_splice(&clean_pages, page_list);
     mod_node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE,
                 -(long)nr_reclaimed);
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
148 [커널 17차] 103주차 ㅇㅇㅇ 2022.08.28 35
147 [커널 18차] 66주차 kkr 2022.08.27 76
146 [커널 17차] 101~102주차 ㅇㅇㅇ 2022.08.21 47
145 [커널 18차] 65주차 kkr 2022.08.20 28
144 [커널 18차] 64주차 kkr 2022.08.13 75
143 [커널 17차] 100주차 [1] ㅇㅇㅇ 2022.08.06 100
142 [커널 18차] 63주차 kkr 2022.08.06 102
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 113
137 [커널 18차] 60주차 kkr 2022.07.16 129
136 [커널 17차] 95~96주차 ㅇㅇㅇ 2022.07.10 105
» [커널 18차] 59주차 kkr 2022.07.09 126
134 [커널 19차] 8주차 kanlee 2022.07.02 160
133 [커널 19차] 7주차 kanlee 2022.07.02 95
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 129
XE Login