【Linux内核】伙伴系统算法和slab分配器(1)

news2024/11/25 20:24:17

【Linux内核】伙伴系统算法和slab分配器(1)

目录

  • 【Linux内核】伙伴系统算法和slab分配器(1)
    • 伙伴系统(buddy)算法
      • 伙伴系统算法基本原理
      • 内存申请
      • 内存回收
    • 接口函数源码分析
      • 内存分配接口
      • 物理内存释放接口
      • 规范物理内存分配行为的掩码 gfp_mask(了解即可)

作者:爱写代码的刚子

时间:2024.5.24

前言:本篇博客将会介绍Linux系统中伙伴系统算法

伙伴系统(buddy)算法

系统需要一种能够高效分配内存,同时又能减少产生碎片的算法——伙伴系统算法

大致结构:

在这里插入图片描述

node划分:

现代服务器上,内存和CPU都是所谓的NUMA架构(有多个CPU)

  • dmidecode命令可以查看主板上插着的CPU的详细信息

在这里插入图片描述

在NUMA架构中node

在这里插入图片描述

  • numactl --hardware指令查看每个node情况

在这里插入图片描述

zone划分

每个zone又会划分成若干个的zone(区域),zone表示内存中的一块范围。

在这里插入图片描述

  • ZONE_DMA:地址段最低的一块内存区域,供I/O设备DMA访问。
  • ZONE_DMA32:用于支持32位地址总线的DMA设备,只在64位系统里才有效。
  • ZONE_NORMAL:在X86-64架构下,DMA和DMA32之外的内存全部都在NORMAL的zone管理

其实还有一个ZONE_HIGHMEM,但是这是32位机时代的产物,现在用的不多

  • cat /proc/zoneinfo查看zone的划分

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

伙伴系统算法基本原理

伙伴系统算法把所有的空闲页框分为11个块链表,每块链表中分布包含特定的连续页框地址空间,例:第0个块链表包含大小为2^0个连续的页框(4kb), 第1个块链表包含大小为2^1个连续的页框(8kb)

伙伴算法每次只能分配2的幂次页的空间,比如一次分配1页,2页,4页,8页,…,1024页(2^10)等等,每页大小一般为4K,因此,伙伴算法最多一次能够分配4M的内存空间。

在这里插入图片描述

伙伴算法在内核中通常用free_area结构体表示,free_list链表数组,nr_free就是当前链表中空闲页框块数量。例:free_area[2]中nr_free值为3,就是3个大小为4的页框块(16kb),总的空闲页就是3*4=12个(48kb)

#define MAX_ORDER 11
struct free_area {//链表
    struct list_head    free_list[MIGRATE_TYPES];//页属性
    unsigned long        nr_free;//空闲页框块数目
};
#define MAX_ORDER 11
struct zone{
    struct  free_area freearea[MAX_ORDER];
};

内存申请

举例:需要分配16k的内存空间,算法会先从free_area[2]中查看nr_free是否为空,如果有空闲块,则从中分配,如果没有空闲块,就从它的上一级free_area[3](每块32K)中分配出16K,并将多余的内存(16K)加入到free_area[2]中去。如果free_area[3]也没有空闲,则从更上一级申请空间,依次递推,直到free_area[max_order],如果顶级都没有空间,那么就报告分配失败。

“伙伴关系”定义:

所谓“伙伴”,就是指在空闲块被分裂时,由同一个大块内存分裂出来的两个小块内存就互称“伙伴”。“伙伴”应当满足以下三个条件:

  • 两个块大小相同
  • 两个块地址连续
  • 两个块必须是同一个大块中分离出来的

如何判断是同一块大块内存分配出来的?

具体的操作步骤如下:

  1. 确定块大小:假设块大小为 2^k。

  2. 检查地址对齐:分别计算内存块 A 和 B 的起始地址对 2^k的对齐情况。

  3. 计算父节点地址

    • 设两个内存块地址分别为 A 和 B,计算父节点地址。
    • 父节点地址为 min(A,B)向下取整到2^(k+1) 的倍数。
  4. 验证共同父节点

    • 如果计算出的父节点地址相同,则 A 和 B 是“伙伴”。

内存回收

