LWN:5.17 中的struct slab!

page _refcount和_mapcount字段 linux page有两个非常重要的引用计数字段_refcount和_mapcount,都是atomic_t类型,其中,_refcount表示内核中应用该page的次数。当_refcount = 0时,表示该page为空闲或者将要被释放。当_refcount > 0,表示该page页面已经被分配且内核正在使用,暂时不会被释放。 阅读详情


关注了就能看到更多这么棒的文章哦~

Struct slab comes to 5.17

By Jonathan Corbet
January 14, 2022
DeepL assisted translation
https://lwn.net/Articles/881039/

正在进行的 memory folio 工作已经在内核的大部分地方产生了波及,并激发出了一些辅助项目(side project),其中之一就是从 struct page 中移除 slab 特定的一些字段。这项工作在 5.17 版本的内核中已被合入 mainline,因此,现在是一个很好的时机来了解 struct slab 的状况,以及了解为什么这项工作很重要了。

struct page and struct slab

page structure 是内存管理子系统的核心。系统中的每一个物理内存 page 都对应着这样一个结构,用它们来跟踪相应内存的状态,随着内存在系统的生命周期中被使用、释放和重用,都需要用到它。随着时间的推移,物理 page 可以采用许多不同的形式了,它们可以放置用户空间的数据,或者内核数据结构,又或者是 DMA buffer 等等。不管某个 page 是如何使用的,都是使用 struct page 来作为跟踪其状态的数据结构。这些 struct 存放在一个 discontinuous array 中(也称为 system memory map )。

这种做法也出现了一些问题。4.18 版本对 page structure 进行了大规模的重写,但 struct page 的定义仍然包含很多 #ifdefs 并且使用了 unions 来构成的一个复杂的混合物,没有任何机制来确保人们总是能使用正确的字段(field )。开发者如果需要在这个结构中利用一些字节的话,很不幸,很难确定出哪些 bit 可以安全地使用起来。子系统通常在设计上都会隐藏其内部的数据结构,但是 struct page 却在整个内核里面到处都在使用,因此导致在内存管理中做任何改变都面临着更加复杂的情况。人们希望通过确保不用每个 page 都分配一个 structure 来减少 page struct 所占用的内存总量,不过在目前的代码组织情况下只是一个遥远的梦想。

因此,有很多好理由来推动人们要从 struct page 里面删除掉更多的内容,并将仍然保留的信息隐藏在内存管理子系统内部。对 folio 的讨论得出的结果之一是,人们希望重新处理一下 struct page,但这个工作是一件很可怕的事情,或者说不耐烦的人无法完成的工作。要达成这个目标就需要很多步骤。在 5.16 版本中把 folio 的初始 patch 合并,就是其中的一个步骤。5.17 版本中的 struct slab 出现,则是另一个步骤。

内核中有许多内存分配器(memory allocator),其中有两个是内存管理子系统的最核心功能,负责了正在运行的系统中的大部分内存分配工作。page allocator 只会以 page 为单位进行内存管理,正如它的名字所示,因此当需要大量的内存时就会使用它来分配。而 slab allocator 则可以高效处理较小对象的分配,包括那些用 kmalloc()等函数来进行的内存分配。slab allocator 会从 page allocator 中获得一个或多个 page 组成的一块连续内存,然后把这个大块内存分割成很小块内存,返回给申请内存的用户。实际上,内核里支持三种 slab allocator(下面会提到),但必须在 kernel config 的时候就从中确定选择哪一个。

当 slab allocator 分配 page 时,这些 page 在相关的 struct page 里面都会标记成 slab page,而这些结构中的许多字段的含义也会因此而改变。slab 相关的特定信息实际上并不是必须要在 struct page 中,而且 slab allocator 也不应该需要访问该结构中的其他信息,但事实是目前这些信息都被混在了一起。

Changes for 5.17

人们想要纠正这种情况,第一步就是把 struct slab 分离独立出来。目前,slab struct 实际上是 page struct 的一个 overlay,因此事实上仍在使用同一片内存空间,但新的 slab struct 就把 struct page 隐藏了起来,并限制 slab allocator 只使用存储在那里的 slab 相关的特定数据。这项工作最初是由 Matthew Wilcox 完成的,作为了 folio 工作的一部分,后来由 Vlastimil Babka 接手并推动其完成。

