博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OK6410A 开发板 (八) 40 linux-5.11 OK6410A buddy 的 alloc 和 free
阅读量:4285 次
发布时间:2019-05-27

本文共 4135 字,大约阅读时间需要 13 分钟。

第三阶段建立的是 buddy
  • buddy 的使用期限
mm_init->mem_init返回 - 无结束点
  • buddy 管理的内存大小
buddy 管理的内存 是 memblock 决定的属于 memblock.memory 中 但不包括 memblock.reserved 的部分memblock 可以通过 memblock_alloc或memblock_reserve 来 预留内存

buddy 的使用方法

  • alloc
alloc_pages/alloc_page // 返回的是 struct pageget_zeroed_page 	// 返回的是虚拟地址__get_free_pages/__get_free_page // 返回的是虚拟地址get_dma_pages__get_free_pages	struct page *page = alloc_pages		alloc_pages_node			__alloc_pages_node				__alloc_pages					__alloc_pages_nodemask						struct page * page = get_page_from_freelist	return (unsigned long) page_address(page);__alloc_pages_nodemask 的 具体细节	__alloc_pages_nodemask	  prepare_alloc_context   //1.准备参数	  get_page_from_freelist  //2.根据prepare_alloc_context 得到的参数 , 快路径尝试分配内存 	  __alloc_pages_slowpath  //3.如果快路径尝试分配内存失败,慢路径尝试分配内存		具体 查看 https://zhuanlan.zhihu.com/p/258921453	强烈推荐prepare_alloc_context   // 设置 get_page_from_freelist  函数的三个参数	1. struct alloc_context *ac		ac->migratetype = gfp_migratetype(gfp_mask); // 设置 需要的 迁移类型 , 与 zone->free_area[order].free_list[migratetype] 相关	2. gfp_t *alloc_mask		*alloc_mask |= __GFP_HARDWALL;	3. unsigned int *alloc_flags		*alloc_flags = current_alloc_flags(gfp_mask, *alloc_flags);get_page_from_freelist 	for_next_zone_zonelist_nodemask(zone, z, ac->highest_zoneidx, ac->nodemask) {
// 按照 ZONE_HIGHMEM ZONE_NORMAL ZONE_DMA 的优先级 遍历zone mark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK); // 获取当前水位线 if (!zone_watermark_fast(zone, order, mark, ac->highest_zoneidx, alloc_flags, gfp_mask)) {
// 与 alloc_pages 设置的 水位线FLAG 比较 // 此时进入 if 函数体 表示, 当前水位线 <= alloc_pages 设置的水位线FLAG,表示不能再分配物理页面 if (alloc_flags & ALLOC_NO_WATERMARKS) goto try_this_zone; // 表示 alloc_pages 设置的 水位线FLAG 表示 忽略 水位线,则直接到 try_this_zone 标号 直接 分配 页面 } try_this_zone: page = rmqueue(ac->preferred_zoneref->zone, zone, order, gfp_mask, alloc_flags, ac->migratetype); if (likely(order == 0)) rmqueue_pcplist(preferred_zone, zone, gfp_flags, migratetype, alloc_flags); // 查询 per_cpu_pages (pcp) 维护的 链表 是否可以满足内存申请 else __rmqueue(zone, order, migratetype, alloc_flags); // 从伙伴系统申请,查询的链表为 // zone->free_area[order].free_list[migratetype] __rmqueue_smallest(zone, order, migratetype); area = &(zone->free_area[current_order]); page = get_page_from_free_area(area, migratetype); del_page_from_free_list(page, zone, current_order); }__alloc_pages_slowpath 调用内存短缺的各种机制 ... relaim ... compact ... oom killer ... kswapd get_page_from_freelist(gfp_mask, order, alloc_flags, ac);
  • free
free_pages/free_page__free_pages/__free_pagefree_pages(unsigned long addr, unsigned int order)	__free_pages(virt_to_page((void *)addr), order);		free_the_page(page, order)			__free_pages_ok				free_one_page					__free_one_page						add_to_free_list(page, zone, order, migratetype);

其他

  • buddy 的 本质