回收是申请的逆过程,当释放一个内存块时,先在其对于的free_area链表中查找是否有伙伴存在,如果没有伙伴块,直接将释放的块插入链表头。如果有或板块的存在,则将其从链表摘下,合并成一个大块,然后继续查找合并后的块在更大一级链表中是否有伙伴的存在,直至不能合并或者已经合并至最大块2^10为止。

接口函数源码分析

内存分配接口

伙伴系统特点:分配的物理内存全部都是在物理内存上连续,分配的是2的整数幂的页,这个幂在内核中称为分配阶(如果指定分配阶为order,那么就会向伙伴系统申请2的order次幂个物理内存页)

  • alloc_pages
struct page *alloc_pages(gfp_t gfp, unsigned int order);
  • 输入参数:alloc_pages 函数用于分配 2 的 order 次幂个物理内存页,参数 gfp_t gfp 是内核中定义的一个用于规范物理内存分配行为的修饰符,这里我们先不展开。

  • 返回值: struct page 类型的指针用于指向申请的内存块中第一个物理内存页。当系统中空闲的物理内存无法满足内存分配时,就会导致内存分配失败,alloc_pages,alloc_page 就会返回空指针 NULL 。

alloc_pages 函数用于分配多个连续的物理内存页,在内核的某些内存分配场景中有时候并不需要分配这么多的连续内存页,而是只需要分配一个物理内存页即可,于是内核又提供了 alloc_page 宏,用于这种单内存页分配的场景,我们可以看到其底层还是依赖了 alloc_pages 函数,只不过 order 指定为 0。

该宏alloc_page的定义:

#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
  • __get_free_pages

该函数返回的是物理内存页的虚拟内存地址

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);

__get_free_pages 函数在使用方式上和 alloc_pages 是一样的,函数参数的含义也是一样,只不过一个是返回物理内存页的虚拟内存地址,一个是直接返回物理内存页。

其实 __get_free_pages 函数的底层也是基于 alloc_pages 实现的,只不过多了一层虚拟地址转换的工作。

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
{
 struct page *page;
    // 不能在高端内存中分配物理页,因为无法直接映射获取虚拟内存地址
 page = alloc_pages(gfp_mask & ~__GFP_HIGHMEM, order);
 if (!page)
  return 0;
    // 将直接映射区中的物理内存页转换为虚拟内存地址
 return (unsigned long) page_address(page);
}

page_address 函数用于将给定的物理内存页 page 转换为它的虚拟内存地址,不过这里只适用于内核虚拟内存空间中的直接映射区,因为在直接映射区中虚拟内存地址到物理内存地址是直接映射的,虚拟内存地址减去一个固定的偏移就可以直接得到物理内存地址

如果物理内存页处于高端内存中,则不能这样直接进行转换,在通过 alloc_pages 函数获取物理内存页 page 之后,需要调用 kmap 映射将 page 映射到内核虚拟地址空间中。

在这里插入图片描述

  • get_zeroed_page

无论是 alloc_pages 也好还是 __get_free_pages 也好,它们申请到的内存页中包含的数据在一开始都不是空白的,而是内核随机产生的一些垃圾信息,但其实这些信息可能并不都是完全随机的,很有可能随机的包含一些敏感的信息。

这些敏感的信息可能会被一些黑客所利用,并对计算机系统产生一些危害行为,所以从使用安全的角度考虑,内核又提供了一个函数 get_zeroed_page,顾名思义,这个函数会将从伙伴系统中申请到内存页全部初始化填充为 0 ,这在分配物理内存页给用户空间使用的时候非常有用。

unsigned long get_zeroed_page(gfp_t gfp_mask)
{
 return __get_free_pages(gfp_mask | __GFP_ZERO, 0);
}

get_zeroed_page 函数底层也依赖于 __get_free_pages,指定的分配阶 order 也是 0,表示从伙伴系统中只申请一个物理内存页并初始化填充 0 。

  • __get_dma_pages

专门用于从 DMA 内存区域分配适用于 DMA 的物理内存页。其底层也是依赖于 __get_free_pages 函数。

unsigned long __get_dma_pages(gfp_t gfp_mask, unsigned int order);

物理内存释放接口

void __free_pages(struct page *page, unsigned int order);
void free_pages(unsigned long addr, unsigned int order);
 
#define __free_page(page) __free_pages((page), 0)
#define free_page(addr) free_pages((addr), 0)
  • __free_pages

