内存管理篇-14kmalloc机制实现分析

ops/2024/9/25 11:39:04/

        引入这个kmalloc的目的,是因为前面的slab接口太过于复杂,因此需要一个全新的封装kmalloc接口,内存申请编程接口实现。kmalloc底层起始也是基于slab缓存实现的

1.kmalloc 调用流程

  1. 参数解析: 解析 gfp_mask 参数,确定分配时是否可以睡眠、是否需要零初始化等。解析 size 参数,确定要分配的内存大小。
  2. 查找缓存:(1)根据请求的大小 size 查找合适的缓存。(2)如果找不到合适的缓存,则可能需要创建一个新的缓存。
  3. 分配对象:(1)从找到的缓存中分配一个对象 (2)如果缓存中的对象不足,则可能需要创建一个新的 slab。(3)如果需要,初始化分配的内存为零。
  4. 返回结果: 返回指向分配的内存块的指针。

 大概实现方式示例

#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/kmalloc.h>
void *kmalloc(size_t size, gfp_t gfp_mask)
{struct kmem_cache *cache;void *ptr;// Find the appropriate cachecache = find_kmem_cache(size);// Allocate from the cacheptr = kmem_cache_alloc(cache, gfp_mask);// Initialize memory if requiredif (gfp_mask & __GFP_ZERO)memset(ptr, 0, size);return ptr;
}static struct kmem_cache *find_kmem_cache(size_t size)
{return kmem_cache_find(size);
}

 2.函数的实践

 3.实现源码解析

        总结下来就是说,kmalloc函数最终调用的是kmem_cache和伙伴系统来实现的,它比kmem_cache那套函数接口实现要简单很多。

当申请的内存大于8KB的时候:        

        如果不是slob,并且大小于8KB,然后去获取索引:index = kmalloc_index(size)。接下来就通过kmem_alloc_trace申请内存。上节说到slab通过一些列的kmem_cache链表连接组成,获取索引(实际上就是order)之后需要找到对应的kmem_cache,kmem_cache_alloc_trace函数根据前面的索引,再到对应的slab上获取对应的内存。

        kmem_cache_alloc_trace函数需要的参数就比较明显了:(1)需要知道是哪个kmem_cache,大小,和flags。然后内部又有slab_alloc进行封装。

        slab_alloc最终的申请过程包括:(1)this_cpu_read函数到对应的CPU缓存区申请。这里其实也挺复杂的,没有想象中那么简单。

 

遗留问题:

kmalloc能申请的最大块的连续内存是多少?

  • 由于kmalloc最终是通过slab或者伙伴系统中获取的内存,所以最大的内存就是pageblock的大小(4MB和max_order的配置有关)。

kmalloc返回的地址已对齐方式?

  • slab的接口支持配置对齐方式,前面的kmem_cache_create函数有这个参数

kmalloc返回的是虚拟地址还是物理地址?

  • 不管是slab或者伙伴系统内存申请,最终都会通过page_to_virt进行转换虚拟地址。在 Linux 内核中,kmalloc 是用于分配内核空间中的小块内存的函数。它返回的指针是指向内核虚拟地址空间中的内存区域。这是因为现代计算机系统普遍使用虚拟内存机制,内核和用户空间的内存访问都是通过虚拟地址进行的。当你调用 kmalloc 时,它会根据你请求的大小查找或创建一个合适的缓存,并从这个缓存中分配一个对象。这个对象的地址是内核虚拟地址空间中的地址。因此,当你使用 kmalloc 分配的内存时,你是在操作虚拟地址。
  • kmem_cache_alloc 函数返回的是虚拟地址。
  • 在 Linux 内核中,struct page 结构体代表一个物理页帧,并包含了关于该页帧的一些元数据。alloc_pages 函数用于分配物理页帧,并返回一个指向这些页帧的 struct page 结构体数组的指针。但是所有的内存申请,最终会在某个阶段通过page_to_virt转换成虚拟地址

 


http://www.ppmy.cn/ops/102346.html

相关文章

android交叉编译报错no input files的解决方法

问题描述 安装NDK后&#xff0c;make报错"clang-18: error: no input files"&#xff0c;即使直接使用clang命令&#xff08;例如clang -c test.c&#xff09;仍然报错。 开发环境 操作系统&#xff1a;win11 虚拟机&#xff1a;WSL ubuntu22.04 NDK版本&#x…

Visio po解版的详细介绍

一、Visio简介 Visio是一款流程图、组织结构图、地平图、工程图等各类专业图表的制作软件。自问世以来&#xff0c;凭借其友好的用户界面、丰富的图形库和强大的编辑功能&#xff0c;已成为行业内使用最广泛的图形设计软件之一。无论是初学者还是专业人士&#xff0c;都能在Vi…

[易聊]软件项目测试报告

一、项目背景 随着互联网发展&#xff0c;各种各样的软件&#xff0c;比如游戏、短视频、购物软件中都有好友聊天功能&#xff0c;这是一个可在浏览器中与好友进行实时聊天的网页程序。“ 易聊 ”相对于一般的聊天软件&#xff0c;可以让用户免安装、随时随地的通过浏览器网页…

Behavior Retrieval: Few-Shot Imitation Learning by Querying Unlabeled Datasets

发表时间&#xff1a;13 May 2023 论文链接&#xff1a;https://readpaper.com/pdf-annotate/note?pdfId1900983943467731200&noteId2446646993511259136 作者单位&#xff1a;Stanford University Motivation&#xff1a;使机器人能够以数据有效的方式学习新的视觉运动…

FLUX 1 将像 Stable Diffusion 一样完整支持ControlNet组件

之前 InstantX 团队做的多合一的 Flux ControlNet 现在开始和 ShakkerAI 合作并推出了&#xff1a;Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro 该模型支持 7 种控制模式&#xff0c;包括 canny (0), tile (1), depth (2), blur (3), pose (4), gray (5) 和 low quality (6)…

鸿蒙(API 12 Beta3版)【媒体资源使用指导】Media Library Kit媒体文件管理服务

应用可以通过photoAccessHelper的接口&#xff0c;对媒体资源&#xff08;图片、视频&#xff09;进行相关操作。 说明 在进行功能开发前&#xff0c;请开发者查阅[开发准备]&#xff0c;了解如何获取相册管理模块实例和如何申请相册管理模块功能开发相关权限。文档中使用到p…

Android App启动流程

1.通过 Launcher 启动应用时&#xff0c;点击应用图标后&#xff0c;Launcher 调用 startActivity 启动应用。 2.Launcher Activity 最终调用 Instrumentation 的 execStartActivity 来启动应用。 3.Instrumentation 调用 ActivityManagerProxy (ActivityManagerService 在应…

springboot调用sap接口传输数据,RFC协议接口调用,包含linux,windows部署

背景&#xff1a;我这边需要将一串数组写入到sap系统中&#xff0c;原本希望sap能提供rest形式接口&#xff0c;可惜sap开发那边说sap对外都是rfc接口&#xff0c;现在记录一下sap接口对接&#xff0c;给其他小伙伴提供点经验。 1、首先必须有对应的原料&#xff0c;驱动jar包…