Linux内核伙伴系统中页面释放,主函数为free_pages()

一、上层操作

void free_pages(unsigned long addr, unsigned int order){if (addr != 0) {VM_BUG_ON(!virt_addr_valid((void *)addr));__free_pages(virt_to_page((void *)addr), order);}}

void __free_pages(struct page *page, unsigned int order){if (put_page_testzero(page)) {trace_mm_page_free_direct(page, order);if (order == 0)free_hot_page(page);else__free_pages_ok(page, order);}}

二、释放单个页面

释放单个页面free_hot_page()调用free_hot_cold_page()函数

static void free_hot_cold_page(struct page *page, int cold){struct zone *zone = page_zone(page);struct per_cpu_pages *pcp;unsigned long flags;int migratetype;int wasMlocked = __TestClearPageMlocked(page);kmemcheck_free_shadow(page, 0);if (PageAnon(page))page->mapping = NULL;if (free_pages_check(page))return;if (!PageHighMem(page)) {debug_check_no_locks_freed(page_address(page), PAGE_SIZE);debug_check_no_obj_freed(page_address(page), PAGE_SIZE);}arch_free_page(page, 0);kernel_map_pages(page, 1, 0);pcp = &zone_pcp(zone, get_cpu())->pcp;migratetype = get_pageblock_migratetype(page);set_page_private(page, migratetype);local_irq_save(flags);if (unlikely(wasMlocked))free_page_mlock(page);__count_vm_event(PGFREE);if (migratetype >= MIGRATE_PCPTYPES) {if (unlikely(migratetype == MIGRATE_ISOLATE)) {free_one_page(zone, page, 0, migratetype);goto out;}migratetype = MIGRATE_MOVABLE;}if (cold)list_add_tail(&page->lru, &pcp->lists[migratetype]);elselist_add(&page->lru, &pcp->lists[migratetype]);pcp->count++;if (pcp->count >= pcp->high) {free_pcppages_bulk(zone, pcp->batch, pcp);pcp->count -= pcp->batch;}out:local_irq_restore(flags);put_cpu();}

从pcp中释放页面到伙伴系统中

free_pcppages_bulk()

are in same zone, and of same order. * count is the number of pages to free. * * If the zone was previously in an "all pages pinned" state then look to * see if this freeing clears that state. * * And clear the zone's pages_scanned counter, to hold off the "all pages are * pinned" detection logic. */ static void free_pcppages_bulk(struct zone *zone, int count,struct per_cpu_pages *pcp){int migratetype = 0;int batch_free = 0;spin_lock(&zone->lock);zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);zone->pages_scanned = 0;__mod_zone_page_state(zone, NR_FREE_PAGES, count);while (count) {struct page *page;struct list_head *list;do {batch_free++;if (++migratetype == MIGRATE_PCPTYPES)migratetype = 0;list = &pcp->lists[migratetype];} while (list_empty(list));do {page = list_entry(list->prev, struct page, lru);list_del(&page->lru);__free_one_page(page, zone, 0, migratetype);trace_mm_page_pcpu_drain(page, 0, migratetype);} while (--count && --batch_free && !list_empty(list));}spin_unlock(&zone->lock);}

三、释放多个页面

释放多个页面__free_pages_ok()函数

int i;int bad = 0;int wasMlocked = __TestClearPageMlocked(page);kmemcheck_free_shadow(page, order);for (i = 0 ; i < (1 << order) ; ++i)bad += free_pages_check(page + i);if (bad)return;if (!PageHighMem(page)) {debug_check_no_locks_freed(page_address(page),PAGE_SIZE<

static void free_one_page(struct zone *zone, struct page *page, int order,int migratetype){spin_lock(&zone->lock);zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);zone->pages_scanned = 0;__mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);__free_one_page(page, zone, order, migratetype);spin_unlock(&zone->lock);}

etype){unsigned long page_idx;if (unlikely(PageCompound(page)))if (unlikely(destroy_compound_page(page, order)))return;VM_BUG_ON(migratetype == -1);page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1); VM_BUG_ON(page_idx & ((1 << order) - 1)); VM_BUG_ON(bad_range(zone, page));while (order < MAX_ORDER-1) {unsigned long combined_idx;struct page *buddy;buddy = __page_find_buddy(page, page_idx, order);if (!page_is_buddy(page, buddy, order))break;list_del(&buddy->lru);zone->free_area[order].nr_free--; rmv_page_order(buddy);combined_idx = __find_combined_index(page_idx, order);page = page + (combined_idx - page_idx);page_idx = combined_idx;order++;}set_page_order(page, order);list_add(&page->lru,&zone->free_area[order].free_list[migratetype]);zone->free_area[order].nr_free++;}

四、关于伙伴的操作

4.1,查找伙伴

static inline struct page *__page_find_buddy(struct page *page, unsigned long page_idx, unsigned int order){unsigned long buddy_idx = page_idx ^ (1 << order);return page + (buddy_idx - page_idx);}

4.2,检查是否为伙伴

static inline int page_is_buddy(struct page *page, struct page *buddy,int order){if (!pfn_valid_within(page_to_pfn(buddy)))return 0;if (page_zone_id(page) != page_zone_id(buddy))return 0;if (PageBuddy(buddy) && page_order(buddy) == order) {VM_BUG_ON(page_count(buddy) != 0);return 1;}return 0;}

