48 slab 的实现

前言

这里说的是 内核中分配小对象的一种内存分配方式 slab 

呵呵 经典程度不必多说了, 内核使用的大多数数据结构 基本上是基于 slab 进行内存分配的 

这里 我们来看一下 slab 

如何分配对象  

几个分配层级, c->free_list, c->page, c->partial, new_slab 

1. 先来看一下走 new_slab 的流程 

如果尝试了 c->free_list, c->page, partial 之后都没有找到可用的 page, 那么会走 new_slab 来尝试分配新的物理页面, 这里的相关代码在 slub.allocate_slab

如下是 分配物理页 部分, 最终调用了 alloc_page, alloc_pages

然后之后 初始化 page 的 slab_cache, 初始化 freelist 为物理页 的虚拟地址

4f3df7f5b4b04ada88ef8e4fd3fa9e7e.png942c14e88070401cb8b734f73f4d23be.png

更新 kmem_cache_node 对应的统计信息

34035d7d76344b1497e22ed9e746c55a.png

然后 ___slab_alloc 是回到上面 new_slab_objects, 之后 更新 c->free_list, load_freelist

然后之后是 获取 free_list 返回, 并更新 c->free_list 为下一个空闲元素 

9309ab1730e9410e9a937aaf0661d268.pnga878cd5ff52d4546b23bef59bed8befe.png 

然后是走 后面的 slab_alloc_node 统一的一部分流程

8cd899b7b95c417987cc516105151bd0.png

2. 再来看一下走 partial 的流程 

取 partial 有几条路径, 如下这里是 取的 kmem_cache_cpu 中暂存的 partial, 然后之后 进行重试 

8e075bd190cb414dba3576d4076540fa.png

获取当前 kmem_cache_cpu 对应的 kmem_cache_node 维护的 partial 链表中获取一个可用的 page, 然后更新为 c->page, 返回 分配的对象

如果是 没有获取到空间, 则从所有的 kmem_cache_node 中尝试分配对象, 更新 c->page

56a1434d834f4d3eb49a7212f54d01f6.png

3. 再来看一下走 c->page 的流程 

这里是从 c->page 获取 free_list 的流程, 拿到 free_list 之后, 获取到空闲区间 分配对象, 然后走后面的 slab_alloc_node 统一的一部分流程

2eb5de7473dd45e5999746703fb88fb0.png

dc1d66ee1ee448f0865ab20d38e87111.png

根据 page 获取 free_list 的实现如下, cas 更新 page->free_list 为 null

获取的是 page 中暂存的 free_list

ae9977dc8d954ce98b667367f54ee27e.png

4. 再来看一下走 c->free_list 的流程, 这是 最 common 的场景 

取得是 c->free_list, 然后之后更新 c->free_list 为 next, next 是存在 next的s->offset偏移处 

687205ffecc746429517761b3e65e0a9.png

如何释放对象 

如果待释放的物理页和 kmem_cache_cpu 持有的物理页一致, 最 common 的场景 

cas 将 待释放对象添加到 c->free_list 所处的链表, 并更新 c->free_list 为 x 

5dda99bb5dfa4e329da0683723b030de.png

如果待释放的物理页和 kmem_cache_cpu 持有的物理页不一致 

cas 将 待释放对象添加到 c->free_list 所处的链表, 并更新 c->free_list 为 x 

如果当前页没有对象了, 并且 partial 的数量大于 kmem_cache 中约束的最小 partial 数量, 则从 partial, full 列表中移除当前页, 并且 更新 kmem_cache_node 的相关统计, free_pages 给定的物理页 

如果当前页 还有对象, 或者当前页需要保留

如果 当前物理页在释放对象之前已经占满, 则将当前 物理页添加到 partial 列表中

否则 直接返回 

9c0f316e49074091b29bdb0efb6a0190.png7d25523e372747a98838ad83481f98b0.png

0074ad3b8ef44724a52f1063bdc44564.png

d02e6fe8eba547e9aff81eb33e251a32.png

完 

相关推荐

  1. linux中slabslub实现区别

    2024-02-19 13:22:01       50 阅读
  2. 视觉SLAM理论与实践学习链接汇总

    2024-02-19 13:22:01       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-19 13:22:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-19 13:22:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-19 13:22:01       82 阅读
  4. Python语言-面向对象

    2024-02-19 13:22:01       91 阅读

热门阅读

  1. git提交代码冲突

    2024-02-19 13:22:01       50 阅读
  2. 第13章 网络 Page818 UDP(和TCP的比较)

    2024-02-19 13:22:01       43 阅读
  3. 解决 error: ‘make_unique’ is not a member of ‘std’

    2024-02-19 13:22:01       43 阅读
  4. 【C++】并查集

    2024-02-19 13:22:01       55 阅读
  5. 常用工具记录

    2024-02-19 13:22:01       48 阅读
  6. 2024前端面试准备之CSS篇(二)

    2024-02-19 13:22:01       61 阅读
  7. g++编译--运行opencv步骤。

    2024-02-19 13:22:01       45 阅读
  8. alibaba的fastjson怎么将json字符串转换为范型对象

    2024-02-19 13:22:01       48 阅读
  9. 动态规划-简单举例-青蛙跳台阶

    2024-02-19 13:22:01       51 阅读