Linux内存管理slub分配器

背景

  1. Kernel版本:4.14

  2. ARM64处理器,Contex-A53,双核

  3. 使用工具:Source Insight 3.5, Visio

1. 概述

之前的文章分析的都是基于页面的内存分配,而小块内存的分配和管理是通过块分配器来实现的。目前内核中,有三种方式来实现小块内存分配:slab, slub, slob,最先有slab分配器,slub/slob分配器是改进版,slob分配器适用于小内存嵌入式设备,而slub分配器目前已逐渐成为主流块分配器。接下来的文章,就是以slub分配器为目标,进一步深入。

先来一个初印象:

2. 数据结构

有四个关键的数据结构:

  • struct kmem_cache:用于管理SLAB缓存,包括该缓存中对象的信息描述,per-CPU/Node管理slab页面等;关键字段如下:

/** Slab cache management.*/
struct kmem_cache {struct kmem_cache_cpu __percpu *cpu_slab;       //每个CPU slab页面/* Used for retriving partial slabs etc */unsigned long flags;unsigned long min_partial;int size;		/* The size of an object including meta data */int object_size;	/* The size of an object without meta data */int offset;		/* Free pointer offset. */
#ifdef CONFIG_SLUB_CPU_PARTIAL/* Number of per cpu partial objects to keep around */unsigned int cpu_partial;
#endifstruct kmem_cache_order_objects oo;     //该结构体会描述申请页面的order值,以及object的个数/* Allocation and freeing of slabs */struct kmem_cache_order_objects max;struct kmem_cache_order_objects min;gfp_t allocflags;	/* gfp flags to use on each alloc */int refcount;		/* Refcount for slab cache destroy */void (*ctor)(void *);           // 对象构造函数int inuse;		/* Offset to metadata */int align;		/* Alignment */int reserved;		/* Reserved bytes at the end of slabs */int red_left_pad;	/* Left redzone padding size */const char *name;	/* Name (only for display!) */struct list_head list;	/* List of slab caches */       //kmem_cache最终会链接在一个全局链表中struct kmem_cache_node *node[MAX_NUMNODES];     //Node管理slab页面
};
  • struct kmem_cache_cpu:用于管理每个CPU的slab页面,可以使用无锁访问,提高缓存对象分配速度;

struct kmem_cache_cpu {void **freelist;	/* Pointer to next available object */                  //指向空闲对象的指针unsigned long tid;	/* Globally unique transaction id */                struct page *page;	/* The slab from which we are allocating */     //slab缓存页面
#ifdef CONFIG_SLUB_CPU_PARTIALstruct page *partial;	/* Partially allocated frozen slabs */
#endif
#ifdef CONFIG_SLUB_STATSunsigned stat[NR_SLUB_STAT_ITEMS];
#endif
};
  • struct kmem_cache_node:用于管理每个Node的slab页面,由于每个Node的访问速度不一致,slab页面由Node来管理;

/** The slab lists for all objects.*/
struct kmem_cache_node {spinlock_t list_lock;#ifdef CONFIG_SLUBunsigned long nr_partial;    //slab页表数量struct list_head partial;       //slab页面链表
#ifdef CONFIG_SLUB_DEBUGatomic_long_t nr_slabs;atomic_long_t total_objects;struct list_head full;
#endif
#endif
};
  • struct page:用于描述slab页面struct page结构体中很多字段都是通过union联合体进行复用的。struct page结构中,用于slub的成员如下:

struct page {union {...void *s_mem;			/* slab first object */...};/* Second double word */union {...void *freelist;		/* sl[aou]b first free object */...};union {...struct {union {...struct {			/* SLUB */unsigned inuse:16;unsigned objects:15;unsigned frozen:1;};...};...};       };   /** Third double word block*/union {...struct {		/* slub per cpu partial pages */struct page *next;	/* Next partial slab */
#ifdef CONFIG_64BITint pages;	/* Nr of partial slabs left */int pobjects;	/* Approximate # of objects */
#elseshort int pages;short int pobjects;
#endif};struct rcu_head rcu_head;	/* Used by SLAB* when destroying via RCU*/};...struct kmem_cache *slab_cache;	/* SL[AU]B: Pointer to slab */    ...
}

图来了:

3. 流程分析

针对Slub的使用,可以从三个维度来分析:

