[linux kernel]slub内存管理分析(0) 导读

news/2024/12/2 23:39:14/

文章目录

    • 简介
    • 整体目录
    • SLUB中的结构体关系图
    • kmalloc 申请逻辑
      • 逻辑图
      • 逻辑简述
    • kfree 释放逻辑
      • 逻辑图
      • 逻辑简述
    • slab page状态转换关系图

简介

linux 内核内存管理算法有管理页面分配的伙伴算法,和对于小块内存的slab、slob、slub算法。其中slab是slob和slub的基础,slob多用于嵌入式设备中,目前linux内核中用到的内存管理算法是slub。本次分为下面几个章节从源码出发分析slub算法。我用的源码不是最新的是linux-5.13版本,主要是最开始看的时候用的这个版本,注释都写在这里,写博客的时候懒得换最新的了,可能有一些错误,欢迎指正。

整体目录

本系列文章从slub算法的结构体分析起,包括初始化、kmalloc申请操作、kfree释放操作和最后的销毁操作以及一些其他相关知识。

[linux kernel]slub内存管理分析(0) 导读

[linux kernel]slub内存管理分析(1) 结构体

[linux kernel]slub内存管理分析(2) 初始化

[linux kernel]slub内存管理分析(2.5) slab重用

[linux kernel]slub内存管理分析(3) kmalloc

[linux kernel]slub内存管理分析(4) 细节操作以及安全加固

[linux kernel]slub内存管理分析(5) kfree

[linux kernel]slub内存管理分析(6) 销毁slab

[linux kernel]slub内存管理分析(7) MEMCG的影响与绕过

SLUB中的结构体关系图

slub 算法中涉及的结构体不多,总共只有:

  • struct kmem_cache
  • struct kmem_cache_cpu
  • struct kmem_cache_node
  • struct page

他们之间的关系如下图:

在这里插入图片描述

kmalloc 申请逻辑

逻辑图

在这里插入图片描述

逻辑简述

其实slab 就是几级缓存机制,从cpu_slab 分配最快,能从cpu_slab当前freelist 分配就从cpu_slab当前freelist 分配,不能则从partial 列表中把一个slab page拿出来放到freelist,如果还没有就从node 里找slab page,都没有再新申请slab page。

  • 首先判断请求kmalloc分配内存的大小,大于slab可以分配的上限(通常8k)则调用kmalloc_large进行分配。
    • kmalloc_large 则直接根据大小调用伙伴系统分配适当的页数。
  • 其他大小可以使用slab申请,则根据申请flag 和申请大小计算出kmalloc_caches的类型和index,获取对应的slab管理结构体。
    • 如果flag 存在ACCOUNT相关可能要切换到计数后slab,即kmalloc-cg相关slab(slab_pre_alloc_hook)
    • 获得slab 之后获取当前cpu 的cpu_slab,如果当前cpu_slabfreelist 不为空,则直接将freelist 的第一个分配返回,然后freelist向后移动,更新tid等。
    • 如果cpu_slabfreelist 为空,则看cpu_slabpartial 链表是否为空,不为空则将partial 链表第一个slab page 切换给cpu_slab freelist,然后分配,partial指向下一个slab page。
    • 如果以上都失败,说明cpu_slab无法完成分配,需要新slab,则会找到合适当前运行cpu 的内存node所属kmem_cache_node结构,查询partial 链表是否有可用slab page有的话将这个slab page给cpu_slab ,然后也从这个node取出一些slab page补充到cpu_slab->partial,然后从freelist 分配一个,跟上面一样。
    • 如果还是没有,则调用new_slab申请一个全新slab page,从新slab page的freelist 分配。

kfree 释放逻辑

逻辑图

在这里插入图片描述

逻辑简述

