๏ปฟ# DMA Pool ๐Ÿ”Œ

๊ด€๋ จ ์†Œ์Šค: mm/dmapool.c, include/linux/dmapool.h, include/linux/dma-mapping.h

๊ฐœ์š” (Overview)

DMA Pool์€ ์ž‘๊ณ  ๊ณ ์ •๋œ ํฌ๊ธฐ์˜ DMA-able(์ผ๊ด€์„ฑ ์žˆ๋Š”, coherent) ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์„ ํšจ์œจ์ ์œผ๋กœ ํ• ๋‹นํ•˜๊ธฐ ์œ„ํ•œ ํ’€ ํ• ๋‹น์ž์ž…๋‹ˆ๋‹ค. ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ž‘์€ DMA ๋ฒ„ํผ๋ฅผ ํ•„์š”๋กœ ํ•  ๋•Œ๋งˆ๋‹ค ์ „์ฒด ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ dma_alloc_coherent()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ๋น„ํšจ์œจ์ ์ด๋ฏ€๋กœ, DMA Pool์€ ํŽ˜์ด์ง€๋ฅผ ํ•œ ๋ฒˆ ํ• ๋‹นํ•œ ํ›„ ๋ฏธ๋ฆฌ ์ž˜๋ผ๋†“์€ ๋ธ”๋ก์œผ๋กœ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๋ถ€์ ์œผ๋กœ dma_pool ๊ตฌ์กฐ์ฒด๊ฐ€ ํ• ๋‹น๋œ ํŽ˜์ด์ง€๋“ค์˜ ์ด์ค‘ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(page_list)๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๊ฐ ํŽ˜์ด์ง€๋Š” boundary ๊ฒฝ๊ณ„์— ๋”ฐ๋ผ ๋ธ”๋ก์œผ๋กœ ๋ถ„ํ• ๋ฉ๋‹ˆ๋‹ค. ํ•ด์ œ๋œ ๋ธ”๋ก์€ ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(next_block)๋กœ ์ถ”์ ๋˜๋ฉฐ, ์‚ฌ์šฉ ์ค‘์ธ ๋ธ”๋ก์€ ๋ณ„๋„๋กœ ์ถ”์ ํ•˜์ง€ ์•Š๊ณ  nr_active ์นด์šดํŠธ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

// mm/dmapool.c
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/slab.h>

๋น ๋ฅธ ์ ๊ฒ€ ๋ช…๋ น

# DMA pool sysfs ์ •๋ณด ํ™•์ธ (์žฅ์น˜๋ณ„)
cat /sys/bus/platform/devices/*/dma_pool/pools 2>/dev/null

# ๋ชจ๋“  DMA pool ์ •๋ณด ์ถœ๋ ฅ
for f in /sys/bus/*/devices/*/dma_pool/pools; do echo "=== $f ==="; cat "$f" 2>/dev/null; done

# DMA ํ• ๋‹น ์‹คํŒจ ํ™•์ธ
dmesg | grep -i "dma" | grep -i "error\|fail"

# IOMMU DMA ๊ด€๋ จ ๋กœ๊ทธ ํ™•์ธ
dmesg | grep -i "swiotlb\|dma-mapping"

# DMA ํ• ๋‹น ํ†ต๊ณ„ (DMA API debug ํ™œ์„ฑํ™” ์‹œ)
cat /sys/kernel/debug/dma/dma_bufstats 2>/dev/null

# ์ปค๋„ DMA ๊ด€๋ จ ์„ค์ • ํ™•์ธ
cat /proc/iomem | grep -i "dma\|swiotlb"

# ํŠน์ • ๋“œ๋ผ์ด๋ฒ„ DMA pool ์‚ฌ์šฉ ํ™•์ธ (์˜ˆ: xHCI)
cat /sys/bus/pci/devices/*/dma_pool/pools 2>/dev/null

# DMA coherent ํ• ๋‹น๋Ÿ‰ ํ™•์ธ
cat /proc/meminfo | grep -i "DMA"