内核目前支持三种板块分配器。SLAB(最早版本的 allocator),SLUB(一个较新开发的分配器,专注于提高可扩展性,通常用在除了嵌入式应用之外的地方),以及 SLOB(一个用于内存非常有限的系统的很小的 allocator)。内核会使用的 allocator 需要在构建时通过 config 选项来指明。Babka 对 patch set 所做的改变之一就是进一步缩小了 slab struct 的定义,使其只包括当前系统中选中的 allocator 所需的那些字段。目前还是使用带有若干 #ifdef 代码的唯一一个 struct slab 定义,但建议大家去看看去掉 #ifdef 之后的最终样子。如果选择了 SLAB allocator,struct slab 的最终结果是这样的:

struct slab {
    unsigned long __page_flags;
    union {
        struct list_head slab_list;
        struct rcu_head rcu_head;
    };
    struct kmem_cache *slab_cache;
    void *freelist;    /* array of free object indexes */
    void *s_mem;    /* first object */
    unsigned int active;
    atomic_t __page_refcount;
#ifdef CONFIG_MEMCG
    unsigned long memcg_data;
#endif
};

(在LWN原文,跟具体 allocator 相关的特有字段以粗体显示)。如果选择的是 SLUB,这个结构就变成了:

struct slab {
    unsigned long __page_flags;
    union {
        struct list_head slab_list;
        struct rcu_head rcu_head;
#ifdef CONFIG_SLUB_CPU_PARTIAL
        struct {
            struct slab *next;
            int slabs;    /* Nr of slabs left */
        };
#endif
    };
    struct kmem_cache *slab_cache;
    /* Double-word boundary */
    void *freelist;        /* first free object */
    union {
        unsigned long counters;
        struct {
            unsigned inuse:16;
            unsigned objects:15;
            unsigned frozen:1;
        };
    };
    unsigned int __unused;
    atomic_t __page_refcount;
#ifdef CONFIG_MEMCG
    unsigned long memcg_data;
#endif
};

如果用的是 SLOB,则是:

struct slab {
    unsigned long __page_flags;
    struct list_head slab_list;
    void *__unused_1;
    void *freelist;        /* first free block */
    long units;
    unsigned int __unused_2;
    atomic_t __page_refcount;
#ifdef CONFIG_MEMCG
    unsigned long memcg_data;
#endif
};

这种组织结构有助于确保一个 slab allocator 不会去意外地使用属于另一个 slab allocator 的特有字段,从而在类型安全(type safety)方面带来更多好处。

新改过的这个结构定义在了 mm/slab.h 中,它不在 include 之下,因此它不能被内存管理子系统之外的代码所用。这给 x86 bootmem allocator 以及 zsmalloc() 带来了麻烦,因为它们都在使用 page struct 中的 slab 相关的一些字段,尽管这些代码并不是一个 slab allocator。这部分代码已经被改为使用 struct page 中的其他字段,而且还添加了注释,提醒说这种用法应该在今后的某一天被清理掉。

同时,slab allocator 中的代码也被修改为使用新的结构,在调用栈的一开始就改成使用新的这个 struct。这就将 slab 的大部分代码与 struct page 隔离开来,为今后的工作铺平了道路,也就是未来可以完全分离这两种 struct 了,并允许根据需要来动态分配 slab structure。

最终结果是为 slab allocator 在系统的 memory map 中有了更清晰的视图,开始将它们与底层的内存管理细节分开,并增加了 type safety (类型安全)。同时,Linux 用户应该不会受到任何影响,并且如果幸运的话,今后的 bug 数量也会有所减少。在更远的将来,可能会有这样一个时刻:struct slab 可以被动态分配并完全从 memory map 中分离出来。不过这种改动还需要一段时间。同时,清理内存管理的核心类型则是朝着正确方向迈出的一步。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

7af77da6d990103222f6caa1bf74a688.png

linux内核内存分配(二、struct slab和struct kmem_cache) 前一篇blog linux内核内存分配(一、基本概念) 主要是分析linux内核内存的分配和物理页分配函数接口。但是在实际的操作中,不一定所有内存申请都需要一个物理页,很多只是需要分配几K大小的内存就可以。所以就需要更小的内存分配函数。刚开始看这个有点不懂,不过懂了就很简单了。哈哈。         摘抄《深入linux设备驱动程序内核机制》的一段话:slab分配器的基本思想是,先利用页面分配 阅读详情

相关推荐

LSTM cell结构的理解和计算

