免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: platinum
打印 上一主题 下一主题

关于 vmalloc 的几点疑惑…… [复制链接]

论坛徽章:
0
61 [报告]
发表于 2009-05-21 22:15 |只看该作者
原帖由 eexplorer 于 2009-5-21 21:49 发表



> 不过你们后来扯出了一堆概念我觉得都不准确,想补充一下。

我就是没搞清楚何为wired memory(在linux kernel里从来没有听说过这种说法),所以就没插上什么话

>...
> 从你们的意思来看所谓“固 ...

这个地方是我表述错了,漏说了是指虚拟地址3G以上map的,并被内核使用的物理内存

[ 本帖最后由 zx_wing 于 2009-5-22 08:19 编辑 ]

论坛徽章:
0
62 [报告]
发表于 2009-05-21 22:58 |只看该作者
原帖由 zx_wing 于 2009-5-21 21:27 发表

你们讨论的真是热烈啊。关于vmalloc的问题eexplorer在35楼已经讲的很清楚了。
不过你们后来扯出了一堆概念我觉得都不准确,想补充一下。
首先是wired memory,这个东西我还真没找到权威定义。Mac OS中内核占的内存就是wired memory,但FreeBSD里又说malloc也可以分配wired memory,所以我觉得姑且不说它。 ...


BSD的wired memory的定义是,和Solaris一样一样一样的。

我从网上随便搜搜就找到了。http://kerneltrap.org/node/312

Wired memory, also known as resident memory, is memory that is always in phyisical RAM and cannot be paged to disk.

N年前在我们翻译Solaris Internal第二版的时候,为了把它翻译成中文,特别思考过这个词汇,后来的译法我个人不是很满意,我们叫“在线内存”。

Wired memory没有特指是用户还是内核内存,Solaris里的情况是这样的,

1.  大部分内核内存属于Wired memory,例如kernel heap
2. 内核线程的Stack是non-wire memory,可以被page out,所以内核debug memory leak的时候比较烦。原因很简单,内核调试器不能追踪swap out出去的内存。
3. 用户内存大部分是non-wire memory, 除非你调用系统调用不允许它换出。

所以,我没看到什么概念错误。

论坛徽章:
0
63 [报告]
发表于 2009-05-21 23:12 |只看该作者
原帖由 zx_wing 于 2009-5-21 21:27 发表

后面你和思一克说的“固定映射”肯定是不准确的。在linux中,固定映射指的是通过set_fixmap和kmap_atomic()占用的内存,前者用于对虚拟地址有硬性要求的硬件,比如APIC要求寄存器必须map到预定的虚拟地址,后者用于原子map高端内存。
从你们的意思来看所谓“固定映射”的是kernel memory,即虚拟地址3G+896M所对应的物理内存,这部分内存的映射在建立Master page table的时候就建好了,不会被swap出或产生由于page non-persent引起的page fault(非法访问还是会有的)。


今天我是第一次听到固定映射这个词汇,也许可能思一克用错了, 但我明白他说的是什么意思。他说的固定映射的意思是 Zone_normal这样的物理内存,不管是给用户还是内核用内核都为它们分配了一个永久的虚拟地址,就算是有换出,这个地址对应的物理内存单元也没有变。



而vmalloc所对应的虚拟地址是固定的,它的范围是:VMALLOC_START ~ VMALLOC_END。VMALLOC_START = high_memory + 8M,也就是3G + 404M处。所以:
>>vmalloc得到的物理页同时有2个虚拟地址。一个是固定映射地址。一个是非固定映射地址。
是不准确的。在物理内存大于896M时,vmalloc从高端内存中分配,只有一个虚拟地址,这就有点像临时映射了。.


思一克说的非固定的,和你说的基本一样,只不过我们只讨论64位上的情况,所以是不准确的。

如果没有一个确切的概念的话,大家还是不要乱用这个词啊。

这可和wired memory不同,这个是在传统OS教科书里的概念,但wired memory和思一克说的固定映射确实是不同的,wired memory强调的是内存数据本身,它是被锁定或者说是绑定在物理内存的,不能换出的。