内存对象释放主要思路就是,如果是页面对象,则直接伙伴系统释放,如果是slab 对象,如果在cpu_slab中,在cpu_slab中释放,如果不是,则根据释放之前之后的状态(为空、为满、半满),进行不同的操作。

  • 首先找到释放的内存对象所在的page 的page结构体。如果该page不是slab,也就是说内存对象不是通过slab分配的,而是直接分配的页(大块内存),那么直接释放页。

    • 大块内存分配的时候就是从伙伴系统直接分配的页,释放的时候页通过伙伴系统释放页面(__free_pages)
  • 其他内存是通过slab分配,则通过slab释放(slab_free)

    • memcg相关处理(memcg_slab_free_hook)

    • 获取当前cpu_slab,如果要释放的内存对象正好属于当前cpu_slab(可以理解为是否是从当前cpu_slab分配的),则快速释放

      • 获取cpu_slabfreelist,将该内存对象插入freelist头部,刷新cpu_slab相关信息(do_slab_free)
    • 如果要释放的内存对象不属于当前cpu_slab,(当前slab page在cpu_slab->partial、别的cpu_slab->page、别的cpu_slab->partial、游离状态、node->partialnode->full6种情况),需要慢速释放(__slab_free)

      • 先把内存对象释放到slab page的freelist头部,更新slab page相关统计信息
      • 如果该slab page为冻结状态(说明是在cpu_slab中的三种情况)
        • 则直接结束(已经将object 放到page->freelist了,剩下的就不用管了)
      • 如果释放前该slab page是满的(freelist为空),则说明page目前是游离状态(不在任何列表中)或node->full
        • 如果开启cpu->partial,则将该slab page放到cpu_slab->partial中(从node->full中移除)
          • 如果cpu_slab->partial满了,则要将当前cpu_slab->partial中的所有slab page放到node->partial中,然后再将新的slab page放到cpu_slab->partial
        • 否则放入node->partial中(从node->full中移除)
      • 如果释放后为空,则说明目前该slab page一定处在node->partial列表中,因为如果在cpu_slab或者游离状态或node->full中不管释放完是否为空,都会在上面的步骤中处理完毕
        • 如果当前slab 管理的partial页面数量满足最小要求,则将该释放后为空的slab page释放掉(__free_pages)
        • 否则不变,继续呆在node->partial
      • 否则说明该page是本来就呆在node->partial中的半满page,并且释放后还是半满,则什么也不操作。

slab page状态转换关系图

结合kmallockfree的逻辑,可以画出slab page的状态转换关系图:

在这里插入图片描述


http://www.ppmy.cn/news/38889.html

相关文章

开心档之开发入门网-C++ 有用的资源

C 有用的资源 目录 C 有用的资源 C 有用的网站 C 有用的书籍 以下资源包含了 C 有关的网站、书籍和文章。请使用它们来进一步学习 C 的知识。 C 有用的网站 C Standard Library headers − C 标准库。C Programming − 这本书涵盖了 C 语言编程、软件交互设计、C 语言的现…

CMake入门教程【基础篇】4.target_include_directories包含指定文件夹头文件

target_include_directories包含指定文件夹头文件 文章目录 知识点实例代码目录代码实现编译知识点 target_include_directories() 指定目标包含的头文件路径 实例 代码目录 |-📁prj3   |-- 🎴CMakeLists.txt   |-📁include    |-- 📄Hello.h   |-📁src…

java面试准备17

事务的四大特性 (1)原子性:事务执行的最小单位,不可被分割,事务的原子性保证事务中的一连串动作要么都执行,要么都不执行。 (2)一致性:执行事务前后的数据保持一致&…

Linux-Git

一、总论 1.1 写在前面的话 ​ 这已经是我第三遍学Git相关操作了,可以说这个玩意是真的狗,因为确实用不到,不知道下个学期会不会用到,直到现在我刚刚学完,处于知识水平的巅峰,知道Git的具体功能&#xff…

Linux系统,centos7系统安装以及使用教程

CentOS 7是一种基于Linux的操作系统,是红帽(Red Hat)企业版操作系统代码的开源再编译版本,是一种稳定、可靠、高性能的服务器操作系统。下面是一份CentOS 7系统的教程。 1.安装CentOS 7 下面介绍通过 DVD 安装 CentOS 7 的步骤: 1) 首先你…

gpt中文版下载-gpt3中文自动生成小说

chat软件怎么用 您可以通过以下步骤尝试使用OpenAI的Chat软件。 首先,访问OpenAI的网站。您可以在该网站上了解OpenAI的项目和产品,并获取相关信息。 在OpenAI的网站上,点击右上角的“Sign In”(登录)按钮。如果您没…

OpenCV实战(13)——高通滤波器及其应用

OpenCV实战(13)——高通滤波器以及应用 0. 前言1. 检测图像边缘1.2 Sobel 滤波器1.2 梯度算子1.3 高斯导数2. 图像拉普拉斯算子2.1 拉普拉斯算子2.2 使用拉普拉斯算子增强图像的对比度2.3 高斯差3. 完整代码小结系列链接0. 前言 在频域分析中,滤波器是一种放大图像某些频带…

【独家】华为OD机试 - 机智的外卖员(C 语言解题)动态规划

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:机智的外卖员 题目描述: 外…