Buddy_Zhang1 发表于 2016-03-09 11:52

struct page 的 lru 成员适用场景分析[不断更新]

本帖最后由 Buddy_Zhang1 于 2016-03-09 15:28 编辑

   简单的说 struct page 的 lru 成员就是负责被各个内存分配器管理.
   1. 假如这个 struct page 属于 Buddy System,那么内核通过将该 struct page 的 lru 加入到对应的 free_area 链表上,可以参照下面代码;
            struct page *page;/* Page 已知 */
            struct zone *zone;
            int migratetype;
            int order;

            zone = page_zone(page);
            migratetype = get_pageblock_migratetype(page);
            order = page_order(page);

            list_add(&page->lru,
                  &zone->free_area.free_list);   /* page 所属的 free_list */
      2. 假如这个 struct page 属于 PCP(per_cpu_pages) 分配器,也就是 hot 或 cold 页.那么这个 struct page 的 lru 就会加入到 PCP 的 冷热页链表中.
          如果这个页是刚刚释放就作为 hot 页加入链表头,如果这个页是冷页,也就是 struct page 的 flags 中函数 __GFP_COLD 标志,该页就被加入到链表尾部.可参照下面代码.
         struct page *page; /* 已知 */
         struct zone *zone;
         struct per_cpu_pages *pcp;
         int migratetype;
         int cold = 0; /* 如果这个页属于 hot 页 cold 为0,如果这个页属于 cold 页那么 cold 为 1*/

         zone = page_zone(page);
         migratetype = get_pageblock_migratetype(page);
         pcp = &zone->pageset->pcp;

         if(cold)
                list_add_tail(&page->lru,&pcp->lists);
         else
                list_add(&page->lru,&pcp->lists);
         pcp->count++;

       3. 如果这个 struct page 属于 SLUB 分配器,那么 struct page 的 lru 就会被加入到 struct kmem_cache->node.partial 链表里面.
         作为一个 slab page,被 struct kmem_cache 管理起来.可以参照如下代码:
            struct page *page = alloc_page(page);
            struct kmem_cache *cache;

             cache = kmem_cache_create("Buddy",8,8,0,NULL);

             list_add(&page->lru,&cache->node.partial);

{:yxh45:}

nswcfd 发表于 2016-03-09 15:32

是的,同样的list_head,在page的不同生命周期里,被挂到了不同含义的链表里,相当于一个union,只是lru这个名字有点误导性。:lol
页: [1]
查看完整版本: struct page 的 lru 成员适用场景分析[不断更新]