总结:伙伴系统内存释放或称主要流程

1,如果释放的是单个页面,需要根据页面类型考虑是否释放到伙伴系统中,同时,将其加入到pcp链表中。如果pcp链表中内存过多,调用free_pcppages_bulk()函数将大块内存放回伙伴系统中;

2,如果释放的是多个页面,直接调用__free_one_page()释放到伙伴系统中。

3,释放到伙伴系统中时,需要考虑和伙伴的合并情况。

linux内存系统管理,Linux内存管理之伙伴系统(内存释放)相关推荐

  1. Linux教程:内核怎样管理你的内存

    在分析了进程的虚拟地址布局,我们转向内核以及他管理用户内存的机制.下图是gonzo的例子: Linux进程在内核中是由task_struct进程描述符实现的,task_struct的mm字段指向内存描 ...

  2. linux内核内存slab,伙伴系统,内存碎片,内存耗尽(OOM)杀手,内存资源控制器memcg,KASAN学习笔记

    目录 1 基础知识 1.1 页 1.2 页表 1.3 UMA(一致性访问) / NUMA(非一致性访问) 1.4 高端内存和低端内存 1.5 内存模型 2 物理内存的管理 2.1 物理内存的组织:节点 ...

  3. linux 进程slab,Linux内存管理之slab slab是什么

    一:准备知识: 前面我们分析过了大内存分配的实现机制,事实上,若为小块内存而请求整个页面,这样对于内存来说是一种极度的浪费.因此linux采用了slab来管理小块内存的分配与释放.Slab最早是由su ...

  4. Linux内存管理、伙伴系统(buddy system)等知识点

    引入 之前写过一篇文章将伙伴系统,可以参考:内存池算法简介 物理内存由页分配器(page allocator)接管. 内存块的申请.释放过程. 伙伴算法.阶数. 2^0 为1 ,链表上存放的是一个pa ...

  5. (转)linux内存管理之伙伴系统(内存分配)

     一.Linux伙伴系统分配器 伙伴系统分配器大体上分为两类.__get_free_pages()类函数返回分配的第一个页面的线性地址:alloc_pages()类函数返回页面描述符地址.不管以哪种函 ...

  6. Linux 进程资源分配,linux 进程管理和内存分配

    1.进程相关概念 进程:正在运行中的程序 内核功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能等 Process:运行中的程序的一个副本,是被载入内存的一个指令集合 进程 ID(Pro ...

  7. alloc_page分配内存空间--Linux内存管理(十七)

    1 前景回顾 在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担. 伙伴系统基于一种相对简单然而令人吃惊的强大算法. Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Know ...

  8. 一步一步学linux操作系统: 21 内存管理_小内存分配与页面换出

    slub 分配器工作原理 相关函数与结构体 进程创建的do_fork中会调用copy_process函数,这个函数会调用 dup_task_struct 函数 \linux-4.13.16\kerne ...

  9. linux内存管理子系统采用基于内存区域,Linux 内存管理之highmem简介

    一.Linux内核地址空间 一般来说Linux 内核按照 3:1 的比率来划分虚拟内存(X86等):3 GB 的虚拟内存用于用户空间,1GB 的内存用于内核空间.当然有些体系结构如MIPS使用2:2 ...

最新文章

  1. 如何管理项目中外包开发人员、测试人员
  2. shell脚本编程之使用结构化命令
  3. 从城市大脑到世界数字大脑 构建人类协同发展的超级智能平台
  4. iptables规则的查看、添加、插入、删除和修改
  5. rhel iptables只允许限定IP访问某端口、某特定网站
  6. php上传大文件500错误,PHP fastcgi模式大文件上传500错误
  7. poj1013 Counterfeit Dollar
  8. 17-Spring持久层框架整合
  9. HTML学生个人网站作业设计——HTML+CSS+JavaScript简单的大学生书店网页制作(13页) web期末作业设计网页 web结课作业的源码 web网页设计实例作业
  10. 下一跳配置的原则--ensp
  11. LaTeX:使用bib插入文献
  12. 探索性因子分析法问答
  13. Paper reading (九十):Can Gut Microbiota Composition Predict Response to Dietary Treatments
  14. 【MySQL】MySQL 存储引擎、索引、锁、集群
  15. VScode使用指南之如何全屏和退出全屏(1)
  16. vue实现网页中英文切换
  17. 基于C++实现的药品销售管理系统
  18. 那些提升开发人员工作效率的在线工具
  19. carlife Android版本,carlife车机端app下载-百度carlife车机端官网app下载安卓版 v5.4.2-友情手机站...
  20. 葡萄酒产业成就迪庆雪域高原“紫色传奇”

热门文章

  1. 未来CPU内核将更简单!
  2. python没有英文基础能学吗-初中毕业没有英语基础能学编程吗?该学C或者Python?...
  3. python画散点图程序-Python散点图与折线图绘制过程解析
  4. python3.8.2安装教程-在服务器上安装python3.8.2环境
  5. python的工作方向-python职业发展方向有哪些,各有什么优劣?
  6. python怎么知道用哪个库使用-dir、help 查看python 库 对应的方法 和使用
  7. 转行学python后悔了-转行学Python可以吗?
  8. python第三方库numpy-Python三方库:Numpy(数组处理)
  9. python官网 中文版 新闻-他说,懂中文就能学会Python,但需要这个工具
  10. 精通python设计模式-Python设计模式