LSTM是传统RNN网络的扩展,其核心结构是其cell单元,网上LSTM的相关资料繁多,质量参差不齐,下面主要结合LSTM神经网络的详细推导和 Christopher Olah的blog两篇文章中的内容进行说明。主要介绍网络如何计算,为何这么算先不展开:)。前者一副图加上29个公式,简洁明了;后者娓娓道来,适合初学者。首先是LSTM cell最常见的结构图: 这是变形的版本(找不到更清晰的版本了),

songhk0209的博客 2万+

linux内核内存管理slab

linux内存管理核心是伙伴系统,slab,slub,slob是基于伙伴系统之上提供api,用于内核内存分配释放管理,适用于小内存(小于1页)分配与释放,当然大于1页,也是可以的.小于一页的,我们也可以直接用伙伴系统api申请内存和释放,但伙伴系统最小单位是页,如果我们只需要100byte,伙伴系统申请内存最小1页(一般情况1页是4k, 具体看系统PAGE_SHIFT定义),显然就很浪费。

子木 1866

Temporal Anti-Aliasing(时域抗锯齿TAA)

首先说一下走样:一般分为时域走样(如旋转车轮)和空域走样(锯齿),但在 TAA 技术是采用时域相关叠加混合技术来解决空域走样的问题。 简单看一下空域抗锯齿 (Spatial Anti-Aliasing, SAA)相关技术,最普及的莫过于 MSAA,被各大渲染引擎采用,但是 MSAA 并不适用于延迟渲染 (Deferred Rendering),随之出现了很多基于形态学的后处理抗锯齿技术,如 MLAA,FXAA,SMAA 等(具体看参见图形_反走样技术总结相关介绍),虽然他们表现良好且支持延迟渲染,但是都会面

qq_35312463的博客 1万+

linux内核中slab定义,linux内核内存分配(二、struct slab和struct kmem_cache)

前一篇blogslab思想摘抄《深入linux设备驱动程序内核机制》的一段话:slab分配器的基本思想是,先利用页面分配器分配出单个或者一组连续的物理页面,然后在此基础上将整块页面分割成多个相等的小内存单元,以满足小内存空间分配的需要。当然,为了有效的管理这些小的内存单元并保证极高的内存使用速度和效率。slab分配器结构首先看下一张图,这是一张非常经典的图(所以也是从别的地方截取过来的,哈哈)基本...

weixin_35891744的博客 699

SQLSTATE58030

在优化一条SQL的时候遇到了执行错误 gtlions =# select t1.telnumber,t2.ua,t2.url,t1.apply_name,t2.apply_name from tb1 t1 gtlions -# left outer join tb2 t2 on t1.sid = t2.ipsid gtlions-# where t1.sum_date=20141128 a

Gtlions Tracker 3659

TikTok Shop API密钥获取与PHP实战对接指南

本文详细介绍了TikTok Shop API密钥的获取流程与PHP实战对接方法。从开发者后台创建应用、获取核心的API密钥开始,逐步解析OAuth 2.0授权机制,并提供了完整的PHP封装类示例,涵盖签名生成、API调用、令牌刷新及错误处理,帮助开发者快速实现与TikTok Shop的数据对接与自动化操作。

weixin_29300241的博客 400

linux 内存管理分析之-----SLAB层

SLAB层:               想必大多数人一提起linux内存管理,第一反应是"啊,特么的怎么这么复杂",哈哈,其实就是看书时蒙蔽了,别急,兄弟我陪你捋捋. 正经的来吧:  (1)             先说说平时编程吧,实现个链表,给每个元素申请空间,用的时候添加链表,不用是删除,释放空间,俗话说的增删改查嘛,可是这个效率方面到底高不高呢?答案是:我特么的怎么知道,又不是搞导

liuchen_csdn的博客 4782

告别手动抓信号!Synopsys AXI VIP的Port Monitor实战:5分钟搞定与Scoreboard的TLM连接

本文详细介绍了Synopsys AXI VIP的Port Monitor功能,帮助验证工程师快速实现与Scoreboard的TLM连接,5分钟内完成自动数据收集。通过实战指南和常见问题排查,提升验证效率,告别手动抓信号的繁琐流程。

weixin_30565327的博客 299

LWN:folio的最新情况!

关注了就能看到更多这么棒的文章哦~A memory-folio updateBy Jonathan CorbetMay 4, 2022LSFMMDeepL assisted translationhttps://lwn.net/Articles/893512/folio 项目还不到两年,但它已经导致了对内核的内存管理以及文件系统层的重大改变。虽然已经做了很多工作,但仍有不...

