Linux内核模块开发之创建slab内存缓存(kmem_cache_*)

Linux内核模块开发之创建slab内存缓存(kmem_cache_*)

  • 一、创建专用的内存缓存编程接口
  • 二、实现步骤
  • 三、内存缓存的数据结构
  • 四、完整代码示例
    • 4.1、源代码
    • 4.2、编译和执行

一、创建专用的内存缓存编程接口

  1. 创建内存缓存 kmem_cache_create。
  2. 指定内存缓存分配 kmem_cache_alloc。
  3. 释放对象 kmem_cache_free。
  4. 销毁内存缓存 keme_cache_destroy。

函数原型:

void *kmem_cache_alloc(struct kmem_cache *cachep, int flags);
void kmem_cache_free(struct kmem_cache *cachep, void *objp);

struct kmem_cache *
kmem_cache_create(const char *name, size_t size, size_t offset,
	unsigned long flags, void (*ctor)(void *));
void kmem_cache_destroy(struct kmem_cache *);

二、实现步骤

  1. 定义初始化模块和退出模块函数。
  2. 定义一个kmem_cache全局变量。
  3. 在初始化模块函数调用kmem_cache_create函数,指定模块名称。
  4. 如果创建成功,可以调用kmem_cache_size获取缓存大小。
  5. 退出模块调用keme_cache_destroy删除函数指针。
  6. 模块初始化操作和退出函数调用module_init()和module_exit()。
  7. 其他的声明信息,比如许可协议、作者、模块功能描述等等。

三、内存缓存的数据结构

(include/linux/slab_def.h)

struct kmem_cache {
	struct array_cache __percpu *cpu_cache;

/* 1) Cache tunables. Protected by slab_mutex */
	unsigned int batchcount;
	unsigned int limit;
	unsigned int shared;

	unsigned int size;
	struct reciprocal_value reciprocal_buffer_size;
/* 2) touched by every alloc & free from the backend */

	slab_flags_t flags;		/* constant flags */
	unsigned int num;		/* # of objs per slab */

/* 3) cache_grow/shrink */
	/* order of pgs per slab (2^n) */
	unsigned int gfporder;

	/* force GFP flags, e.g. GFP_DMA */
	gfp_t allocflags;

	size_t colour;			/* cache colouring range */
	unsigned int colour_off;	/* colour offset */
	struct kmem_cache *freelist_cache;
	unsigned int freelist_size;

	/* constructor func */
	void (*ctor)(void *obj);

/* 4) cache creation/removal */
	const char *name;
	struct list_head list;
	int refcount;
	int object_size;
	int align;

/* 5) statistics */
#ifdef CONFIG_DEBUG_SLAB
	unsigned long num_active;
	unsigned long num_allocations;
	unsigned long high_mark;
	unsigned long grown;
	unsigned long reaped;
	unsigned long errors;
	unsigned long max_freeable;
	unsigned long node_allocs;
	unsigned long node_frees;
	unsigned long node_overflow;
	atomic_t allochit;
	atomic_t allocmiss;
	atomic_t freehit;
	atomic_t freemiss;

	/*
	 * If debugging is enabled, then the allocator can add additional
	 * fields and/or padding to every object. 'size' contains the total
	 * object size including these internal fields, while 'obj_offset'
	 * and 'object_size' contain the offset to the user object and its
	 * size.
	 */
	int obj_offset;
#endif /* CONFIG_DEBUG_SLAB */

#ifdef CONFIG_MEMCG
	struct memcg_cache_params memcg_params;
#endif
#ifdef CONFIG_KASAN
	struct kasan_cache kasan_info;
#endif

#ifdef CONFIG_SLAB_FREELIST_RANDOM
	unsigned int *random_seq;
#endif

	unsigned int useroffset;	/* Usercopy region offset */
	unsigned int usersize;		/* Usercopy region size */

	struct kmem_cache_node *node[MAX_NUMNODES];
};

内存缓存的数据结构如下图所示:
在这里插入图片描述

四、完整代码示例

4.1、源代码

kmemd.c

/* 头文件和全局变量地声明*/
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>


static int __init kmem_cache_create_InitFunc(void);
static void __exit kmem_cache_create_ExitFunc(void);

struct kmem_cache *pmycache = NULL;

// 模块初始化函数
int __init kmem_cache_create_InitFunc(void)
{
    pmycache = kmem_cache_create("FlyCache",64,0, SLAB_HWCACHE_ALIGN, NULL);
    if(NULL==pmycache)
    {
        printk("执行:kmem_cache_create(...)函数失败,请重新检查?\n");
    }        
    else
    {
        printk("创建slab缓存成功!\n");
        printk("FlyCache Cache大小为: %d\n", kmem_cache_size(pmycache));
    }
    return 0;
}

