本文共 2046 字,大约阅读时间需要 6 分钟。
void __free_pages(struct page *page, unsigned int order)用于释放从page开始个数为2的order次方的页面其源码分析如下:void __free_pages(struct page *page, unsigned int order){ #首先通过put_page_teszero来看page的usage count 是否为0 #是0的话,才能表示这个page没有人使用,可以释放了. if (put_page_testzero(page)) { #根据order 是否为0,分两种路径来释放内存 if (order == 0) free_unref_page(page); else #这个函数会将page 代表的内存是放到伙伴系统中 __free_pages_ok(page, order); }}我们重点看看order等于0时候/* * Free a 0-order page */void free_unref_page(struct page *page){ unsigned long flags; #根据page得到pfn unsigned long pfn = page_to_pfn(page); if (!free_unref_page_prepare(page, pfn)) return; local_irq_save(flags); #将page释放到pcp中,这里pcp的意思是per_cpu_pages,也就是单页的话,不会是放到伙伴系统 #而是交给个个cpu自己管理 free_unref_page_commit(page, pfn); local_irq_restore(flags);}static void free_unref_page_commit(struct page *page, unsigned long pfn){ #得到这个page所在的zone struct zone *zone = page_zone(page); struct per_cpu_pages *pcp; int migratetype; #拿到这个页的迁移类型 migratetype = get_pcppage_migratetype(page); #计算vm中free page的个数 __count_vm_event(PGFREE); /* * We only track unmovable, reclaimable and movable on pcp lists. * Free ISOLATE pages back to the allocator because they are being * offlined but treat HIGHATOMIC as movable pages so we can get those * areas back if necessary. Otherwise, we may have to free * excessively into the page allocator */ #如果迁移类型大于等于MIGRATE_PCPTYPES,则将迁移类型设置为MIGRATE_MOVABLE if (migratetype >= MIGRATE_PCPTYPES) { if (unlikely(is_migrate_isolate(migratetype))) { free_one_page(zone, page, pfn, 0, migratetype); return; } migratetype = MIGRATE_MOVABLE; } #得到当前cpu的pcp的指针 pcp = &this_cpu_ptr(zone->pageset)->pcp; #pcp 中的页也是按照迁移类型组成不同的list。所以这里按照迁移类型将页加入到pcp不同的list中 list_add(&page->lru, &pcp->lists[migratetype]); #增加pcp中总的free page的计数 pcp->count++; #pcp中存储的页的个数有个阈值,高于这个阈值的话,则会将多余的页释放到伙伴系统中 if (pcp->count >= pcp->high) { #得到要释放到伙伴系统中页的个数 unsigned long batch = READ_ONCE(pcp->batch); #释放单页到伙伴系统,这里不能通过调用__free_pages 来释放单页,因为__free_pages #中会把单页释放到pcp中,造成这里的递归调用 free_pcppages_bulk(zone, batch, pcp); pcp->count -= batch; }}
转载地址:http://lgjmi.baihongyu.com/