[커널 18차] 61주차

2022.07.23 23:19

kkr 조회 수:113

dma 마무리 + qemu 환경 세팅

 

git : https://github.com/iamroot18/5.10/commit/0ec372019adb8d237b1ef4795723e8f604a90e7c

 

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 580d65d8269b..47337898a3ad 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -306,6 +306,11 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page,
 int dma_mmap_pages(struct device *dev, struct vm_area_struct *vma,
         size_t size, struct page *page);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - 일반적으로 cma에서 dma를 할당해오고 memset한다.
+ *   legacy에서는 global pool, swiotlb등에서 할당해올수도있다.
+ */
 static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
         dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
 {
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index eef6169f93fd..cd20987764e2 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -28,6 +28,7 @@
  * IAMROOT, 2021.11.13:
  * - buddy system에서 사용하는 메모리 승수
  *   2^0 ~ 2^10까지 관리한다는것.
+ * - MAX_ORDER_NR_PAGES = 1024
  */
 #ifndef CONFIG_FORCE_MAX_ZONEORDER
 #define MAX_ORDER 11
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 0823f393bdab..87cdc0af88cb 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -213,6 +213,11 @@ static inline void fs_reclaim_release(gfp_t gfp_mask) { }
  * that might allocate, but often don't. Compiles to nothing without
  * CONFIG_LOCKDEP. Includes a conditional might_sleep() if @gfp allows blocking.
  */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - preemption point. 잠깐 쉰다.
+ */
 static inline void might_alloc(gfp_t gfp_mask)
 {
     fs_reclaim_acquire(gfp_mask);
diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 086cf6e5876a..a5f116a266f0 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -310,6 +310,10 @@ int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma,
 #ifdef CONFIG_DMA_GLOBAL_POOL
 static struct dma_coherent_mem *dma_coherent_default_memory __ro_after_init;
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - dma_coherent_default_memory에서 할당해온다.
+ */
 void *dma_alloc_from_global_coherent(struct device *dev, ssize_t size,
                      dma_addr_t *dma_handle)
 {
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index a073366bf51d..e2b2f8c175bc 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -320,6 +320,10 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
     return cma_release(dev_get_cma_area(dev), pages, count);
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - @cma의 bitmap관리를 통해 @page를 가져온다.
+ */
 static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp)
 {
     unsigned int align = min(get_order(size), CONFIG_CMA_ALIGNMENT);
@@ -342,6 +346,11 @@ static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp)
  * there is no need to waste CMA pages for that kind; it also helps reduce
  * fragmentations.
  */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - dev에 cma가 지정되있다면 지정된 cma에서, 아니면 default cma에서 할당해온다.
+ */
 struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
 {
 #ifdef CONFIG_DMA_PERNUMA_CMA
@@ -351,6 +360,11 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
     /* CMA can be used only in the context which permits sleeping */
     if (!gfpflags_allow_blocking(gfp))
         return NULL;
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - dev init에서 dtb등을 통해 cma_area이 설정됬을것.
+ */
     if (dev->cma_area)
         return cma_alloc_aligned(dev->cma_area, size, gfp);
     if (size <= PAGE_SIZE)
@@ -368,6 +382,11 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
         }
     }
 #endif
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - default cma가 가 설정되있으면 default에서 가져온다.
+ */
     if (!dma_contiguous_default_area)
         return NULL;
 
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 086e9b6285ee..5c01c719ec08 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -101,6 +101,10 @@ static void __dma_direct_free_pages(struct device *dev, struct page *page,
     dma_free_contiguous(dev, page, size);
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - cma등을 통해서 dma page를 할당해온다.
+ */
 static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
         gfp_t gfp)
 {
@@ -112,6 +116,11 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
 
     gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
                        &phys_limit);
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - swiotlb를 사용하는 장치라면 해당 방법으로 alloc.
+ */
     if (IS_ENABLED(CONFIG_DMA_RESTRICTED_POOL) &&
         is_swiotlb_for_alloc(dev)) {
         page = swiotlb_alloc(dev, size);
@@ -150,6 +159,10 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
     return page;
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - PASS
+ */
 static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
         dma_addr_t *dma_handle, gfp_t gfp)
 {
@@ -177,6 +190,10 @@ void *dma_direct_alloc(struct device *dev, size_t size,
     if (attrs & DMA_ATTR_NO_WARN)
         gfp |= __GFP_NOWARN;
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - kernel mapping을 하지 않은 경우.
+ */
     if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
         !force_dma_unencrypted(dev) && !is_swiotlb_for_alloc(dev)) {
         page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);
@@ -190,6 +207,10 @@ void *dma_direct_alloc(struct device *dev, size_t size,
         return page;
     }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - arch. arm32, sparc등등
+ */
     if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
         !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
         !IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
@@ -197,6 +218,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
         !is_swiotlb_for_alloc(dev))
         return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - global pool이 있는 kernel config일때, dev가 dma coherent device가 아니라면
+ *   (전용 dma가 아니라면) global pool에서 메모리를 할당한다.
+ */
     if (IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
         !dev_is_dma_coherent(dev))
         return dma_alloc_from_global_coherent(dev, size, dma_handle);
@@ -208,6 +234,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
      * set up another device coherent pool by shared-dma-pool and use
      * dma_alloc_from_dev_coherent instead.
      */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - kernel config에서 dma coherent pool을 지원하고 blocking이 가능한 경우(reclaim)
+ */
     if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
         !gfpflags_allow_blocking(gfp) &&
         (force_dma_unencrypted(dev) ||
@@ -221,6 +252,10 @@ void *dma_direct_alloc(struct device *dev, size_t size,
     if (!page)
         return NULL;
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - remap이 가능한경우, highmem인 경우(32bit system). remap을 한다.
+ */
     if ((IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
          !dev_is_dma_coherent(dev)) ||
         (IS_ENABLED(CONFIG_DMA_REMAP) && PageHighMem(page))) {
@@ -332,12 +367,22 @@ void dma_direct_free(struct device *dev, size_t size,
     __dma_direct_free_pages(dev, dma_direct_to_page(dev, dma_addr), size);
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - 일반적으로 cma에서 dma를 할당해온다.
+ *   legacy에서는 pool에서 할당해올수있다.
+ */
 struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
         dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
 {
     struct page *page;
     void *ret;
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - PASS
+ * - CONFIG_DMA_COHERENT_POOL은 x86에서만 사용했던걸로 보인다.
+ */
     if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
         force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp) &&
         !is_swiotlb_for_alloc(dev))
@@ -346,6 +391,11 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
     page = __dma_direct_alloc_pages(dev, size, gfp);
     if (!page)
         return NULL;
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - highmem에서 가져왔다면 안된다. 그걸 검사하는 루틴.
+ */
     if (PageHighMem(page)) {
         /*
          * Depending on the cma= arguments and per-arch setup
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index bf0e4e22ad06..e9a83f87a454 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -537,6 +537,7 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
 /*
  * IAMROOT, 2022.07.16:
  * - direct alloc인지 ops alloc인지 판단해 alloc한다.
+ *   (1:1를 사용하는 direct 방식인지, iommu를 사용하는 방식인지 판단)
  */
     if (dma_alloc_direct(dev, ops))
         cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs);
@@ -577,6 +578,12 @@ void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 }
 EXPORT_SYMBOL(dma_free_attrs);
 
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - 일반적으로 cma에서 dma를 할당해오고 memset한다.
+ *   legacy에서는 global pool, swiotlb등에서 할당해올수도있다.
+ */
 static struct page *__dma_alloc_pages(struct device *dev, size_t size,
         dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
 {
@@ -595,6 +602,11 @@ static struct page *__dma_alloc_pages(struct device *dev, size_t size,
     return ops->alloc_pages(dev, size, dma_handle, dir, gfp);
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - 일반적으로 cma에서 dma를 할당해오고 memset한다.
+ *   legacy에서는 global pool, swiotlb등에서 할당해올수도있다.
+ */
 struct page *dma_alloc_pages(struct device *dev, size_t size,
         dma_addr_t *dma_handle, enum dma_data_direction dir, gfp_t gfp)
 {
diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
index 5f84e6cdb78e..ebd94879ce41 100644
--- a/kernel/dma/pool.c
+++ b/kernel/dma/pool.c
@@ -21,6 +21,11 @@ static struct gen_pool *atomic_pool_kernel __ro_after_init;
 static unsigned long pool_size_kernel;
 
 /* Size can be defined by the coherent_pool command line */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - cmdline coherent_pool을 통해서 설정가능.
+ */
 static size_t atomic_pool_size;
 
 /* Dynamic background expansion when the atomic pool is near capacity */
@@ -76,6 +81,10 @@ static bool cma_in_zone(gfp_t gfp)
     return true;
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - PASS
+ */
 static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
                   gfp_t gfp)
 {
@@ -159,6 +168,10 @@ static void atomic_pool_work_fn(struct work_struct *work)
     atomic_pool_resize(atomic_pool_kernel, GFP_KERNEL);
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - slab에서 pool을 할당해오고 초기화한다.
+ */
 static __init struct gen_pool *__dma_atomic_pool_init(size_t pool_size,
                               gfp_t gfp)
 {
@@ -179,6 +192,14 @@ static __init struct gen_pool *__dma_atomic_pool_init(size_t pool_size,
         return NULL;
     }
 
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - ex)
+ *  DMA: preallocated 1024 KiB GFP_KERNEL pool for atomic allocations
+ *  DMA: preallocated 1024 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
+ *  DMA: preallocated 1024 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations 
+ */
     pr_info("DMA: preallocated %zu KiB %pGg pool for atomic allocations\n",
         gen_pool_size(pool) >> 10, &gfp);
     return pool;
@@ -192,6 +213,16 @@ static int __init dma_atomic_pool_init(void)
      * If coherent_pool was not used on the command line, default the pool
      * sizes to 128KB per 1GB of memory, min 128KB, max MAX_ORDER-1.
      */
+/*
+ * IAMROOT, 2022.07.23:
+ * - cmdline coherent_pool설정이 없었다면 totalram_pages를 기준으로 만든다.
+ * - totalram_pages / 8192. 범위는 128k ~ 4MB. RAM 1GB당 128k. 8GB max 1024k
+ * - ex) totalram 4GB, page size = 4k
+ *   totalram_pages  = 1MB
+ *   pages = 1MB / 8192 = 128
+ *   pages = MIN(pages, MAX_ORDER_NR_PAGES ) = pages = 128
+ *   atomic_pool_size = MAX( 128 * 4k = 512k, SZ_128K) = 512k
+ */
     if (!atomic_pool_size) {
         unsigned long pages = totalram_pages() / (SZ_1G / SZ_128K);
         pages = min_t(unsigned long, pages, MAX_ORDER_NR_PAGES);
@@ -221,6 +252,18 @@ static int __init dma_atomic_pool_init(void)
 }
 postcore_initcall(dma_atomic_pool_init);
 
+/*
+ * IAMROOT, 2022.07.23:
+ *   prev                     next
+ * - atomic_pool_kernel      atomic_pool_dma32가 존재하면 dma32. 아니면 dma
+ *   atomic_pool_dma32       atomic_pool_dma
+ *   atomic_pool_dma         NULL
+ *
+ * 1. atomic_pool_dma32가 존재하는 경우
+ * atomic_pool_kernel -> atomic_pool_dma32 -> atomic_pool_dma -> NULL
+ * 2. atomic_pool_dma32가 없는 경우
+ * atomic_pool_kernel -> atomic_pool_dma -> NULL
+ */
 static inline struct gen_pool *dma_guess_pool(struct gen_pool *prev, gfp_t gfp)
 {
     if (prev == NULL) {
@@ -230,6 +273,7 @@ static inline struct gen_pool *dma_guess_pool(struct gen_pool *prev, gfp_t gfp)
             return atomic_pool_dma;
         return atomic_pool_kernel;
     }
+
     if (prev == atomic_pool_kernel)
         return atomic_pool_dma32 ? atomic_pool_dma32 : atomic_pool_dma;
     if (prev == atomic_pool_dma32)
@@ -262,6 +306,10 @@ static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
     return pfn_to_page(__phys_to_pfn(phys));
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - PASS
+ */
 struct page *dma_alloc_from_pool(struct device *dev, size_t size,
         void **cpu_addr, gfp_t gfp,
         bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 9a57257988c7..51287a0ee6c6 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -150,6 +150,11 @@ bitmap_clear_ll(unsigned long *map, unsigned long start, unsigned long nr)
  * Create a new special memory pool that can be used to manage special purpose
  * memory not managed by the regular kmalloc/kfree interface.
  */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - struct gen_pool 구조체를 할당하고 초기화한다.
+ */
 struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
 {
     struct gen_pool *pool;
@@ -619,6 +624,14 @@ EXPORT_SYMBOL_GPL(gen_pool_size);
  * If @algo is NULL use gen_pool_first_fit as default
  * memory allocation function.
  */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - pool을 사용할 algo를 set한다.
+ *   __dma_atomic_pool_init()에서 불러왔을 경우
+ *   algo = gen_pool_first_fit_order_align
+ *   data = NULL
+ */
 void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data)
 {
     rcu_read_lock();
diff --git a/mm/cma.c b/mm/cma.c
index b081ce39ae3e..02bb331c2204 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -471,6 +471,11 @@ static inline void cma_debug_show_areas(struct cma *cma) { }
  * This function allocates part of contiguous memory on specific
  * contiguous memory area.
  */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - @cma의 bitmap관리를 통해 @page를 가져온다.
+ */
 struct page *cma_alloc(struct cma *cma, unsigned long count,
                unsigned int align, bool no_warn)
 {
diff --git a/mm/dmapool.c b/mm/dmapool.c
index 64b537b3ccb0..fb205fb92b20 100644
--- a/mm/dmapool.c
+++ b/mm/dmapool.c
@@ -62,6 +62,18 @@ struct dma_page {        /* cacheable header for 'allocation' bytes */
 static DEFINE_MUTEX(pools_lock);
 static DEFINE_MUTEX(pools_reg_lock);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - @dev에 등록되있는 dma_pools를 iterate하며 정보를 출력한다.
+ * - ex)
+ *  # cat /sys/devices/platform/soc/fe007000.dma/pools
+ *  poolinfo - 0.1
+ *  fe007000.dma        0     128    32       1
+ *
+ *  해석
+ *  name              | blocks | 할당가능 개수 | size | pages |
+ *  fe007000.dma      | 0      | 128           | 32   | 1     |
+ */
 static ssize_t pools_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
     unsigned temp;
@@ -102,6 +114,10 @@ static ssize_t pools_show(struct device *dev, struct device_attribute *attr, cha
     return PAGE_SIZE - size;
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - dev_attr_pools
+ */
 static DEVICE_ATTR_RO(pools);
 
 /**
@@ -127,6 +143,14 @@ static DEVICE_ATTR_RO(pools);
  * Return: a dma allocation pool with the requested characteristics, or
  * %NULL if one can't be created.
  */
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - strcut dma_pool을 slab에서 할당받고 @size, @align, @boundary에 따라 값을
+ *   초기화한다.
+ * - @dev의 최초 dma_pool일 경우 sysfs에 생성한다.
+ *
+ */
 struct dma_pool *dma_pool_create(const char *name, struct device *dev,
                  size_t size, size_t align, size_t boundary)
 {
@@ -143,15 +167,26 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev,
         return NULL;
     else if (size < 4)
         size = 4;
-
+/*
+ * IAMROOT, 2022.07.23:
+ * - @size를 @align으로 align시키고, 최소 PAGE_SIZE값 이상으로 할당한다.
+ */
     size = ALIGN(size, align);
     allocation = max_t(size_t, size, PAGE_SIZE);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - boundary가 없으면 Allocation과 동일하게 쓴다.
+ */
     if (!boundary)
         boundary = allocation;
     else if ((boundary < size) || (boundary & (boundary - 1)))
         return NULL;
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - struct dma_pool을 slab에서 할당해온다.
+ */
     retval = kmalloc_node(sizeof(*retval), GFP_KERNEL, dev_to_node(dev));
     if (!retval)
         return retval;
@@ -178,8 +213,18 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev,
      */
     mutex_lock(&pools_reg_lock);
     mutex_lock(&pools_lock);
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - dma_pools이 비어있을경우 sysfs를 생성한다.
+ */
     if (list_empty(&dev->dma_pools))
         empty = true;
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - 만들어진 dma pools을 dev>dma_pools에 추가한다.
+ */
     list_add(&retval->pools, &dev->dma_pools);
     mutex_unlock(&pools_lock);
     if (empty) {
@@ -200,6 +245,17 @@ struct dma_pool *dma_pool_create(const char *name, struct device *dev,
 }
 EXPORT_SYMBOL(dma_pool_create);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - offset으로 next object를 가리킨다.
+ *
+ * <---------------------4096----------------------------->
+ * <----1024----><----1024----><----1024----><----1024---->
+ * |1024|        |2048|        |3072|        |0|          |
+ * ^             ^             ^             ^
+ * 0             vaddr+1024    vaddr+2048     vaddr+3072
+ * (vaddr)
+ */
 static void pool_initialise_page(struct dma_pool *pool, struct dma_page *page)
 {
     unsigned int offset = 0;
@@ -216,6 +272,11 @@ static void pool_initialise_page(struct dma_pool *pool, struct dma_page *page)
     } while (offset < pool->allocation);
 }
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - struct dma_page 자료구조를 slab에서 할당후 dma_alloc_coherent에서 메모리를
+ *   얻어와 page->vaddr에 넣는다.
+ */
 static struct dma_page *pool_alloc_page(struct dma_pool *pool, gfp_t mem_flags)
 {
     struct dma_page *page;
@@ -311,6 +372,10 @@ EXPORT_SYMBOL(dma_pool_destroy);
  * and reports its dma address through the handle.
  * If such a memory block can't be allocated, %NULL is returned.
  */
+/*
+ * IAMROOT, 2022.07.23:
+ * - pool에서 dma object를 하나 가져온다.
+ */
 void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
              dma_addr_t *handle)
 {
@@ -321,6 +386,11 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
 
     might_alloc(mem_flags);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - pool에 있는 page에서 free object가 있는 page를 가져온다. 만약 없다면
+ *   pool_alloc_page를 통해 charge한다.
+ */
     spin_lock_irqsave(&pool->lock, flags);
     list_for_each_entry(page, &pool->page_list, page_list) {
         if (page->offset < pool->allocation)
@@ -339,8 +409,23 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
     list_add(&page->page_list, &pool->page_list);
  ready:
     page->in_use++;
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - 현재 object의 위치를 가져온다.
+ */
     offset = page->offset;
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - next object 위치를 page->offset에 갱신한다.
+ */
     page->offset = *(int *)(page->vaddr + offset);
+
+/*
+ * IAMROOT, 2022.07.23:
+ * - 현재 object 위치 + vaddr로 해서 실제 object의 va를 retval로 가져온다.
+ */
     retval = offset + page->vaddr;
     *handle = offset + page->dma;
 #ifdef    DMAPOOL_DEBUG
@@ -379,10 +464,22 @@ void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
 }
 EXPORT_SYMBOL(dma_pool_alloc);
 
+/*
+ * IAMROOT, 2022.07.23:
+ * - @dma가 소속된 dma_page를 찾는다.
+ */
 static struct dma_page *pool_find_page(struct dma_pool *pool, dma_addr_t dma)
 {
     struct dma_page *page;
 
+/*
+ * IAMROOT, 2022.07.23:
+ * ex) 
+ * <--- allocation-->  <--- allocation-->
+ * |    dma_page1   |  |    dma_page2   | 
+ * ^page->dma          ^page->dma  ^dma
+ *                      dma_page2가 선택된다.
+ */
     list_for_each_entry(page, &pool->page_list, page_list) {
         if (dma < page->dma)
             continue;
@@ -455,6 +552,18 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
 #endif
 
     page->in_use--;
+
+/*
+ * IAMROOT, 2022.07.23:
+ * ex)
+ * 1. before
+ * | o1-inuse        | o2-inuse        | o3-free        |
+ *                                     ^page->offset
+ * 2. after o2 free                          
+ * | o1-inuse        | o2-inuse        | o3-free        |
+ * |                 | o3 offset|      |                |
+ *                   ^page->offset(o2offset으로 갱신)
+ */
     *(int *)vaddr = page->offset;
     page->offset = offset;
     /*
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. 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
» [커널 18차] 61주차 kkr 2022.07.23 113
137 [커널 18차] 60주차 kkr 2022.07.16 129
136 [커널 17차] 95~96주차 ㅇㅇㅇ 2022.07.10 105
135 [커널 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