同 alloc_pages 函数对应,用于释放一个或者 2 的 order 次幂个内存页,释放的物理内存区域起始地址由该区域中的第一个 page 实例指针表示,也就是参数里的 struct page *page 指针。

  • free_pages

__get_free_pages 函数对应,与 __free_pages 函数的区别是在释放物理内存时,使用了虚拟内存地址而不是 page 指针。

在这里插入图片描述

规范物理内存分配行为的掩码 gfp_mask(了解即可)

gfp是get free page的缩写,这个参数由3种flag组成,分别为action modifier, zone modifier,type。

参考的文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1826361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring boot配置ssl证书,支持https访问

1. 阿里云官网下载证书,云控制台搜索ssl,点击进入。 2.点击免费证书,立即购买。 3. 点击创建证书,填写完证书申请后,等待证书签发。 4. 证书签发以后,点击下载证书,spring boot选tomcat服务器类型的。 5. …

FineReport简单介绍

一、介绍 官网 :FineReport产品简介- FineReport帮助文档 - 全面的报表使用教程和学习资料 报表是以表格、图表的形式来动态展示数据,企业通过报表进行数据分析,进而用于辅助经营管理决策。 FineReport 是一款用于报表制作,分析和…

Mybatis-Plus多种批量插入方案对比

背景 六月某日上线了一个日报表任务,因是第一次上线,故需要为历史所有日期都初始化一次报表数据 在执行过程中发现新增特别的慢:插入十万条左右的数据,SQL执行耗费高达三分多钟 因很早就听闻过mybatis-plus的[伪]批量新增的问题&…

C++语法05 浮点型/实数类型

什么是实数类型 实数类型是一种数据类型&#xff0c;实数类型变量里能存放小数和整数。 定义格式&#xff1a;double a; 赋值&#xff1a;a0.4; 输入&#xff1a;cin>>a; 输出&#xff1a;cout<<a; 训练&#xff1a;尺子的价格 小知在文具店买铅笔&#xff…

亲测几十款随身wifi,全网最全随身WiFi避坑指南!最值得买的随随身wifi品牌推荐!

关于随身wifi我认为我是比较有发言权的&#xff0c;历经三年测评了几十种随身wifi&#xff0c;便宜的贵的&#xff0c;大牌的小厂的&#xff0c;电池款USB款等各种随身wifi。根据测试结果以及通过电商平台搜索、粉丝反馈、社交平台评价等综合测评结果。今天就跟大家分享一下&am…

Orange_Pi_AIpro运行蜂鸟RISC-V仿真

Orange_Pi_AIpro运行蜂鸟RISC-V仿真 突发奇想&#xff0c;试一试Orange Pi AIpro上运行蜂鸟RISC-V的仿真。 准备 默认已经有一个Orange Pi AIpro&#xff0c;并且对设备进行一定的初始化配置&#xff0c;可以参考上一篇博文开源硬件初识——Orange Pi AIpro&#xff08;8T&a…

《C++ Primer》导学系列:第 2 章 - 变量和基本类型

2.1 基本内置类型 概述 本小节介绍C中的基本内置类型。基本内置类型是构成C程序的基础&#xff0c;它们用于表示数据的不同形式&#xff0c;如整数、浮点数、字符等。理解和使用这些基本类型是编写C程序的起点。 2.1.1 算术类型 C的算术类型分为整型和浮点型。整型用于表示…

LVS三种负载均衡模式:NAT、Tunneling和DR的技术对比

1. LVS-NAT 模式的特性 IP使用&#xff1a;RS&#xff08;Real Server&#xff09;应使用私有地址&#xff0c;RS的网关必须指向DIP&#xff08;Director IP&#xff09;。网络范围&#xff1a;DIP和RIP必须在同一个网段内。数据包处理&#xff1a;请求和响应报文都需要经过Di…

【YashanDB知识库】PHP使用OCI接口使用数据库绑定参数功能异常

【问题分类】驱动使用 【关键字】OCI、驱动使用、PHP 【问题描述】 PHP使用OCI8连接yashan数据库&#xff0c;使用绑定参数获取数据时&#xff0c;出现报错 如果使用PDO_OCI接口连接数据库&#xff0c;未弹出异常&#xff0c;但是无法正确获取数据 【问题原因分析】 开启O…

远程桌面失败:你的凭据不工作