  1. slub缓存创建

  2. slub对象分配

  3. slub对象释放

下边将进一步分析。

3.1 kmem_cache_create

在内核中通过kmem_cache_create接口来创建一个slab缓存

先看一下这个接口的函数调用关系图:

  1. kmem_cache_create完成的功能比较简单,就是创建一个用于管理slab缓存kmem_cache结构,并对该结构体进行初始化,最终添加到全局链表中。kmem_cache结构体初始化,包括了上文中分析到的kmem_cache_cpukmem_cache_node两个字段结构。

  2. 在创建的过程中,当发现已有的slab缓存中,有存在对象大小相近,且具有兼容标志的slab缓存,那就只需要进行merge操作并返回,而无需进一步创建新的slab缓存

  3. calculate_sizes函数会根据指定的force_order或根据对象大小去计算kmem_cache结构体中的size/min/oo等值,其中kmem_cache_order_objects结构体,是由页面分配order值和对象数量两者通过位域拼接起来的。

  4. 在创建slab缓存的时候,有一个先鸡后蛋的问题:kmem_cache结构体来管理一个slab缓存,而创建kmem_cache结构体又是从slab缓存中分配出来的对象,那么这个问题是怎么解决的呢?可以看一下kmem_cache_init函数,内核中定义了两个静态的全局变量kmem_cachekmem_cache_node,在kmem_cache_init函数中完成了这两个结构体的初始化之后,相当于就是创建了两个slab缓存,一个用于分配kmem_cache结构体对象的缓存池,一个用于分配kmem_cache_node结构体对象的缓存池。由于kmem_cache_cpu结构体是通过__alloc_percpu来分配的,因此不需要创建一个相关的slab缓存

3.2 kmem_cache_alloc

kmem_cache_alloc接口用于从slab缓存池中分配对象。

看一下大体的调用流程图:

从上图中可以看出,分配slab对象与Buddy System中分配页面类似,存在快速路径和慢速路径两种,所谓的快速路径就是per-CPU缓存,可以无锁访问,因而效率更高。

整体的分配流程大体是这样的:优先从per-CPU缓存中进行分配,如果per-CPU缓存中已经全部分配完毕,则从Node管理的slab页面中迁移slab页per-CPU缓存中,再重新分配。当Node管理的slab页面也不足的情况下,则从Buddy System中分配新的页面,添加到per-CPU缓存中。

还是用图来说明更清晰,分为以下几步来分配:

  • fastpath快速路径下,以原子的方式检索per-CPU缓存的freelist列表中的第一个对象,如果freelist为空并且没有要检索的对象,则跳入慢速路径操作,最后再返回到快速路径中重试操作。

  • slowpath-1将per-CPU缓存中page指向的slab页中的空闲对象迁移到freelist中,如果有空闲对象,则freeze该页面,没有空闲对象则跳转到slowpath-2

  • slowpath-2将per-CPU缓存中partial链表中的第一个slab页迁移到page指针中,如果partial链表为空,则跳转到slowpath-3

  • slowpath-3将Node管理的partial链表中的slab页迁移到per-CPU缓存中的page中,并重复第二个slab页将其添加到per-CPU缓存中的partial链表中。如果迁移的slab中空闲对象超过了kmem_cache.cpu_partial的一半,则仅迁移slab页,并且不再重复。如果每个Node的partial链表都为空,跳转到slowpath-4

  • slowpath-4Buddy System中获取页面,并将其添加到per-CPU的page中。

3.2 kmem_cache_free

kmem_cache_free的操作,可以看成是kmem_cache_alloc的逆过程,因此也分为快速路径和慢速路径两种方式,同时,慢速路径中又分为了好几种情况,可以参考kmem_cache_alloc的过程。

调用流程图如下:

效果如下:

  • 快速路径释放 快速路径下,直接将对象返回到freelist中即可。

  • put_cpu_partialput_cpu_partial函数主要是将一个刚freeze的slab页,放入到partial链表中。在put_cpu_partial函数中调用unfreeze_partials函数,这时候会将per-CPU管理的partial链表中的slab页面添加到Node管理的partial链表的尾部。如果超出了Node的partial链表,溢出的slab页面中没有分配对象的slab页面将会返回到伙伴系统。

