当前位置:Linux教程 - Linux - Linux的存储管理

Linux的存储管理



        

    Linux的存储管理


    Blue Ocean


    虚存管理


    Linux里使用了N个概念来描述虚存系统:




    • 地址空间(struct mm_struct

    • 虚存区(struct vm_area_struct

    • 页面(struct page

    • 体系无关MMU管理


    struct mm_struct


    核心为每个进程的地址空间维护一个数据结构struct mm_struct(linux/sched.h),每个进程的task_struct(linux/sched.h)结构中都有一个指向它的指针。


    该结构的成员如下:





































    成员名


    用途


    count


    mm_struct结构的引用计数。为了在Linux中实现线程,系统调用clone派生一个线程,它具备进程所具有的控制结构,但和调用进程共享内存,即mm_struct结构,派生后系统会累加mm_struct中的引用计数。


    pgd


    页目录基址


    context


    虚存上下文。在有的体系结构中,虚存地址要加上一个上下文标识才能进行地址转换,如MIPS系列,这个域就是进程的上下文标识。


    start_code, end_code, start_data, end_data


    进程的代码和数据的起始地址。


    start_brk, brk, start_stack, start_mmap


    进程堆的起始地址,当前地址,进程用户栈的起始地址,进程映射空间的起始地址。


    rss, total_vm, locked_vm


    进程贮留在物理内存中的页面,进程所需的总的页面数,被锁定在物理内存中的页面数。


    def_flags


    进程某人的页面标志。系统在设定页面标志时,首先OR上这个标志。如在调用mlockall(MCL_CURRENT)时,系统就会将def_flags设置为VM_LOCKED,这样以后在调入的页面也被标记为VM_LOCKED的,就完成相应的页面锁定工作。


    mmap


    struct vm_area_struct队列,按基址从小到大排列。


    mmap_avl


    struct vm_area_struct AVL树。核心经常会完成从虚址到相应的struct vm_area_struct结构的转换操作,如果总是线性地查找mmap队列就会非常地耗时。利用AVL树可以将查找的代价控制在O(logN)的水平上。


    mmap_sem


    系统修改进程的mmap队列和mmap_avl树时用于互斥的信号量。



    struct vm_area_struct(linux/mm.h)


    进程的地址空间是由一系列的虚存区构成的。虚存区的结构成员如下:








































    成员名


    用途


    vm_mm


    指向所属的mm_struct结构的指针。


    vm_startvm_end


    虚存区的起始地址。


    vm_page_prot


    虚存区的保护权限。


    vm_flags


    虚存区的标志。


    vm_avl_heightvm_avl_leftvm_avl_right


    3个成员在一起构成AVL树,其中vm_avl_height是该节点距跟节点的高度,vm_avl_leftvm_avl_right分别时该节点的左右两个子树。


    vm_next


    构成虚存区的线性链,按基址从小到大排列。


    vm_next_sharevm_prev_share


    当虚存区是文件映射空间的一部分时,这两个域将所有属于同一个文件(即同一个inode)的虚存区连接在一起。


    当虚存区时SYS V共享内存的一部分时,这两个域将所有属于同一片共享内存的虚存区连接在一起。


    vm_ops


    虚存区的函数开关表。这个表里给出了可以在对虚存区中的页面进行的操作(由vm_operations_struct(linux/mm.h)结构署名),包括opencloseunmapprotectsyncadvisenopagewppageswapoutswapinLinux中较为常用的几个vm_operations_struct结构是shm_vm_ops(ipc/shm.c)file_shared_mmap(mm/filemap.c)file_private_mmap(mm/filemap.c),这3个变量分别对应SYS V共享内存的虚存区函数开关表,文件共享方式映射的虚存区函数开关表,文件私有式映射的虚存区函数开关表。


    vm_offset


    虚存区在文件中的偏移。如果时SYS V的共享内存,则是其在共享内存段中的偏移(虽然shmat完成了整个共享内存段的映射,但进程在以后的操作中可能将映射这个共享内存段的虚存区打裂,如在相应的虚存区上在映射文件。所以SYS V的共享内存区也需要这个偏移)。


    vm_inode


    当虚存区为文件映射时,是该文件在内存中的inode。如果时SYS V的共享内存则为空。其他情况也为空。注意,系统时靠vm_ops来区分是否为SYS V的共享内存区。


    vm_pte


    当虚存区为SYS V的共享内存时,这个域存放虚存区所在的共享内存段的ID(不是简单的存放ID,具体格式见程序ipc/shm.c)。



    struct page(linux/mm.h)


    struct page时物理页面的对应数据结构(与mem_map_t相同)。其结构成员如下:











































    成员名


    用途


    nextprev


    当页面空闲时,这两个指针是空闲页面链表的前后指针。当页面时某个inode在内存中的贮留页面时,nextprev构成该inode在内存中页面的双向链表。


    inode


    该页面对应的inode


    offset


    该页面在由inode指定的文件中的偏移。


    next_hashprev_hash


    这两个域构成贮留在内存中的页面数据的哈希链。


    count


    页面的引用计数。


    flags


    页面的标志,下面详细介绍。


    dirty


    ???


    age


    页面的年龄,age == 0时年龄最大。这个值反应了页面最近的使用情况,最近不使用的页面年龄较大,利用这个值控制页面的换入换出。


    wait


    等待在这样页面上的任务的单向链表。


    buffers


    当这个页面用做磁盘缓冲时,这个域是磁盘缓冲区双向循环链表。


    swap_unlock_entry


    页面换出时要对相应换出设备上的页面上锁,有的换出有时是异步的,此时需要记住换出设备和其上的页面偏移以便解锁,这个域就是暂存这个数值的。


    map_nr


    该结构在mem_map数组中的索引,也就是页面在物理内存中的物理页面号。



    mem_map


    Linux在管理物理页面时设置若干数据结构,首先时mem_map数组。这个数组的每一项都是strut page结构,对应着物理内存中的一个页面,记录它们的状态和有关其内容的元信息。系统在初始化时根据物理内存的大小建立这个数组(这段代码在mm/page_alloc.c中的free_area_init中)。


    空闲区


    其次,为了维护连续空闲内存,系统还维护一组称为空闲区(free_area)结构。每个空闲区对应一个固定的内存大小(2N×PAGE_SIZEN=01,…,NR_MEM_LISTS-1),该结构有一个双向循环链表将指定大小的空闲区连接起来。此外,它还有一个位图,每一位对应连续的两个页面。当这两个页面都时空闲时,也就是有两次释放动作发生,这个二进制位经过两次异或又恢复为0,此时说明这两个都是空闲,应该从2N空闲区删除,并加入到2(N+1)空闲区中。所以,Linux空闲页面的管理实际上以页面为单位的伙伴系统(Buddy System)。


    page cache


    虚存系统将全部内存或内存的一部分最为后备存储介质(文件,交互区等)的cacheLinux中将文件贮留在内存中的部分通过一个哈希链表管理起来,这个哈希链表就是page cache。系统将页面的inodeoffset最为键值,并通过find_page(mm/filemap.h)寻找相应的页面。


    除了page cache外,系统中另外一个cache部件是磁盘缓冲区,这部分在文件系统中介绍,此处忽略。


    体系无关MMU管理


    发布人:netbull 来自:利索脚