zoukankan      html  css  js  c++  java
  • 内存页分配/释放

    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 */
    }
  • 相关阅读:
    Sbt 配置国内镜像
    spark sql 之 RDD与DataFrame互相转化
    Base64编码和解码工具
    BDB数据库操作工具化
    String、StringBuffer、StringBuilder三者的区别
    常见的数组排序方法
    drop,delete,truncate 三者的异同点
    redis 常用命令
    git shell应用
    机器学习入门之路
  • 原文地址:https://www.cnblogs.com/sunnycindy/p/9099703.html
Copyright © 2011-2022 走看看