// 模块退出函数
void __exit kmem_cache_create_ExitFunc(void)
{
    if(pmycache)
    {
        kmem_cache_destroy(pmycache);
        printk("执行:kmem_cache_destroy()函数释放slab缓存成功!\n");
    }
    printk("内核模块退出成功!\n");
}

/* 模块初始化操作和退出函数调用 */
module_init(kmem_cache_create_InitFunc);
module_exit(kmem_cache_create_ExitFunc);

MODULE_LICENSE("GPL"); /* 描述模块代码接受的软件许可协议 */
MODULE_AUTHOR("Lion Long"); /* 描述模块的作者信息:包括作者姓名及邮箱等等 */
MODULE_DESCRIPTION(" kernel module : kmem_cache_create/kmem_cache_destroy"); /* 简要描述此模块用途及功能介绍*/

Makefile

obj-m:=kmemd.o	

CURRENT_PAHT:=$(shell pwd) 
LINUX_KERNEL:=$(shell uname -r)   

LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)
all:

	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) modules

clean:

	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) cleals

4.2、编译和执行

(1)make。

$ make
make -C /usr/src/linux-headers-4.15.0-142-generic    M=/home/fly/workspace/linux_kernel  modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-142-generic'
  CC [M]  /home/fly/workspace/linux_kernel/kmemd.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/fly/workspace/linux_kernel/kmemd.mod.o
  LD [M]  /home/fly/workspace/linux_kernel/kmemd.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-142-generic'

(2)插入模块。

insmod kmemd.ko

(3)查看模块。

$ sudo dmes -c
[101921.947832] 创建slab缓存成功!
[101921.947833] FlyCache Cache大小为: 64

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试零基础好入门么

零基础学习软件测试不失为一个好的选择&#xff0c;虽然IT行业里对小白最友好的非软件测试莫属了&#xff0c;但是也要看你个人在学习软件测试这件事上面花费了多少的时间和努力了~ 每年毕业季&#xff0c;IT行业依然是比较热门且收入是最高的行业。对于应届毕业生来说想要进入…

数据结构学习之路-队列

队列&#xff08;Queue&#xff09;定义队列的接口设计&#xff08;使用双向链表&#xff09;用栈实现队列的接口设计双端队列&#xff08;Deque&#xff09;循环队列&#xff08;Circle Queue&#xff09;循环双端队列&#xff08;Ciecle Deque&#xff09;定义 队列是一种特…

企业短视频推广怎么玩?制造业短视频推广干货分享

短视频作为一种新型营销方式&#xff0c;已经成为企业推广的重要手段。通过合理的推广策略、精美的短视频制作、适当的社交媒体平台选择和与用户的互动&#xff0c;企业可以实现短视频推广的效果。同时&#xff0c;借助短视频制作工具可以提高制作效率和降低制作成本&#xff0…

文件IO知识(一)

作者&#xff1a;爱塔居 专栏&#xff1a;JavaEE 作者简介&#xff1a;大三学生&#xff0c;希望和大家一起进步。 文章目录 目录 文章目录 前言 一、路径 二、文本文件和二进制文件 三、文件系统操作 四、“字符流”和“字节流” 五、utf8和unicode 前言 平时谈到的“文件”&…

Spring 源码解析 - BeanPostProcessor 扩展接口

一、BeanPostProcessor 扩展接口 BeanPostProcessor是Spring中的一个扩展接口&#xff0c;它可以在Spring容器实例化bean之后&#xff0c;在执行 bean的初始化方法前后&#xff0c;允许我们自定义修改新的 bean实例。比如修改 bean 的属性&#xff0c;将 bean 替换为动态代理等…

《Effective Objective-C 2.0 》 阅读笔记 item6

第6条&#xff1a;理解“属性”这一概念 1. 属性的概念 “属性”&#xff08;property&#xff09;是Objective-C的一项特性&#xff0c;用于封装对象中的数据。 Objective-C对象通常会把所需要的数据保存为各种实例变量&#xff0c;实例变量一般通过“存取方法”&#xff08…

GPT-4 免费体验方法

POE 在Quora上非常受欢迎的手机聊天机器人Poe App已经集成ChatGPT助手&#xff01;除了最初集成的三个聊天机器人Sage、Claude和Dragonfly外&#xff0c;Poe现在还加入了第四位ChatGPT。由于使用了ChatGPT API&#xff0c;因此Poe拥有真正的ChatGPT。 现在更是第一批集成了GP…