论坛徽章:
0
64 [报告]
发表于 2009-05-22 08:56 |只看该作者
2. 内核线程的Stack是non-wire memory,可以被page out,所以内核debug memory leak的时候比较烦。原因很简单,内核调试器不能追踪swap out出去的内存。
请问这个有例子吗?
我看到2.6里面kernel_thread实际上是调用的clone 在copy_process 中他申请了2个page的内存作为内核堆栈,属性是GFP_KERNEL 看上去应该是不会被page out

论坛徽章:
0
65 [报告]
发表于 2009-05-22 08:59 |只看该作者
而且实际上ULK中也说 内核是不会产生异常的(除了vmalloc区间的同步和访问用户地址空间),如果像你说的 岂不是一定要page fault来处理 。。。。。

论坛徽章:
0
66 [报告]
发表于 2009-05-22 09:42 |只看该作者
原帖由 zx_wing 于 2009-5-21 21:27 发表

你们讨论的真是热烈啊。关于vmalloc的问题eexplorer在35楼已经讲的很清楚了。
不过你们后来扯出了一堆概念我觉得都不准确,想补充一下。
首先是wired memory,这个东西我还真没找到权威定义。Mac OS中内核占 ...


32位系统上,如果物理内存》896, vmalloc分得的内存就没有2个虚拟地址了。
我说的是分得的小于896M的页的时候。

固定映射在LINUX中就是指虚拟--》物理用固定映射的那部分内存。这概念是非常简单和清楚的。
就是可以用内核的宏__pa()   __va()直接固定换算的页。
wired memory不是LINUX上的概念,不清楚。

论坛徽章:
0
67 [报告]
发表于 2009-05-22 10:29 |只看该作者
原帖由 思一克 于 2009-5-22 09:42 发表


32位系统上,如果物理内存》896, vmalloc分得的内存就没有2个虚拟地址了。
我说的是分得的小于896M的页的时候。

固定映射在LINUX中就是指虚拟--》物理用固定映射的那部分内存。这概念是非常简单和清楚 ...

>>固定映射在LINUX中就是指虚拟--》物理用固定映射的那部分内存。这概念是非常简单和清楚的。
这是你想当然的概念,正规的说法叫identify mapping或1:1 mapping。固定映射在Linux下是有特指的,而且恰恰和你说的不一样,不能用_pa和_va转换。

参考ULK 2.5.6节“Fix-Mapped Linear Addresses”和 《Understanding the Linux Virtual Memory Manager》3.6.2 节"Finalizing"对固定映射的定义。我帮你贴出来:
ULK:

2.5.6. Fix-Mapped Linear Addresses
We saw that the initial part of the fourth gigabyte of kernel linear addresses maps the physical memory of the system. However, at least 128 MB of linear addresses are always left available because the kernel uses them to implement noncontiguous memory allocation and fix-mapped linear addresses.

Noncontiguous memory allocation is just a special way to dynamically allocate and release pages of memory, and is described in the section "Linear Addresses of Noncontiguous Memory Areas" in Chapter 8. In this section, we focus on fix-mapped linear addresses.

Basically, a fix-mapped linear address is a constant linear address like 0xffffc000 whose corresponding physical address does not have to be the linear address minus 0xc000000, but rather a physical address set in an arbitrary way. Thus, each fix-mapped linear address maps one page frame of the physical memory. As we'll see in later chapters, the kernel uses fix-mapped linear addresses instead of pointer variables that never change their value.

ULVMM:
3.6.2 Finalizing
Next, pagetable_init() calls fixrange_init() to set up the fixed address space mappings at the end of the virtual address space starting at FIXADDR_START. These mappings are used for purposes such as the local Advanced Programmable Interrupt Controller (APIC) and the atomic kmappings between FIX_KMAP_BEGIN and FIX_KMAP_END required by kmap_atomic(). Finally, the function calls fixrange_init() to initialize the page table entries required for normal high memory mappings with kmap().

[ 本帖最后由 zx_wing 于 2009-5-22 10:33 编辑 ]

论坛徽章:
0
68 [报告]
发表于 2009-05-22 10:34 |只看该作者
原帖由 javacool 于 2009-5-22 08:56 发表
2. 内核线程的Stack是non-wire memory,可以被page out,所以内核debug memory leak的时候比较烦。原因很简单,内核调试器不能追踪swap out出去的内存。
请问这个有例子吗?
我看到2.6里面kernel_thread实际上是 ...

他讲的是solaris

论坛徽章:
0
69 [报告]
发表于 2009-05-22 11:05 |只看该作者
以前的一段fixmap笔记:
======================

61, Linux i386的fixmap (IO-APIC 和 Local APIC的Base Address都是通过它得到)
/*{{{*/
        1). 定义
       
            fixmap是这样一种机制:提供一些线性地址,在编译时就确定下来,等到Linux引导时再为之
            建立起和物理地址的映射(用set_fixmap(idx, phys))。

            fixmap和内核内存的普通影射的不同之处在于, 通常情况下内核态内存影射就是 virt = phys + PAGE_OFFSET,
            而fixmap的物理地址可以是任意的,不一定等于virt - PAGE_OFFSET.

            fixmap使用的是线性地址的高处(不是最高处)的一块区域,从0xfffff000开始。往低地址长。


            enum fixed_address {
                    FIX_HOLE,
                    FIX_VDSO,

            #ifdef CONFIG_X86_LOCAL_APIC
                    FIX_APIC_BASE,                 /* local APIC */
            #endif

            #ifdef CONFIG_X86_IO_APIC
                    FIX_IO_APIC_BASE_0,
                    FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
            #endif

            #ifdef CONFIG_ACPI
                    FIX_ACPI_BEGIN,
                    FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
            #endif

            #ifdef CONFIG_PCI_MMCONFIG
                    FIX_PCIE_MCFG,
            #endif

            #ifdef CONFIG_PARAVIRT
                    FIX_PARAVIRT_BOOTMAP,
            #endif
                    __end_of_permanent_fixed_addresses,
                    /* temporary boot-time mappings, used before ioremap() is functional */

            #define NR_FIX_BTMAPS        16
                    FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
                    FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
                    FIX_WP_TEST,
                    __end_of_fixed_addresses
            };
       
            按照C语法,FIX_HOLE的值就是0,FIX_VDSO的值是1, ……,依此类推。


        2). 映射 & 使用
            
            先映射,再使用。 引导时映射,但编写内核C代码时可以先使用.

            例如init_apic_mappings()中:
                   
                    L1: set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
                    L2: printk(KERN_DEBUG "mapped APIC to %08lx (%08lx)\n", APIC_BASE,
                                    apic_phys);
            L1是映射,L2是使用(看APIC_BASE这个宏就是在使用fixmap)。
            
            其中APIC_BASE的定义:

                    #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))

            fix_to_virt()函数的作用,就是从一个fixmap的Index得到它的 线性地址。


                #define __fix_to_virt(x)  (FIXADDR_TOP - ((x) << PAGE_SHIFT))

            
            
            
            而FIXADDR_TOP的定义:
               
               #define FIXADDR_TOP        ((unsigned long)__FIXADDR_TOP)
               unsigned long __FIXADDR_TOP = 0xfffff000;

/*}}}*/

论坛徽章:
0
70 [报告]
发表于 2009-05-22 14:56 |只看该作者
原帖由 albcamus 于 2009-5-22 11:05 发表
以前的一段fixmap笔记:
======================

61, Linux i386的fixmap (IO-APIC 和 Local APIC的Base Address都是通过它得到)
/*{{{*/
        1). 定义
       
            fixmap是这样一种机制:提供一些线性地址,在 ...


zx_wing和albcamus,

你们说的对。
我说的映射是指"kernel direct mapping", 中文不应该叫固定映射。
应该叫直接映射。就是可以用pa, va转换的kernel生存期永远不变的映射。
因为基本没有系统看过书,理解有误。中文的固定映射就是你们说的fixmap

谢谢指正
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP