美文网首页AlmaLinux
20230418--RHELRockyAlmaLinux8显示内

20230418--RHELRockyAlmaLinux8显示内

作者: 負笈在线 | 来源:发表于2023-04-17 11:00 被阅读0次

    上次从系统的启动过程了解内存预分配的一些情况,现在从Linux内存管理机制memblock内核代码及CMA机制再看看RHEL/Rocky/AlmaLinux8内存管理的一些情况。

    1.了解memblock预留内存

    mmeblock是内存的一种管理机制,主要管理这两种内存:一种是系统可用部分的物理内存(usable),也就是/proc/meminfo里看到的总内存都是提供给系统使用的;另一种是用户预留部分的内存(reserved),用户自己特殊使用,这部分在系统总内存里看不到;reserved主要包括静态内存(内存中的某些部分使永久分配给内核的,例如代码段和数据段,ramdisk和dtb占用的空间等,是系统内存的一部分,不能被侵占,也不参与内存的分配。)和预留内存(GPU/camera/多核共享的内存都需要预留大量连续内存,这部分内存平时不使用,但是必须为各个应用场景预留。)。
    memblock 结构体维护着上述两种内存, 其中成员 memory 维护着可用物理内存区域;成员 reserved 维护预留的内存区域。

    memblock的算法实现是,它将所有的状态都保持在一个全局变量__initdata_memblock中,算法的初始化以及内存的申请释放都是在将内存块的状态做变更。那么从数据结构入手,__initdata_memblock是一个memblock结构体,其定义如下:
    # cat  /usr/src/kernels/4.18.0-425.19.2.el8_7.x86_64/include/linux/memblock.h
    ...
    struct memblock {
        bool bottom_up;  /* is bottom up direction? */
        phys_addr_t current_limit;
        struct memblock_type memory;
        struct memblock_type reserved;
    #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
        struct memblock_type physmem;
    #endif
    };
    ...
    定义    含义
    bottom_up    表示分配器的分配方式,true表示从低地址向高地址分配,false则相反
    current_limit    来表示用来限制alloc的内存申请
    memory    表示usabe内存区域
    reserved    表示保留reserved内存区域
    memory和reserved是很关键的一个数据结构,memblock算法的内存初始化和申请释放都是围绕着他们展开工作。
    physmem     表示所有物理内存
    往下看看memory和reserved的结构体memblock_type定义:
    
    ...
    struct memblock_region {
            phys_addr_t base;
            phys_addr_t size;
            enum memblock_flags flags;
    #ifdef CONFIG_NEED_MULTIPLE_NODES
            int nid;
    #endif
    };
    ...
    定义    含义
    struct memblock_region-表示内存区域
    base:表示区域的物理地址
    size:表示区域大小
    flags:表示内存区域属性
    nid:表示NUMA(Non Uniform Memory Access,非一致内存访问架构)节点id
    
    ...
    struct memblock_type {
        unsigned long cnt;    /* number of regions */
        unsigned long max;    /* size of the allocated array */
        phys_addr_t total_size;    /* size of all regions */
        struct memblock_region *regions;
    };
    ...
    定义    含义
    struct memblock_type:表示特定类型的内存区域的集合
    cnt:表示当前状态(memory/reserved)的内存区域可用数
    max:表示可支持的最大区域数
    total_size:表示当前状态(memory/reserved)的空间大小,也就是内存总大小空间
    regions:表示用于保存内存块信息的结构(包括基址、大小和标记等)
    name:表示内存类型符号名称
    

    memblock 方式预留内存需要有内核代码,就不深入研究了;

    2.通过限时可用内存增加预留内存

    1)修改可用内存

    # cp -p /etc/default/grub /etc/default/grub.20230417
    # vi /etc/default/grub
    限制可用内存为512M,物理内存是1G。
    # diff /etc/default/grub /etc/default/grub.20230417
    6c6
    < GRUB_CMDLINE_LINUX="crashkernel=0 mem=512M resume=/dev/mapper/almalinux-swap rd.lvm.lv=almalinux/root rd.lvm.lv=almalinux/swap"
    ---
    > GRUB_CMDLINE_LINUX="crashkernel=0 resume=/dev/mapper/almalinux-swap rd.lvm.lv=almalinux/root rd.lvm.lv=almalinux/swap"
    # grub2-mkconfig -o /boot/grub2/grub.cfg
    # reboot
    

    2)确认可用内存正好为512M

    # cat /proc/iomem |grep RAM
    00001000-0009ebff : System RAM     # 4096~650239+1  646,144
    00100000-1fffffff : System RAM     # 1048576~536870911+1= 535,822,336
    
    # dmesg |grep e820 |grep usable
    [    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ebff] usable     # ①
    [    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003fedffff] usable   
    [    0.000000] BIOS-e820: [mem 0x000000003ff00000-0x000000003fffffff] usable    # 1048576~1073741823+1=1,072,693,248
    [    0.000000] e820: remove [mem 0x20000000-0xfffffffffffffffe] usable
              #减少可用内存
    [    0.000000] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved   # ②    ①-②=00001000-0009ebff   646,144
    [    0.000000] e820: remove [mem 0x000a0000-0x000fffff] usable
              #减少可用内存
    

    3.CMA连续内存分配方式预留内存

    1)什么是CMA?
    CMA,Contiguous Memory Allocator,是内存管理子系统中的一个模块,负责物理地址连续的内存分配。一般系统会在启动过程中,从整个memory中配置一段连续内存用于CMA,然后内核其他的模块可以通过CMA的接口API进行连续内存的分配。CMA的核心并不是设计精巧的算法来管理地址连续的内存块,实际上它的底层还是依赖内核伙伴系统这样的内存管理机制,或者说CMA是处于需要连续内存块的其他内核模块(例如DMA mapping framework)和内存管理模块之间的一个中间层模块,主要功能包括:
    1、解析DTS或者命令行中的参数,确定CMA内存的区域,这样的区域我们定义为CMA area。
    2、提供cma_alloc和cma_release两个接口函数用于分配和释放CMA pages
    3、记录和跟踪CMA area中各个pages的状态
    4、调用伙伴系统接口,进行真正的内存分配。
    2)内核中为何建立CMA模块?
    Linux内核中已经提供了各种内存分配的接口,为何还有建立CMA这种连续内存分配的机制呢?
    先来看看内核哪些模块有物理地址连续的需求。huge page模块需要物理地址连续是显而易见的。大家都熟悉的处理器(不要太古老),例如ARM64,其内存管理单元都可以支持多个页面大小(4k、64K、2M或者更大的page size),但在大多数CPU架构上,Linux内核总是倾向使用最小的page size,即4K page size。Page size大于4K的page统称为“huge page”。对于一个2M的huge page,MMU会把一个连续的2M的虚拟地址mapping到连续的、2M的物理地址上去,当然,这2M size的物理地址段必须是由512个地址连续的4k page frame组成。
    当然,更多的连续内存的分配需求来自形形色色的驱动。例如现在大家的手机都有视频功能,camer功能,这类驱动都需要非常大块的内存,而且有DMA用来进行外设和大块内存之间的数据交换。对于嵌入式设备,一般不会有IOMMU,而且DMA也不具备scatter-getter功能,这时候,驱动分配的大块内存(DMA buffer)必须是物理地址连续的。
    3)CMA的状况确认
    CMA是2010年三星公司Michal Nazarewicz 首先提出,用于用于解决连续物理内存申请问题。Linux Kernel 3.5中首次合并改功能。

    RHEL/Rocky/AlmaLinux8中都具备该功能
    # uname -a
    Linux test 4.18.0-425.19.2.el8_7.x86_64 #1 SMP Tue Apr 4 05:30:47 EDT 2023 x86_64 x86_64 x86_64 GNU/Linux
    # dmesg |grep -i cma
    [    0.000000] Memory: 261120K/523892K available (12293K kernel code, 5878K rwdata, 8376K rodata, 2552K init, 14256K bss, 117240K reserved, 0K cma-reserved)
    # find / -name cma.h
    /usr/src/kernels/4.18.0-425.19.2.el8_7.x86_64/include/linux/cma.h
    /usr/src/kernels/4.18.0-425.19.2.el8_7.x86_64/include/trace/events/cma.h
    
    RHEL/Rocky/AlmaLinux7中未启用该功能
    # uname -a
    Linux chefserver 3.10.0-693.11.6.el7.x86_64 #1 SMP Thu Jan 4 01:06:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
    # dmesg |grep -i cma
    # find / -name cma.h
    /usr/src/kernels/3.10.0-693.el7.x86_64/include/config/cma.h
    /usr/src/kernels/3.10.0-693.11.6.el7.x86_64/include/config/cma.h
    

    至此,对Linux内存管理增加了解了一点皮毛。

    参考URL:

    https://blog.csdn.net/u012294613/article/details/124133143
    https://zhuanlan.zhihu.com/p/554043638
    https://blog.csdn.net/ludaoyi88/article/details/115280238
    https://www.bbsmax.com/A/A7zg8VRlJ4/
    https://www.yii666.com/blog/356096.html
    https://blog.csdn.net/u012489236/article/details/105348579/

    相关文章

      网友评论

        本文标题:20230418--RHELRockyAlmaLinux8显示内

        本文链接:https://www.haomeiwen.com/subject/ugfcjdtx.html