Welcome 微信登录

首页 / 操作系统 / Linux / Linux内存管理之伙伴系统(内存释放)

Linux内核伙伴系统中页面释放,主函数为free_pages()一、上层操作
  1. /*用虚拟地址进行释放*/  
  2. void free_pages(unsigned long addr, unsigned int order)  
  3. {  
  4.     if (addr != 0) {  
  5.         VM_BUG_ON(!virt_addr_valid((void *)addr));  
  6.         __free_pages(virt_to_page((void *)addr), order);/*具体的释放函数*/  
  7.     }  
  8. }  
 
  1. /*释放页面*/  
  2. void __free_pages(struct page *page, unsigned int order)  
  3. {  
  4.     if (put_page_testzero(page)) {/*count值减一为0时释放*/  
  5.         /*调试*/  
  6.         trace_mm_page_free_direct(page, order);  
  7.         if (order == 0)  
  8.             free_hot_page(page);/*释放单个页面*/  
  9.         else  
  10.             __free_pages_ok(page, order);  
  11.     }  
  12. }  
二、释放单个页面释放单个页面free_hot_page()调用free_hot_cold_page()函数
  1. static void free_hot_cold_page(struct page *page, int cold)  
  2. {  
  3.     struct zone *zone = page_zone(page);  
  4.     struct per_cpu_pages *pcp;  
  5.     unsigned long flags;  
  6.     int migratetype;  
  7.     int wasMlocked = __TestClearPageMlocked(page);  
  8.     /*调试代码*/  
  9.     kmemcheck_free_shadow(page, 0);  
  10.   
  11.     if (PageAnon(page))  
  12.         page->mapping = NULL;  
  13.     if (free_pages_check(page))  
  14.         return;  
  15.   
  16.     if (!PageHighMem(page)) {  
  17.         debug_check_no_locks_freed(page_address(page), PAGE_SIZE);  
  18.         debug_check_no_obj_freed(page_address(page), PAGE_SIZE);  
  19.     }  
  20.     /*x86下为空*/  
  21.     arch_free_page(page, 0);  
  22.     /*调试用*/  
  23.     kernel_map_pages(page, 1, 0);  
  24.     /*获得zone对应cpu的pcp*/  
  25.     pcp = &zone_pcp(zone, get_cpu())->pcp;  
  26.     /*获得页面的migratetype*/  
  27.     migratetype = get_pageblock_migratetype(page);  
  28.     set_page_private(page, migratetype);/*设置私有位为参数*/  
  29.     local_irq_save(flags);/*保存中断*/  
  30.     if (unlikely(wasMlocked))  
  31.         free_page_mlock(page);  
  32.     __count_vm_event(PGFREE);  
  33.   
  34.     /* 
  35.      * We only track unmovable, reclaimable and movable on pcp lists. 
  36.      * Free ISOLATE pages back to the allocator because they are being 
  37.      * offlined but treat RESERVE as movable pages so we can get those 
  38.      * areas back if necessary. Otherwise, we may have to free 
  39.      * excessively into the page allocator 
  40.      */  
  41.     if (migratetype >= MIGRATE_PCPTYPES) {  
  42.         if (unlikely(migratetype == MIGRATE_ISOLATE)) {  
  43.             /*释放到伙伴系统 */  
  44.             free_one_page(zone, page, 0, migratetype);  
  45.             goto out;  
  46.         }  
  47.         migratetype = MIGRATE_MOVABLE;  
  48.     }  
  49.   
  50.     if (cold)/*加入到pcp链表尾部*/  
  51.         list_add_tail(&page->lru, &pcp->lists[migratetype]);  
  52.     else/*加入到pcp链表头部*/  
  53.         list_add(&page->lru, &pcp->lists[migratetype]);  
  54.     pcp->count++;/*pcp计数加一*/  
  55.     if (pcp->count >= pcp->high) {/*当pcp中页面数量超过他的最高值时, 
  56.         释放pcp->batch个页面到伙伴系统中*/  
  57.         free_pcppages_bulk(zone, pcp->batch, pcp);  
  58.         pcp->count -= pcp->batch;/*页面数减去释放的页面数量*/  
  59.     }  
  60.   
  61. out:  
  62.     local_irq_restore(flags);/*回复中断*/  
  63.     put_cpu();  
  64. }  
从pcp中释放页面到伙伴系统中free_pcppages_bulk()
  1. are in same zone, and of same order.  
  2.  * count is the number of pages to free.  
  3.  *  
  4.  * If the zone was previously in an "all pages pinned" state then look to  
  5.  * see if this freeing clears that state.  
  6.  *  
  7.  * And clear the zone"s pages_scanned counter, to hold off the "all pages are  
  8.  * pinned" detection logic.  
  9.  */  
  10.  /*从PCP中释放count个页面到伙伴系统中*/  
  11. static void free_pcppages_bulk(struct zone *zone, int count,  
  12.                     struct per_cpu_pages *pcp)  
  13. {  
  14.     int migratetype = 0;  
  15.     int batch_free = 0;  
  16.     /* 
  17.      * 虽然管理区可以按照CPU节点分类,但是也可以跨CPU节点进行内存分配, 
  18.      * 因此这里需要用自旋锁保护管理区  
  19.      * 使用每CPU缓存的目的,也是为了减少使用这把锁。 
  20.      */  
  21.     spin_lock(&zone->lock);  
  22.     /* all_unreclaimable代表了内存紧张程度,释放内存后,将此标志清除 */  
  23.     zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);  
  24.     zone->pages_scanned = 0;/* pages_scanned代表最后一次内存紧张以来,页面回收过程已经扫描的页数。 
  25.     目前正在释放内存,将此清0,待回收过程随后回收时重新计数 */  
  26.   
  27.     /*增加管理区空闲页数*/  
  28.     __mod_zone_page_state(zone, NR_FREE_PAGES, count);  
  29.     while (count) {  
  30.         struct page *page;  
  31.         struct list_head *list;  
  32.   
  33.         /* 
  34.          * Remove pages from lists in a round-robin fashion. A 
  35.          * batch_free count is maintained that is incremented when an 
  36.          * empty list is encountered.  This is so more pages are freed 
  37.          * off fuller lists instead of spinning excessively around empty 
  38.          * lists 
  39.          */  
  40.         do {/*从pcp的三类链表中找出不空的一个,释放*/  
  41.             batch_free++;/*参看英文注释*/  
  42.             if (++migratetype == MIGRATE_PCPTYPES)  
  43.                 migratetype = 0;  
  44.             list = &pcp->lists[migratetype];  
  45.         } while (list_empty(list));  
  46.   
  47.         do {  
  48.             page = list_entry(list->prev, struct page, lru);  
  49.             /* must delete as __free_one_page list manipulates */  
  50.             list_del(&page->lru);  
  51.             /*释放单个页面到伙伴系统,注意这里的分类回收*/  
  52.             __free_one_page(page, zone, 0, migratetype);  
  53.             trace_mm_page_pcpu_drain(page, 0, migratetype);  
  54.         } while (--count && --batch_free && !list_empty(list));  
  55.     }  
  56.     spin_unlock(&zone->lock);  
  57. }  
  • 1
  • 2
  • 下一页
64位 CentOS 5.6 中 rrdtool 的编译安装Linux内存管理之伙伴系统(内存分配)相关资讯      Linux内存 
  • Linux内存管理精述  (01月18日)
  • 在 Linux x86-32 模式下分析内存映  (02/08/2015 07:25:25)
  • Linux下如何释放cache内存  (02/02/2015 13:36:34)
  • 在 Linux x86-64 模式下分析内存映  (02/08/2015 07:33:09)
  • Linux系统入门学习:如何检查Linux  (02/06/2015 10:36:00)
  • Linux内存映射  (04/04/2014 13:21:48)
本文评论 查看全部评论 (0)
表情: 姓名: 字数