Linux News搬运工 1448

CloudCompare 和 PCL:点云网格化分析与处理

点云网格化是将点云数据转化为规则网格的过程,其主要思想是将离散的点云投影到一个平面上,然后对该平面进行划分,形成一系列小区域。在点云网格化方面,PCL 提供了各种算法和工具,可以实现高效的点云网格化操作。以上示例代码中,首先加载了输入的点云数据,然后通过设置合适的网格化算法参数,如搜索半径和最大三角形边长等,执行了网格化操作,最后将网格化结果保存到输出文件中。以上示例代码中,首先加载了输入的点云数据,然后通过设置合适的网格化参数,如分辨率等,执行了网格化操作,最后将网格化结果保存到输出文件中。

TechPulseZ的博客 1290

eCognition易康操作教程(一):如何利用eCognition易康软件进行影像分割之棋盘分割、四叉树分割、光谱差异分割

进程执行完成后,植被覆盖区域与裸地区域合并了。第三步:清除分割结果,点击“Image Objects”菜单栏,点击“Delete Level(s)”,选中“ResultLevel1”,点击”ok”删除棋盘分割结果。四叉树分割之后,有的正方形大一些,有的正方形小一些,大说明该区域的光谱特性更加均一,而小说明不太均一。Leve:选择运行算法的矢量层名称,这里选择四叉树分割算法得到的矢量层“ResultLevel2”。Image Layer weights:图层权重,这里设置为“1,1,1,1”。

蒹葭苍苍 4608

Linux内核内存管理

Linux内核内存管理,页,slab,高端内存,每cpu变量,进程地址空间,伙伴算法

chenxiaosongcsdn的博客 3324

镜头像差之五——场曲

什么是场曲? 场曲[curvature of field] 物面上所有的点经过系统后,最佳焦点位置不在同一平面上,若这些像点所成的面为曲面,则称为系统有场曲。 与物高二次方、入射光瞳口径一次方成正比的像差。若仅存在场曲,则所有物平面上的点都有相应的像点,但分布在一个球面上;若采用弯成此种形状的底片,则可获得处处清晰的像。此时在理想像平面上,像点呈现为圆斑。 第一张图是最简单也是最容易理解的场曲,也就是对焦点锐利,其余部分逐渐松散,但实际上大多现代镜头的场曲都呈现为图二的形态:对焦点与边缘锐度.

camerall 1万+

Rust在Linux内核中的应用与优化实践

Rust作为一种内存安全的系统编程语言,近年来在Linux内核开发中展现出显著的技术价值。其所有权模型和类型系统有效解决了传统C语言中的内存安全问题,特别适用于驱动开发和内核模块编写。通过双堆内存管理和智能指针封装,Rust与内核现有基础设施实现了无缝集成,在GPIO、I2C等子系统中已得到验证。工程实践中,Rust模块通常能减少40%代码量并消除内存安全漏洞,尽管可能带来约5%的上下文切换开销。随着谷歌等企业推动Rust在Binder驱动等核心组件的应用,其在内核中的占比正快速增长。当前技术焦点集中在稳定

weixin_30552811的博客 400

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Linux内核问题驱动式调试导航图

Linux内核调试是操作系统工程实践的核心能力,其本质是将抽象机制(如进程调度、内存管理)与具体故障现象(如D状态卡死、page fault无法定位)建立可验证的因果链。理解内核源码阅读的关键不在于通读,而在于掌握‘问题—现象—路径—验证’四步法,借助内核调试工具链(ftrace、perf、crash)实现从dmesg日志到源码行号的秒级定位。技术价值体现在大幅压缩debug_cost(实测平均降低75%)、支撑多版本内核(4.19至6.1)的精准适配,并在嵌入式IoT、云原生内核模块、现场故障排查等场景中

weixin_34080571的博客 332

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

linux内核中slab定义,Linux内核中内存cache的实现

1. 前言kmem_cache是Linux内核提供的快速内存缓冲接口,这些内存块要求是大小相同的,因为分配出的内存在接口释放时并不真正释放,而是作为缓存保留,下一次请求分配时就可以直接使用,省去了各种内存块初始化或释放的操作,因此分配速度很快,通常用于大数量的内存块分配的情况,如inode节点,skbuff头, netfilter的连接等,其实kmalloc也是从kmem_cache中分配的,可通...

weixin_31786973的博客 374

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

slab原理总结