buddy系统 只会维护空闲的块,已经分配出去的块不属于buddy系统对某一些块 调用 free_pages 后, 才会将其 放入 buddy 系统中---拆解&合并buddy的本质就是按照 2^n 拆解&合并
  • buddy 的问题及解决方案
// 有没有 存在的 虚拟内存 的问题1. 物理内存碎片问题	buddy 合并		时机: free_pages		方法:		线程:无	规整 compact		时机: alloc		方法:		线程: 1个线程 kcompactd02. 物理内存不足问题	回收 reclaim		时机: alloc内存紧缺时/周期/系统睡眠		方法:		线程: 2个线程 kswapd0 oom_reaper3. 无法申请到连续的物理页	CMA  contiguous memory allocator		时机: alloc连续内存时		方法: 			预留一段的内存给驱动使用,但当驱动不用的时候,CMA区域可以分配给用户进程用作匿名内存或者页缓存。			而当驱动需要使用时,就将进程占用的内存通过回收或者迁移的方式将之前占用的预留内存腾出来,供驱动使用。		线程: 无
---5. 如果 __GFP_DMA 被置位, 则 只能从 ZONE_DMA 内存管理区获取 page6. 如果 __GFP_HIGH 没被置位, 则 依次从  ZONE_NORMAL ZONE_DMA 内存管理区获取 page7. 如果 __GFP_HIGH 被置位, 则 依次从  ZONE_HIGHMEM ZONE_NORMAL ZONE_DMA 内存管理区获取 page---页框无限制,可存储任意数据x86硬件对页框有限制			导致新增ZONE(ZONE对页框分类)原来没有ZONE,或者只有一个ZONE 	: 		ZONE_NORMAL		16MB 	-	896MB1.DMA只能对RAM前16MB寻址		: 新增了 ZONE_DMA		0MB 	-	16MB2.32bit不能寻址所有的物理内存 	: 新增了 ZONE_HIGHMEM	896M 	- arm32呢???页框无限制,可存储任意数据arm32硬件对页框有限制			导致新增ZONE(ZONE对页框分类)原来没有ZONE,或者只有一个ZONE 	: 		ZONE_NORMAL		0MB 	-	760MB1.32bit不能寻址所有的物理内存 	: 新增了 ZONE_HIGHMEM	760MB 	-  ---现状没有配置CONFIG_ZONE_DMA CONFIG_ZONE_DMA32 CONFIG_HIGHMEM只有两个 ZONE : ZONE_NORMAL ZONE_MOVABLE---对于arm32来讲,什么时候需要配置 CONFIG_HIGHMEM?200MB 是不需要配置 CONFIG_HIGHMEM的1GB 是需要配置的,因为内核空间只有1G,memblock预留之后小于1G,不能完全映射---
  • S3C6410 的 DMA
6410 是 有 DMA 的源和目标 在 系统总线/外围总线 中(4种情况) 皆可用采用的是 ARM的 IP PL0804个DMA ,每个DMA 8个通道对内存没有限制

转载地址:http://yjigi.baihongyu.com/

你可能感兴趣的文章
git clean reset checkout
查看>>
[轉載]6個超強網站讓你查到最道地的英文
查看>>
HUB 與 Switch 差別
查看>>
linux產生 core dump文件方法及設置
查看>>
How to pass macro definition from “makefile” command line arguments to C source code?
查看>>
英文句型
查看>>
mtd and /dev/mtd*相關資料
查看>>
cp: cannot create symbolic link to fat format of usb: Operation not permitted
查看>>
MTD bad Block issue
查看>>
How to change network interface name
查看>>
ubifs and ubi and mtd
查看>>
shell script set 用法
查看>>
英文序數寫法與唸法 Ordinal Numbers(轉載)
查看>>
DVB-S info
查看>>
绿盟扫描操作指导
查看>>
理解链路本地址与站点本地地址
查看>>
/proc/mtd 各个参数含义 -- linux内核
查看>>
linux nand flash常用命令
查看>>
NESSUS扫描操作指导
查看>>
C语言读取文件大小,载入文件全部内容
查看>>