# DMA API debug ํ™œ์„ฑํ™” ํ™•์ธ
grep -r "DMA_API_DEBUG" /boot/config-* 2>/dev/null

# DMA ์žฅ์น˜ ๋งˆ์Šคํฌ ํ™•์ธ
cat /sys/bus/pci/devices/*/dma_mask 2>/dev/null

ํ•ต์‹ฌ ์ž๋ฃŒ๊ตฌ์กฐ

struct dma_pool (ํ’€ ๊ด€๋ฆฌ ๊ตฌ์กฐ์ฒด)

// mm/dmapool.c:48-62
struct dma_pool {          /* DMA ํ’€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ */
struct list_head page_list;   /* ํ• ๋‹น๋œ dma_page ๋ชฉ๋ก (์ด์ค‘ ์—ฐ๊ฒฐ) */
spinlock_t lock;              /* ๋™์‹œ์„ฑ ๋ณดํ˜ธ์šฉ ์Šคํ•€๋ฝ */
struct dma_block *next_block; /* ๋‹ค์Œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก ํฌ์ธํ„ฐ */
size_t nr_blocks;             /* ์ด ๋ธ”๋ก ์ˆ˜ */
size_t nr_active;             /* ์‚ฌ์šฉ ์ค‘์ธ ๋ธ”๋ก ์ˆ˜ */
size_t nr_pages;              /* ํ• ๋‹น๋œ ํŽ˜์ด์ง€ ์ˆ˜ */
struct device *dev;           /* ์ด ํ’€์ด ์†ํ•œ ์žฅ์น˜ */
unsigned int size;            /* ๊ฐ ๋ธ”๋ก์˜ ํฌ๊ธฐ (alignment ์ ์šฉ ํ›„) */
unsigned int allocation;      /* ํ•œ ๋ฒˆ์— ํ• ๋‹นํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ (max(size, PAGE_SIZE)) */
unsigned int boundary;        /* ๋ธ”๋ก์ด ๊ฒฝ๊ณ„๋ฅผ ๋„˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฐ’ (2์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ) */
int node;                     /* NUMA ๋…ธ๋“œ ๋ฒˆํ˜ธ */
char name[32];                /* ํ’€ ์ด๋ฆ„ (์ง„๋‹จ์šฉ) */
struct list_head pools;       /* dev->dma_pools ๋ชฉ๋ก์— ์—ฐ๊ฒฐ๋˜๋Š” ๋…ธ๋“œ */
};
  • page_list: DMA Pool์ด ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ๋“  ํŽ˜์ด์ง€์˜ ๋ฆฌ์ŠคํŠธ. ๊ฐ ํŽ˜์ด์ง€๋Š” ์ตœ์†Œ PAGE_SIZE ํฌ๊ธฐ๋กœ dma_alloc_coherent()๋กœ ํ• ๋‹น๋จ.
  • next_block: ํ•ด์ œ๋œ ๋ธ”๋ก์˜ ๋‹จ์ผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ํ—ค๋“œ. free ๋ธ”๋ก์ด ์—†์œผ๋ฉด NULL.
  • boundary: ํŠน์ • ์žฅ์น˜์˜ DMA ์ „์†ก ์‹œ ๊ฒฝ๊ณ„ ์ œ์•ฝ. ์˜ˆ: 4KB ๊ฒฝ๊ณ„๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋ธ”๋ก์ด 4KB ๊ฒฝ๊ณ„๋ฅผ ๋„˜์ง€ ์•Š์Œ.
  • allocation: max(size, PAGE_SIZE). ํ•œ ๋ฒˆ์— ํ• ๋‹นํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์–‘.
  • struct dma_block (๊ฐœ๋ณ„ ๋ธ”๋ก ํ—ค๋”)

    // mm/dmapool.c:43-46
    struct dma_block {
    struct dma_block *next_block; /* ๋‹ค์Œ free ๋ธ”๋ก์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ */
    dma_addr_t dma;               /* ์ด ๋ธ”๋ก์˜ DMA ๋ฌผ๋ฆฌ ์ฃผ์†Œ */
    };

    ๊ฐ ๋ธ”๋ก์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์˜ค๋ฒ„ํ—ค๋“œ๋กœ ์กด์žฌ. ํ• ๋‹น ์‹œ ์ด ๊ตฌ์กฐ์ฒด ํฌ๊ธฐ๋งŒํผ size๊ฐ€ ์ฆ๊ฐ€ํ•˜์—ฌ ์‹ค์ œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์˜์—ญ์€ block + sizeof(struct dma_block) ๋ถ€ํ„ฐ ์‹œ์ž‘.

    struct dma_page (ํŽ˜์ด์ง€ ๊ด€๋ฆฌ ๊ตฌ์กฐ์ฒด)

    // mm/dmapool.c:64-68
    struct dma_page {            /* 'allocation' ๋ฐ”์ดํŠธ์งœ๋ฆฌ ์บ์‹œ ๊ฐ€๋Šฅํ•œ ํ—ค๋” */
    struct list_head page_list; /* pool->page_list์— ์—ฐ๊ฒฐ๋˜๋Š” ๋…ธ๋“œ */
    void *vaddr;                /* ์ฝ”์–ด CPU ๊ฐ€์ƒ ์ฃผ์†Œ */
    dma_addr_t dma;             /* DMA ์ฃผ์†Œ */
    };

    ์‹ค์ œ DMA ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ด€๋ฆฌ ํ—ค๋”. dma_alloc_coherent()๋กœ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์˜ vaddr๊ณผ dma ์ฃผ์†Œ๋ฅผ ๋ณด๊ด€.

    DMA Pool ์ž๋ฃŒ๊ตฌ์กฐ ๊ด€๊ณ„๋„

    ํ•ต์‹ฌ ํ•จ์ˆ˜

    1. dma_pool_create_node() โ€” ํ’€ ์ƒ์„ฑ

    // mm/dmapool.c:226-301
    struct dma_pool *dma_pool_create_node(const char *name, struct device *dev,
    size_t size, size_t align, size_t boundary, int node)

    ์—ญํ• : ์ง€์ •๋œ ํฌ๊ธฐ์˜ DMA coherent ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    ๋ถ„๊ธฐ ๋กœ์ง:

  • dev == NULL โ†’ NULL ๋ฐ˜ํ™˜
  • align์ด 0์ด๋ฉด 1๋กœ ์„ค์ •, 2์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ์ด ์•„๋‹ˆ๋ฉด NULL ๋ฐ˜ํ™˜
  • size == 0 ๋˜๋Š” size > INT_MAX โ†’ NULL ๋ฐ˜ํ™˜
  • size < sizeof(struct dma_block) โ†’ sizeof(struct dma_block)์œผ๋กœ ์ฆ๊ฐ€ (์˜ค๋ฒ„ํ—ค๋“œ ํ™•๋ณด)
  • size = ALIGN(size, align) ํ›„ allocation = max(size, PAGE_SIZE)
  • boundary == 0 โ†’ boundary = allocation (๊ฒฝ๊ณ„ ์ œ์•ฝ ์—†์Œ)
  • boundary < size ๋˜๋Š” ๋น„-2์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ โ†’ NULL ๋ฐ˜ํ™˜
  • ์žฅ์น˜์˜ ์ฒซ ๋ฒˆ์งธ ํ’€ ์ƒ์„ฑ ์‹œ device_create_file()๋กœ sysfs pools ํŒŒ์ผ ์ƒ์„ฑ
  • 2. dma_pool_alloc() โ€” ๋ธ”๋ก ํ• ๋‹น

    // mm/dmapool.c:407-441
    void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
    dma_addr_t *handle)

    ์—ญํ• : ํ’€์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ DMA ๋ธ”๋ก์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

    ๋ถ„๊ธฐ ๋กœ์ง:

    1. pool->lock ํš๋“ ํ›„ pool_block_pop()์œผ๋กœ free ๋ธ”๋ก ์‹œ๋„

    2. free ๋ธ”๋ก์ด ์—†์œผ๋ฉด:

    - pool->lock ํ•ด์ œ (์Šคํ•€๋ฝ ํ•˜์—์„œ sleep ๋ถˆ๊ฐ€)

    - pool_alloc_page()๋กœ ์ƒˆ ํŽ˜์ด์ง€ ํ• ๋‹น (dma_alloc_coherent())

    - pool->lock ์žฌํš๋“ ํ›„ pool_initialise_page()๋กœ ํŽ˜์ด์ง€๋ฅผ ๋ธ”๋ก์œผ๋กœ ๋ถ„ํ• 

    - ๋‹ค์‹œ pool_block_pop()์œผ๋กœ ๋ธ”๋ก ํ• ๋‹น

    3. *handle = block->dma (DMA ์ฃผ์†Œ ๋ฐ˜ํ™˜)

    4. DMAPOOL_DEBUG ํ™œ์„ฑํ™” ์‹œ pool_check_block()์œผ๋กœ ํ’ˆ์งˆ ๊ฒ€์ฆ

    3. dma_pool_free() โ€” ๋ธ”๋ก ํ•ด์ œ

    // mm/dmapool.c:453-465
    void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)

    ์—ญํ• : ํ• ๋‹น๋œ ๋ธ”๋ก์„ ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    ๋ถ„๊ธฐ ๋กœ์ง:

    1. pool->lock ํš๋“

    2. pool_block_err()๋กœ ์˜ค๋ฅ˜ ๊ฒ€์ฆ (์ž˜๋ชป๋œ DMA ์ฃผ์†Œ, ์ด๋ฏธ ํ•ด์ œ๋œ ๋ธ”๋ก ํ™•์ธ)

    3. ์˜ค๋ฅ˜ ์—†์œผ๋ฉด pool_block_push()๋กœ free ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€, nr_active--

    4. DMAPOOL_DEBUG ๋ฏธํ™œ์„ฑํ™” ์‹œ want_init_on_free()์ด๋ฉด 0์œผ๋กœ ์ดˆ๊ธฐํ™”

    4. dma_pool_destroy() โ€” ํ’€ ํŒŒ๊ดด

    // mm/dmapool.c:363-395
    void dma_pool_destroy(struct dma_pool *pool)

    ์—ญํ• : ํ’€์„ ์™„์ „ํžˆ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

    ๋ถ„๊ธฐ ๋กœ์ง:

    1. pool == NULL โ†’ ์ฆ‰์‹œ ๋ฐ˜ํ™˜

    2. pools_lock ํ•˜์—์„œ dev->dma_pools์—์„œ ์ œ๊ฑฐ

    3. ์žฅ์น˜์— ๋” ์ด์ƒ ํ’€์ด ์—†์œผ๋ฉด sysfs pools ํŒŒ์ผ ์ œ๊ฑฐ

    4. nr_active > 0์ด๋ฉด busy ๊ฒฝ๊ณ  ์ถœ๋ ฅ, ์‹ค์ œ DMA ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋Š” ๊ฑด๋„ˆ๋œ€

    5. ๋ชจ๋“  dma_page์— ๋Œ€ํ•ด dma_free_coherent() ํ˜ธ์ถœ ํ›„ kfree

    6. dma_pool ์ž์ฒด kfree

    5. pool_initialise_page() โ€” ํŽ˜์ด์ง€ ๋ถ„ํ• 

    // mm/dmapool.c:303-335
    static void pool_initialise_page(struct dma_pool *pool, struct dma_page *page)

    ์—ญํ• : ํ• ๋‹น๋œ ํŽ˜์ด์ง€๋ฅผ boundary ๊ฒฝ๊ณ„๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋ธ”๋ก ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•ฉ๋‹ˆ๋‹ค.

    ๋ถ„๊ธฐ ๋กœ์ง:

  • offset + size > next_boundary โ†’ boundary ๊ฒฝ๊ณ„๋ฅผ ๊ฑด๋„ˆ๋œ€ (๋ธ”๋ก ๋ฐฐ์น˜ ์•ˆ ํ•จ)
  • ๊ทธ ์™ธ: ๋ธ”๋ก์„ ์—ฐ์†์œผ๋กœ ๋ฐฐ์น˜ํ•˜๊ณ  next_block ๋ฆฌ์ŠคํŠธ์— ์—ฐ๊ฒฐ
  • nr_blocks ์ฆ๊ฐ€
  • DMA Pool ํ˜ธ์ถœ ํ๋ฆ„

    ํ˜ธ์ถœ ํ๋ฆ„

    ๋“œ๋ผ์ด๋ฒ„
    โ”‚
    โ”œโ”€ dma_pool_create(name, dev, size, align, boundary)
    โ”‚    โ””โ”€ dma_pool_create_node(..., NUMA_NO_NODE)
    โ”‚         โ”œโ”€ kzalloc_node()              โ† dma_pool ๊ตฌ์กฐ์ฒด ํ• ๋‹น
    โ”‚         โ”œโ”€ INIT_LIST_HEAD(page_list)
    โ”‚         โ”œโ”€ list_add(pools, dev->dma_pools)
    โ”‚         โ””โ”€ device_create_file()        โ† sysfs pools ํŒŒ์ผ ์ƒ์„ฑ
    โ”‚
    โ”œโ”€ dma_pool_alloc(pool, GFP_KERNEL, &handle)
    โ”‚    โ”œโ”€ spin_lock_irqsave(pool->lock)
    โ”‚    โ”œโ”€ pool_block_pop(pool)             โ† free ๋ธ”๋ก ์žˆ์œผ๋ฉด ๋ฐ˜ํ™˜
    โ”‚    โ”‚    โ””โ”€ (์—†์œผ๋ฉด)
    โ”‚    โ”œโ”€ spin_unlock_irqrestore(pool->lock)
    โ”‚    โ”œโ”€ pool_alloc_page(pool, mem_flags)
    โ”‚    โ”‚    โ”œโ”€ kmalloc_node()              โ† dma_page ๊ตฌ์กฐ์ฒด ํ• ๋‹น
    โ”‚    โ”‚    โ””โ”€ dma_alloc_coherent()        โ† ์‹ค์ œ DMA ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น
    โ”‚    โ”œโ”€ spin_lock_irqsave(pool->lock)
    โ”‚    โ”œโ”€ pool_initialise_page(pool, page) โ† ํŽ˜์ด์ง€๋ฅผ ๋ธ”๋ก์œผ๋กœ ๋ถ„ํ• 
    โ”‚    โ”‚    โ””โ”€ ๋ฐ˜๋ณต: block = page->vaddr + offset
    โ”‚    โ”œโ”€ pool_block_pop(pool)             โ† ์ƒˆ ๋ธ”๋ก ํ• ๋‹น
    โ”‚    โ””โ”€ spin_unlock_irqrestore(pool->lock)
    โ”‚
    โ”œโ”€ dma_pool_free(pool, vaddr, dma)
    โ”‚    โ”œโ”€ spin_lock_irqsave(pool->lock)
    โ”‚    โ”œโ”€ pool_block_err(pool, vaddr, dma) โ† ์˜ค๋ฅ˜ ๊ฒ€์ฆ
    โ”‚    โ”œโ”€ pool_block_push(pool, block, dma) โ† free ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€
    โ”‚    โ””โ”€ spin_unlock_irqrestore(pool->lock)
    โ”‚
    โ””โ”€ dma_pool_destroy(pool)
    โ”œโ”€ list_del(pools, dev->dma_pools)
    โ”œโ”€ device_remove_file()             โ† sysfs pools ํŒŒ์ผ ์ œ๊ฑฐ
    โ”œโ”€ (busy๊ฐ€ ์•„๋‹ˆ๋ฉด) dma_free_coherent() ๋ฐ˜๋ณต
    โ”œโ”€ kfree(page) ๋ฐ˜๋ณต
    โ””โ”€ kfree(pool)

    ์กฐ๊ฑด๋ณ„ ๋น„๊ต

    DMA Pool API ๋น„๊ต

    APINUMA ์ง€์›๊ด€๋ฆฌ ๋ฐฉ์‹์ฃผ์š” ์‚ฌ์šฉ์ฒ˜
    `dma_pool_create()`โŒ (NUMA_NO_NODE)์ˆ˜๋™ ์ƒ์„ฑ/ํŒŒ๊ดด์ผ๋ฐ˜ ๋“œ๋ผ์ด๋ฒ„
    `dma_pool_create_node()`โœ… (node ํŒŒ๋ผ๋ฏธํ„ฐ)์ˆ˜๋™ ์ƒ์„ฑ/ํŒŒ๊ดดNUMA ์ธ์‹ ๋“œ๋ผ์ด๋ฒ„
    `dmam_pool_create()`โŒ์ž๋™ ํ•ด์ œ (devres)๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๋“œ๋ผ์ด๋ฒ„

    DMA ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ฐฉ์‹ ๋น„๊ต

    ๋ฐฉ์‹ํฌ๊ธฐ ๋‹จ์œ„์˜ค๋ฒ„ํ—ค๋“œ์žฌ์‚ฌ์šฉ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค
    `dma_alloc_coherent()`ํŽ˜์ด์ง€ ๋‹จ์œ„์—†์Œ์—†์Œ๋Œ€ํ˜• DMA ๋ฒ„ํผ
    DMA Pool๊ณ ์ • ํฌ๊ธฐ ๋ธ”๋ก`sizeof(dma_block)`โœ…์ž‘๊ณ  ๋ฐ˜๋ณต์ ์ธ DMA ํ• ๋‹น
    `dma_alloc_pages()`ํŽ˜์ด์ง€ ๋‹จ์œ„์—†์Œ์—†์ŒSG DMA
    vmalloc์ž„์˜ ํฌ๊ธฐํŽ˜์ด์ง€ ํ…Œ์ด๋ธ”์—†์Œ์ปค๋„ ๋‚ด๋ถ€ ์‚ฌ์šฉ

    boundary ์„ค์ • ๋™์ž‘ ๋น„๊ต

    boundary ๊ฐ’๋ธ”๋ก ๋ฐฐ์น˜ ๊ทœ์น™์˜ˆ์‹œ
    0 (๋ฏธ์ง€์ •)allocation ๋‹จ์œ„๋กœ ์ž์œ ๋กญ๊ฒŒ ๋ฐฐ์น˜๊ธฐ๋ณธ ๋™์ž‘
    40964KB ๊ฒฝ๊ณ„๋ฅผ ๋„˜์ง€ ์•Š์ŒxHCI HCI command ring
    6553664KB ๊ฒฝ๊ณ„๋ฅผ ๋„˜์ง€ ์•Š์Œ๊ณ ์„ฑ๋Šฅ NIC descriptor ring

    DMAPOOL_DEBUG ๋™์ž‘ ๋น„๊ต

    ์กฐ๊ฑดํ• ๋‹น ์‹œํ•ด์ œ ์‹œํŽ˜์ด์ง€ ์ดˆ๊ธฐํ™”
    DMAPOOL_DEBUG ON`POOL_POISON_ALLOCATED`๋กœ ๋ฎ์–ด์“ฐ๊ธฐ`POOL_POISON_FREED` ๊ฒ€์ฆ + ๋ฎ์–ด์“ฐ๊ธฐ`POOL_POISON_FREED`๋กœ ์ดˆ๊ธฐํ™”
    DMAPOOL_DEBUG OFF`want_init_on_alloc`์ด๋ฉด 0 ์ดˆ๊ธฐํ™”`want_init_on_free`์ด๋ฉด 0 ์ดˆ๊ธฐํ™”์—†์Œ

    ๊ด€๋ จ ๋ฌธ์„œ

  • ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ฐœ์š”
  • Buddy Allocator
  • SLUB ํ• ๋‹น์ž
  • vmalloc
  • CMA
  • HugeTLB
  • Per-CPU ๋ฉ”๋ชจ๋ฆฌ