JDK1.8去除永久代引入元空间的原因您知道吗

之前写了一篇文章 JVM中的堆和栈到底存储了什么 重点介绍了Java虚拟机运行时数据区中堆、栈以及方法区存储数据的相关知识很受大家欢迎&#xff0c;今天来介绍一下jdk 1.8开始引入的元空间&#xff0c;元空间的引入也是与Java虚拟机运行时存储数据有关。 元空间 JDK8之后就没…

02-Maven高级-分模块开发、依赖传递、聚合、继承(SpringBoot的部分底层原理)、多模块开发(环境切换)、Nexus私服搭建与使用

文章目录学习目标一、分模块开发与设计1. 分模块开发的意义问题导入模块拆分原则2. 分模块开发&#xff08;模块拆分&#xff09;问题导入2.1 创建Maven模块2.2 书写模块代码2.3 通过maven指令安装模块到本地仓库&#xff08;install指令&#xff09;2.4 代码演示二、依赖管理1…

高低温真空磁场探针台T8-EM5的技术参数

高低温真空磁场探针台是具备提供高低温、真空以及磁场环境的高精度实验台&#xff0c;它的诸多设计都是专用的。因此&#xff0c;高低温磁场探针台的配置主要是根据需求进行选配及设计。例如&#xff0c;要求的磁场值&#xff0c;均匀区大小、均匀度大小、样品台的尺寸等&#…

OJ系统刷题 第三篇

11202 - 任意两个数的和 时间限制 : 1 秒 内存限制 : 128 MB 编程序&#xff0c;电脑任意输入两个整数&#xff0c;计算出他们的和。 输入 a b&#xff08;a b为整数&#xff0c;范围是-2,147,483,648~2,147,483,647&#xff09; 输出 ab的和 样例 输入 1 1 输出 2 答案&a…

含分布式电源的配电网可靠性评估研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

外网访问本地Tomcat服务器【cpolar内网穿透】

文章目录前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置3.公网访问测试4.结语前言 Tomcat作为一个轻量级的服务器&#xff0c;不仅名字很有趣&#xff08;让…

第二届ACC(AcWing Cup)全国联赛 C4943. 方格迷宫

题意 题目大意就是给定一个地图&#xff0c;给定一个起点和终点&#xff0c;要求我们以最小步数到达终点&#xff0c;其中不可以落入陷阱并且每步可以走1−−k步题目大意就是给定一个地图&#xff0c;给定一个起点和终点&#xff0c;要求我们以最小步数到达终点&#xff0c;其中…

基于粒子群优化算法的分布式电源选址与定容【多目标优化】【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

crud删除(1.5小时)

一、servlet删除 页面效果 删除一个重复的韩非&#xff0c;可以看到无论是list显示还是navicate全都删除成功了 编写servlet页面时一定要注意&#xff0c;我们不光要在list页面开辟一个新的单元格以及加上超链接&#xff0c;还要给它传入当前行的id参数&#xff0c;这样delete…

企业如何利用大数据精准获客

打造大数据硬核组织 运营商大数据精准获客&#xff0c;助力企业高效获客 导语 获客难、成本高一直是困扰各个企业的一大难点。在大数据获客弥漫的今天&#xff0c;我们仿佛看见了眼前影影绰绰的都是客户&#xff0c;但当伸手去抓&#xff0c;却发现寥寥无几&#xff0c;什么…

Web-Http基本概念(请求与响应)

目录 1、http请求 &#xff08;1&#xff09;get &#xff08;2&#xff09;host &#xff08;3&#xff09;accept &#xff08;4&#xff09;referer &#xff08;5&#xff09;accept-language &#xff08;6&#xff09;user-agent 2、http响应 &#xff08;1&…

Linux 文件系统是怎么工作的?

同 CPU、内存一样&#xff0c;磁盘和文件系统的管理&#xff0c;也是操作系统最核心的功能。 磁盘为系统提供了最基本的持久化存储。 文件系统则在磁盘的基础上&#xff0c;提供了一个用来管理文件的树状结构。 那么&#xff0c;磁盘和文件系统是怎么工作的呢&#xff1f;又有…

毕业设计源码基于springboot的旧物置换系统的实现

摘 要 随着时代在一步一步在进步&#xff0c;旧物也成人们的烦恼&#xff0c;许多平台网站都在推广自已的产品像天猫、咸鱼、京东。所以开发出一套关于旧物置换网站成为必需。旧物置换网站主要是借助计算机&#xff0c;通过对用户进行管理。为减少管理员的工作&#xff0c;同…