内存页分配/释放

Posted jingmojing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存页分配/释放相关的知识,希望对你有一定的参考价值。

page alloc/free

create_empty_buffers
├─ alloc_page_buffers => alloc_buffer_head 
│ └─ kmem_cache_alloc
└─ attach_page_buffers
   ├─ get_page
   ├─ SetPagePrivate 
   └─ set_page_private

try_to_release_page
└─ try_to_free_buffers
   ├─ drop_buffers
   │ └─ __clear_page_buffers
   │    ├─ ClearPagePrivate
   │    ├─ set_page_private
   │    └─ put_page
   └─ free_buffer_head

kswapd  /* The background pageout daemon, started as a kernel thread from the init process. */
└─ balance_pgdat /* reclaim pages */
   └─ kswapd_shrink_node => shrink_node => shrink_node_memcg
      └─ shrink_inactive_list => shrink_page_list
         └─ try_to_release_page

kmem_cache_alloc
└─ ___slab_alloc => new_slab
   └─ __alloc_pages_nodemask
      ├─ get_page_from_freelist /* If fail, it will __alloc_pages_slowpath */
      └─ __alloc_pages_slowpath 
         └─__alloc_pages_direct_reclaim => __perform_reclaim
            └─ try_to_free_pages
               └─ shrink_node

 

struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,
        int retry)
{
    struct buffer_head *bh, *head;
    long offset;

try_again:
    head = NULL;
    offset = PAGE_SIZE;
    while ((offset -= size) >= 0) {
        bh = alloc_buffer_head(GFP_NOFS);
        if (!bh)
            goto no_grow;

        bh->b_this_page = head; /* circular list of page\'s buffers */
        bh->b_blocknr = -1;
        head = bh;

        bh->b_size = size; /* for ntfs/fat, it is the sector size */

        /* Link the buffer to its page */
        set_bh_page(bh, page, offset);
    }
    return head;
/*
 * In case anything failed, we just free everything we got.
 */
no_grow:
......
}

void set_bh_page(struct buffer_head *bh,
        struct page *page, unsigned long offset)
{
    bh->b_page = page; /* the page this bh is mapped to */
    BUG_ON(offset >= PAGE_SIZE);
    if (PageHighMem(page))
        /*
         * This catches illegal uses and preserves the offset:
         */
        bh->b_data = (char *)(0 + offset);
    else
        bh->b_data = page_address(page) + offset; /* pointer to data within the page */
}

 

以上是关于内存页分配/释放的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式linux,dma_alloc_coherent再释放再申请多次偶会出现页分配失败,有啥办

linux采用啥方法实现内存的分配和释放

Linux内核态动态内存分配与释放

Linux 内核 内存管理物理页释放 ( 物理页释放 __free_pages 函数 )

动态内存分配php

分配内存页和页表的算法