expand 伙伴系统中块的碎裂

来源:互联网 发布:中日韩长相知乎 编辑:程序博客网 时间:2024/06/02 08:20

 

/*简单来说就是如果小块没空间了,就从大块上分配,然后把大块碎裂为n个小块。

    然后把其余的小块放到相应分配阶的free_area中。

    参数的含义如下:

    zone:  管理区

    page:  要归还内存的起始内框page

    index: 在管理区中的序号

    low:    欲分配的内框大小

    high:   已经分配的内框大小

    area:   空闲区

*/

static inline struct page *

expand(struct zone *zone, struct page *page,

          unsigned long index, int low, int high, struct free_area *area)

{

         //求得总的内框个数

         unsigned long size = 1 << high;

 

         while (high > low) {

                   area--;

                   high--;

                   size >>= 1;

                   BUG_ON(bad_range(zone, &page[size]));

                    /*

                        page[size]:参数传进来的是page*,对于连续为2的high阶的页来说,这也可以看作是元素为page的数组指针

                         size是1<<high 然后>>1,就是说这个page的数组原来有2^high个元素,page[size]指向第2^high/2个元素,即指向了数组的

                        中间元素。

                        这里还要留意分裂后的页是如何并入到下一个分配阶的frea_area中的。是将这个page数组中高的那一半的第一个页(

                        即page[size])的lru指针加入到area->free_list[]队列中。

                     */

                   list_add(&page[size].lru, &area->free_list);

                   //更正空闲区的页框位图      

         //1

                   MARK_USED(index + size, high, area);

         }

         return page;

}

 

1 在书中,该处还有两个操作,一个是将area->nr_free++,一个是set_page_order(&page[size],high);

   这里可以看出来,我们分配一个N阶的连续页,所得到的只是该连续页中第一个页的指针,即该连续页的

   指针,一个指针指向的是多少阶的连续页是通过p[0]->private来指示的。


联想:借此复习一下空闲列表的初始化过程:zone_init_free_lists

static void __meminit zone_init_free_lists(struct zone *zone)
{
    int order, t;
    for_each_migratetype_order(order, t) {
        INIT_LIST_HEAD(&zone->free_area[order].free_list[t]);//free_list是队列头,将指向某个页的lru。
        zone->free_area[order].nr_free = 0;

    }
}

原创粉丝点击