  • add_partial 添加slab页到Node的partial链表中。

  • remove_partial 从Node的partial链表移除slab页。

具体释放的流程走哪个分支,跟对象的使用情况,partial链表的个数nr_partial/min_partial等相关,细节就不再深入分析了。

 

  推荐阅读:

    专辑|Linux文章汇总

    专辑|程序人生

    专辑|C语言

嵌入式Linux

微信扫描二维码,关注我的公众号 

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

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

相关文章

大学计算机科学不会编码,华中科技大学人员编号编码管理办法

第一条 为进一步推进学校管理的信息化、规范化和系统化,加强对我校教职工、学生等各类人员基本信息的统一管理,结合学校实际情况,制定本管理办法。第二条 凡在我校工作、学习的教职工、学生、短期聘用人员及其他人员,均拥有由10…

逆向知识第十讲,循环在汇编中的表现形式,以及代码还原

逆向知识第十讲,循环在汇编中的表现形式,以及代码还原 一丶do While在汇编中的表现形式 1.1高级代码: #include "stdafx.h"int main(int argc, char* argv[]) {int nSum 0;int i 0;do {nSum nSum i;} while (i <100);return 0; } 高级代码很简单,只是一个简单…

数据库基础系列之一:MySQL账户

1.mysql用户创建&#xff1a; shell> mysql --userroot mysql mysql> GRANT ALL PRIVILEGES ON *.* TO montylocalhost IDENTIFIED BY something WITH GRANT OPTION; mysql> GRANT ALL PRIVILEGES ON *.* TO monty"%" IDENTIFIED BY something WITH GRANT…

计量经济学实验报告计算机,计量经济学-实验报告.doc

.PAGE.资料.经济与政法学院计量经济学实验报告班级&#xff1a; 国贸1312姓名&#xff1a; 纪方方学号&#xff1a; 2013104208实验课程计量经济学实验名称OLS的估计和检验(受约束回归模型)实验目的和内容1&#xff0e;利用SPSS计算OLS估计量2&#xff0e;对模型估计结果进行检…

做技术知道了哪些事情代表自己成熟了?

如果技术圈是一个江湖&#xff0c;每个人初入江湖的时候都懵懵懂懂的&#xff0c;从懵懂到老练&#xff0c;从老练到老油条&#xff0c;这个是一个过程&#xff0c;过程中总是有一些比较有用的观点&#xff0c;这些观点&#xff0c;就表示你从小白上升到老白的过渡。这些观点&a…

数据结构复习笔记(2)

1&#xff0c; 若入栈的元素为n,则可得到的输出序列数量为 (2n)!/(n1)(n!)(n!)。2&#xff0c; 用两个长度相同的栈S1,S2构造一个队列。在S1中进行入队操作&#xff0c;S2中进行出队操作 &#xff0c;判断队列空的条件是&#xff0c;S1和S2同时为空&#xff0c;判断队列满的条…

html兼容webki,评IE10对HTML5的完美支持

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼近期Windows 8的消息充斥着整个网络。微软将IE10集成在系统中&#xff0c;并且宣称IE10会很好的支持HTML5。本文是对IE10支持HTML5的研究报告。预览&#xff1a;HTML5初探 在过去的几年里我们做了一系列测试来评估主要的移动平台对…

用于MCU,基于FreeRTOS的micro(轻量级)ROS

编辑整理&#xff1a;strongerHuang作者&#xff1a;Francesca Finocchiaro关注我的读者中应该有部分是做ROS相关的工作&#xff0c;今天就来分享一个基于FreeRTOS的micro&#xff08;微型&#xff09;ROS。一、关于ROSROS&#xff1a;Robot Operating System,&#xff0c;即机…

惜缘-致家乡的一位女孩[原创]

命里有时终须有,命里无时莫强求.这说的应该就是缘分吧.曾经有人说,每个人来到世界上,都只有一半.然后,每个人会花一生的时间寻找另一半.无论你有意识还是无意识地去寻找你的恋人,你是不是都希望这个假设是成立的呢?至少,你知道有那样一个人在世界的那一个地方等你回来,在你找他…

【干货】同步与互斥的失败例子

韦东山老师最新录制的驱动大全之<<同步与互斥>>收费视频已经在淘宝上架销售 &#xff0c;一共7节&#xff0c;良心价29元&#xff0c;同时已经同步到CSDN , 51CTO , 电子发烧友&#xff0c;腾讯课堂等平台。本文是其中一节《同步与互斥的失败例子》视频配套文档&am…

微型计算机计算机钢琴,微型计算机原理及接口技术钢琴课程设计.doc

高频电子线路课程设计题目&#xff1a; 高 频 功 率 放 大 器 .班级&#xff1a; 08级通信1班 .姓名&#xff1a; 马宗祥 .学号&#xff1a; P081513166 .成绩&#xff1a; .组内分工成员及分工&#xff1a;程冲冲&#xff1a;低频放大马云、吴欣萌&#xff1a;振荡及调制洪学军…

TCP三次握手

以下是我做的实验 &#xff0c;180.97.33.108 是百度 以下是我自己画的图 转载于:https://www.cnblogs.com/heben/p/7879439.html

微软TechEd 2006亲历(六):微软新一代系统管理平台面纱待揭

<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />对于企业网络管理人员&#xff0c;也许没有想到微软将陆续提供it系统&#xff08;包括存储&#xff09;的管理工具。利用这些管理工具&#xff0c;企业将可以轻松、便捷地管理企业…

Linux中断子系统-通用框架处理

背景Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio1. 概述《Linux中断子系统&#xff08;一&#xff09;-中断控制器及驱动分析》讲到了底层硬件GIC驱动&#xff0c;以及Arch-Specif…

接口测试工具-fiddler的运用

本篇主要介绍一下fiddler的基本运用&#xff0c;包括查看接口请求方式&#xff0c;状态响应码&#xff0c;如何进行接口测试等 一&#xff0e;Fiddler的优点 独立的可以直接抓http请求小巧、功能完善快捷、启动就行代理方便二&#xff0e;什么是Fiddler Fiddler是一个http协议调…

微电子科学与工程要学计算机吗,微电子科学与工程专业就业前景如何 有前途吗...

微电子科学与工程专业就业前景如何&#xff1f;有前途吗&#xff1f;下面小编为大家整理了相关内容&#xff0c;以供参考&#xff0c;一起来看看吧&#xff01;微电子科学与工程专业就业前景微电子科学与工程专业近年来也逐渐热火起来了&#xff0c;竞争力也很大。微电子专业一…

利用Excel VBA畫出所有圖標

有時候﹐常感覺﹐恰當的使用Excel的VBA做些開發﹐常常收到事半功倍的效果的。從Birdshome的博客中看到這篇貼深有感觸﹐當然﹐自己以前也是使用過一段時間的VBA開發的﹐直到使用.net之后就沒有再搞那玩意兒了﹐唉....﹐感嘆一下先。順便把那里jinta2001的Excel文檔轉上來。呵呵…

我的丈母娘

2020年9月17日12点46分&#xff0c;刚进入新居我终于还是要写这篇文章了&#xff0c;想了很久&#xff0c;我觉得写一篇文章来记录下我的丈母娘。前段时间&#xff0c;小云妈妈骑车不小心把鼻子给摔破了&#xff0c;很严重&#xff0c;二哥马上回家带老人到医院检查并做了手术。…

学法语,加油!

我家小猪又折腾法语了.在大学的时候她就不学无术&#xff0c;当我专心治学的时候&#xff0c;她总是手捧闲书作认真状&#xff1b;正儿八经上课时间&#xff0c;大部分还是可以认真度过&#xff0c;但是逢到计算机课&#xff0c;她就全傻了&#xff0c;是的&#xff0c;她是计算…

华南理工大学广州学院计算机二级,华南理工大学广州学院学子在第三届“泰迪杯”数据分析职业技能大赛中荣获佳绩...

12月19日&#xff0c;第三届泰迪杯数据分析职业技能大赛落下帷幕并公示了获奖名单。华南理工大学广州学院获得国家二等奖一项&#xff0c;国家三等奖两项的好成绩&#xff0c;这是我华南理工大学广州学院首次有组织地参与该赛事。本次竞赛由计算机工程学院组织&#xff0c;同时…