slab详解: https://blog.csdn.net/cosmoslhf/article/details/42743101 总结: 内存分为静态内存和动态内存,静态内存在编译的时候就分配好了,这里主要讲的是动态分配内存。kmalloc分配内存是根据所要的大小在malloc_sizes的数组里寻找与之大小相匹配的stuct kmem_cache对象。每个stuct kmem_cache对象只管理一种内存大小的内存,而且它有两个重要成员,一个是struct array_cache对象,另一个是str

ask_true的博客 382

详解slab机制(2) 创建slab的过程

2.2、创建slab的过程: 现在去看结构kmem_cache的各个成员定义是很模糊的,直接看函数源码: struct kmem_cache * kmem_cache_create (const char *name, size_t size, size_t align,          unsigned long flags, void (*ctor)(void *)) {    

u010246947的专栏 2959

Linux内存管理之SLAB原理浅析。

前言 1.以下这篇文章是2015年我所在的via-telecom小组学习内存知识时整理的笔记。最近复习内存管理又拿出来看了一遍,庆幸当时阅读时留了这份笔记,不然重头看又要花费很多时间。当时画了很多visio图片且加上了via-telecom的copyright。虽然目前via-telecom被intel收购了,为了纪念在via-telecom的岁月暂且保留这些copyright。如果涉及了版权问...

月出皎兮。 佼人僚兮。 舒窈纠兮。 劳心悄兮。 2万+

Slab块分配器详解

slab块分配器学习笔记——包括slab思想及数据结构、高速缓存描述符结构、每处理器数组缓存、内存回收等内容。

qq_41952309的博客 1844

Linux内存管理之slab机制(释放对象)

Linux内核中将对象释放到slab中上层所用函数为kfree()或kmem_cache_free()。两个函数都会调用__cache_free()函数。 代码执行流程: 1,当本地CPU cache中空闲对象数小于规定上限时,只需将对象放入本地CPU cache中; 2,当local cache中对象过多(大于等于规定上限),需要释放一批对象到slab三链中。由函数cache_flusha

bullbat的专栏 4502

Linux内存管理之slab机制(创建cache)

Linux内核中创建cache节点由函数kmem_cache_create()实现。 该函数的执行流程: 1,从全局cache_cache中获得cache结构,因为全局cache_cache初始化对象的大小就是kmem_cache结构的大小,所以返回的指针正好可以转换为cache结构;调用 kmem_cache_zalloc(&cache_cache, gfp); 2,获得slab中碎片大小

bullbat的专栏 6553

详解slab机制

http://blog.csdn.net/u010246947/article/details/10133101 目前有很多讲slab的文章,要么是纯讲原理画一堆图结合源码不深导致理解困难,要么是纯代码注释导致理解更困难,我在猛攻了一周时间后,细致总结一下slab,争取从原理到源码都能细致的理解到并立刻达到清楚的使用。 一、slab分配器概述: 有了伙伴系统buddy,我们可以以页为单位获取

cosmoslhf的专栏 1万+

kernel hacker修炼之道之内存管理-SLAB(SLAB的基本数据结构)

kernel hacker修炼之道之内存管理-SLAB 作者:李万鹏 于北京 borqs 2011.9.13 21:15 本SLAB系列文章从几个方面讨论: ...

tomhibolu 358

Linux2.6 Slab系统机制解析(一)slab系统理论

介绍Linux2.6.12.6 Slab分配器的理论知识。从slab系统结构角度介绍slab分配器的三层结构;从slab精细结构角度介绍slab页面内的具体设计排列;并介绍了slab的对齐机制和染色机制,引入array本地缓存机制。并对slab系统的数据结构源码做了解析。

远见望远的博客 1454

slab机制的原理

slab获取 - 效率最高的获取方法 分配和释放数据结构是所有内核中最普遍的操作之一。为了便于数据的频繁分配和回收,常常会用到一个空间链表。它就相当于对象高速缓存以便快速存储频繁使用的对象类型。在内核中,空闲链表面临的主要问题之一是不能全局控制。当可用内存变得紧张的时候,内核无法通知每个空闲链表,让其收缩缓存的大小以便释放一些内存来。实际上,内核根本不知道有这样的空闲离岸边。为了弥补这一缺陷,也为了是代码更加稳固,linux内核提供了slab层(也就是所谓的slab分类器),slab分类器扮演了通用数据结构

C/C++Linux、音视频、DPDK 2387
上一篇: LWN: 把LibreOffice Online束之高阁!
下一篇: LWN:何时以及为何需要废弃一些文件系统?
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值