远程桌面失败&#xff1a;你的凭据不工作 远程桌面失败&#xff1a;你的凭据不工作_您的凭据不工作-CSDN博客https://blog.csdn.net/weixin_38004638/article/details/82290796

java设计模式和面向对象编程思想

Java设计模式和面向对象编程思想是软件开发中的核心概念&#xff0c;对于构建可维护、可扩展的软件系统至关重要。下面是对这两个主题的知识点总结&#xff1a; 面向对象编程&#xff08;OOP&#xff09;思想 封装&#xff1a;将数据&#xff08;属性&#xff09;和操作这些数据…

Linux C编译器从零开发一

基础程序汇编 test.c int main() {return 42; } 查看反汇编 cc -o test test.c objdump -d -M intel test 0000000000001129 <main>:1129: f3 0f 1e fa endbr64 112d: 55 push rbp112e: 48 89 e5 mov rbp,rsp1131: b…

攻防世界-fakebook题目__详解

1.打开题目先用dirsearch工具扫描一波&#xff0c;扫出来了robots.php目录&#xff0c;然后访问robots.txt 目录&#xff0c;发现了有一个备份文件 &#xff0c;访问备份文件&#xff0c;下载内容 文件的大致内容如下 里面有一个curl_exec这个函数容易造成ssrf攻击的漏洞 我…

运行时类型识别RTTI(typeid dynamic_cast)和虚函数机制的关系

1.typeid 2.dynamic_cast 指针类型决定了可以操作的内存范围大小 子类指针转化为父类类型的指针的一般是合法的&#xff1a; 父类的指针类型转化为子类类型指针&#xff0c;超过合法操作范围&#xff0c;不安全 两种转换&#xff1a;编译期的转换&#xff0c;运行时的转化 编译…

四川汇聚荣聚荣科技有限公司是干什么的,拼多多运营如何做?

四川汇聚荣聚荣科技有限公司是干什么的&#xff0c;拼多多运营如何做?随着电商行业的快速发展&#xff0c;越来越多的企业开始涉足这一领域。其中&#xff0c;四川汇聚荣聚荣科技有限公司便是其中的一员。那么&#xff0c;这家公司究竟是做什么的呢?简单来说&#xff0c;它是…

【代码随想录】【算法训练营】【第35天】[134]加油站 [135]分发糖果 [860]柠檬水找零 [406]根据身高重建队列

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 35&#xff0c;连休两天~ 题目详情 [134] 加油站 题目描述 134 加油站 解题思路 前提&#xff1a;数组 思路&#xff1a;全局贪心算法&#xff1a;最小累加剩余汽油为负数&#xff0c;说明…

短视频矩阵系统源码搭建--如何基于各平台原生态坏境做开发

短视频矩阵系统源码搭建是一个涉及多个技术层面的复杂过程&#xff0c;它要求开发者能够理解并利用不同平台的原生环境来开发和部署应用程序。以下是一些基于不同平台原生环境开发短视频矩阵系统的一般步骤和考虑因素&#xff1a; 1.需求分析&#xff1a;首先明确系统需要实现的…

Python学习笔记9:入门知识(九)

缩进 什么是缩进&#xff1f; 缩进&#xff0c;简单的理解为本行的首字符相比上一行的首字符位置相对靠后。目前笔者接触的编程语言缩进一般是4字符&#xff0c;直接可以按tab键就行。 为什么突然讲缩进&#xff1f; Python这门语言&#xff0c;是依靠缩进来判断当前行与上…

ISP图像算法面试准备(1)

ISP图像算法面试准备 ISP图像算法面试准备(1) 文章目录 ISP图像算法面试准备前言一、ISP流程二、重点关注1. AWB必须在Demosaic之后进行。2. Gamma矫正通常在CCM之前进行 三、如何实现ISP参数自动化调试四、AE&#xff0c;即自动曝光&#xff08;Auto Exposure&#xff09;总结…

【深度学习】基于EANet模型的图像识别和分类技术

1.引言 1.1.EANet模型简介 EANet&#xff08;External Attention Transformer&#xff09;是一种深度学习模型&#xff0c;它结合了Transformer架构和外部注意力机制&#xff0c;特别适用于图像分类等计算机视觉任务。以下是关于EANet的详细解释&#xff1a; 1.1.1 定义与背…