免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2536 | 回复: 3
打印 上一主题 下一主题

[内存管理] 关于ARM-Linux在内存管理初始化过程中的一点困惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-12-04 13:25 |只看该作者 |倒序浏览
本帖最后由 paul719 于 2014-12-04 13:26 编辑

刚开始研究ARM-linux内核,有个小问题希望大家讨论原因,帮忙解答...
在内存管理的初始化阶段的后期,Linux内核会使用buddy system替换初始阶段的bootmem分配器,这个过程在meminit()实现,在这个替换过程中有一个阶段叫做free_unused_memmap_node,调用过程如下:
meminit()
        |--->free_unused_memmap_node(node);
                              |--->free_memmap(node, prev_bank_end, bank_start);
                                                 |--->free_bootmem_node(NODE_DATA(node), pg, pgend - pg);

free_unused_memmap_node这个函数,看名字大概就是说释放掉未使用的页。我的理解,unused的意思大概也就是说bank与bank之间有些不可用的地址,
需要找到这些地址,然后把它从可分配的地址空间中刨除。在操作系统自动为申请内存操作分配页框时,就不会把这些未使用的内存地址分配出去。

举例,假如是图中黑色区域未接内存
这个刨除unused地址区域的函数到最后调用的是free_bootmem_node(),让我搞不懂的地方来了,这个函数是将bitmap中相应的页框置0,表示可分配的页。
明明这个地址对应的页框未使用,后面又将bitmap中对应的位设置为可分配,是什么原因呢?这些bitmap中设置为0的区域将来应该是要交给buddy system管理的
可供分配的内存啊?是我理解有问题么?

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
2 [报告]
发表于 2014-12-04 23:16 |只看该作者
没有去看代码,按印象给你答。
1. 你理解的unused有误。这里所指的unused,是指没有被bootmem分配出去的内存。你想想,如果别人从bootmen分配了内存,一直在用,没有换给bootmem,再由buddy去管理时,也应该属于它的。如果在free_unused_memmap_node函数里还给buddy,那其它人就能从buddy申请到,这决对是不行的。
2. 一般来于,Linux所能用的物理内存是连续的,称为一致性内存,如果像你这种情况,物理内存都不连续了了,就是非一致性内存。此时,每一段内存都是一个node。free_unused_memmap_node会一个一个node的去处理node内的unused内存。

论坛徽章:
0
3 [报告]
发表于 2014-12-05 10:36 |只看该作者
本帖最后由 paul719 于 2014-12-05 10:41 编辑

回复 2# Tinnal

谢谢版主解答,但是还是不理解。。。。版主可能还没真正理解我的疑惑~
详细阐述一下:
看最后的调用函数,确实是像你所说的,这里的unused是未被bootmem分配出去的内存。为了说清楚我的问题,我把bootmem到buddy system过渡阶段,尽可能说明白一些。
我们说对于bootmem的视角来看,就分为"已被分配出去的内存"和“未分配出去的内存”。
    已被分配出去的内存(bitmap位:1)很简单,当然不可能交给buddy system的free_list(比如内核代码段区域),这个后面也会将这部分bit置1的区域交给reserve_list。
    未被分配出去的内存(bitmap位:0)在我看来应该是两部分构成:1 可以分配给内核使用但尚未使用的 2 不可以使用的内存
    假如说未被分配出去的内存不存在第二种情况-不可以使用的内存,就清楚多了,去查bitmap位就好了,已分配的交给buddy system的reserve保留页列表,未分配的交给free空白页列表。
    但是,这里出现了第二种情况,不可使用的内存,这里可能是版主和我存在理解不一样的地方,也是我迷惑的地方:
    未被分配出去的内存就一定能交给buddy system的空白页链表,作为供内核申请的可用空间吗?我的理解是,不可以!不可以使用的内存就不能交给free空白页列表。
    为什么会说有个不可使用的内存呢(也就是图中那个黑色区域)?版主在回复的第2点的说明可能认为这个区域根本不存在,因为内核要物理内存连续。我想说:
    第一,一致性内存的概念应该是相对于线性地址空间而言的,物理地址不一致并不影响线性地址空间的一致性。
    第二,这里的不可使用的内存也不是凭空捏造的,很多资料都有说到早期的处理器,内存bank之间是有hole的概念的,这里的洞也就是说有一块儿地址存在,但不可操作使用的空间,主要原因是受硬件制约,图中为了方便理解,可能画的夸张一点,实际上即使两个bank的物理地址空间紧挨着,在早期的处理器中,两个bank相邻的一块区域也是不可被操作的。
    而且从代码中可以看出来:
            free_memmap(prev_bank_end, bank_start);
    注意看标红的参数,第一个参数是前一个bank的结束,第二个参数是当前bank的开始。用前一个bank的结束和后一个bank的开始标记的区域,难道不是不可用区域吗?因为bank本来就是描述可用物理内存的数据结构,不管是分配的内存和没有分配的内存,能用的都必然在bank范围之内,而这里的区域很明显在bank之外。
    版主也说了,free_unused_memmap_node指定的区域,交给buddy system后,如果有人申请内存,系统就有可能把这块地址空间交给他使用。可是,再看看上面那个函数标红的区域,那一块区域在bank范围内吗?能用吗?如果是不可用,那为什么最后调用mark_bootmem(start, end, 0, 0)将这块区域设置成可分配区域?
    附这部分源码:
static inline void
free_memmap(unsigned long start_pfn, unsigned long end_pfn)
{
        struct page *start_pg, *end_pg;
        unsigned long pg, pgend;

        /*
         * Convert start_pfn/end_pfn to a struct page pointer.
         */
        start_pg = pfn_to_page(start_pfn - 1) + 1;
        end_pg = pfn_to_page(end_pfn - 1) + 1;

        /*
         * Convert to physical addresses, and
         * round start upwards and end downwards.
         */
        pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
        pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;

        /*
         * If there are free pages between these,
         * free the section of the memmap array.
         */
        if (pg < pgend)
                free_bootmem(pg, pgend - pg);
}





void __init free_bootmem(unsigned long addr, unsigned long size)
{
        unsigned long start, end;

        kmemleak_free_part(__va(addr), size);

        start = PFN_UP(addr);
        end = PFN_DOWN(addr + size);

        mark_bootmem(start, end, 0, 0); //对应区域的bitmap置0,表示可分配
}

论坛徽章:
0
4 [报告]
发表于 2014-12-09 13:40 |只看该作者
楼主你是对的,free_unused_memmap_node函数释放掉内存节点中空洞空间的page数据结构。如果保留这些结构会占用大量的内存空间,同时页会给分配带来麻烦
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP