kmalloc分配大小的限制

2023-10-27

kmalloc是通过cache来实现的, 只不过每次kmalloc的大小不同, 因此是从不同的cache中分配:
/* include/linux/slab.h */
// 注意kmalloc是在头文件中定义的
static inline void *kmalloc(size_t size, gfp_t flags)
{
 if (__builtin_constant_p(size)) {
// 以下是找一个对象大小刚好大于等于size的cache
  int i = 0;
#define CACHE(x)
  if (size <= x)
   goto found;
  else
   i++;
#include "kmalloc_sizes.h"
#undef CACHE
  {
   extern void __you_cannot_kmalloc_that_much(void);
   __you_cannot_kmalloc_that_much();
  }
found:
// 实际还是通过kmem_cache_alloc来分配内存空间, 因此也是cache
  return kmem_cache_alloc((flags & GFP_DMA) ?
   malloc_sizes[i].cs_dmacachep :
   malloc_sizes[i].cs_cachep, flags);
 }
// 通过该函数最后也是由__cache_alloc()函数来分配空间
 return __kmalloc(size, flags);
}

// 这是kmalloc_sizes.h文件内容, 实际就是定义CACHE中可用的对象大小
// 普通情况下最大是128K, 也就是kmalloc能分配的最大内存量
#if (PAGE_SIZE == 4096)
 CACHE(32)
#endif
 CACHE(64)
#if L1_CACHE_BYTES < 64
 CACHE(96)
#endif
 CACHE(128)
#if L1_CACHE_BYTES < 128
 CACHE(192)
#endif
 CACHE(256)
 CACHE(512)
 CACHE(1024)
 CACHE(2048)
 CACHE(4096)
 CACHE(8192)
 CACHE(16384)
 CACHE(32768)
 CACHE(65536)
 CACHE(131072)
#if (NR_CPUS > 512) || (MAX_NUMNODES > 256) || !defined(CONFIG_MMU)
 CACHE(262144)
#endif
#ifndef CONFIG_MMU
 CACHE(524288)
 CACHE(1048576)
#ifdef CONFIG_LARGE_ALLOCS
 CACHE(2097152)
 CACHE(4194304)
 CACHE(8388608)
 CACHE(16777216)
 CACHE(33554432)
#endif /* CONFIG_LARGE_ALLOCS */
#endif /* CONFIG_MMU
继续调用
void *__kmalloc(size_t size, gfp_t flags)
{
 return __do_kmalloc(size, flags, NULL);
}
 
static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
       void *caller)
{
 struct kmem_cache *cachep;
 /* If you want to save a few bytes .text space: replace
  * __ with kmem_.
  * Then kmalloc uses the uninlined functions instead of the inline
  * functions.
  */
 cachep = __find_general_cachep(size, flags);
 if (unlikely(cachep == NULL))
  return NULL;
 return __cache_alloc(cachep, flags, caller);
}
 
static inline struct kmem_cache *__find_general_cachep(size_t size, gfp_t gfpflags)
{
 struct cache_sizes *csizep = malloc_sizes;
#if DEBUG
 /* This happens if someone tries to call
  * kmem_cache_create(), or __kmalloc(), before
  * the generic caches are initialized.
  */
 BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL);
#endif
 while (size > csizep->cs_size)
  csizep++;
 /*
  * Really subtle: The last entry with cs->cs_size==ULONG_MAX
  * has cs_{dma,}cachep==NULL. Thus no special case
  * for large kmalloc calls required.
  */
 if (unlikely(gfpflags & GFP_DMA))
  return csizep->cs_dmacachep;
 return csizep->cs_cachep;
}
 
__find_general_cachep确定可以分配的空间大小由malloc_sizes结构体数组指定,在阅读mm/slab.c中它的定义如下
struct cache_sizes malloc_sizes[] = {
#define CACHE(x) { .cs_size = (x) },
#include <linux/kmalloc_sizes.h>
 CACHE(ULONG_MAX)
#undef CACHE
};

在对一个结构体进行赋值的时候,第一次看到了这个用法,赶紧来仔细看看代码。
首先在slab_def.h中找到cache_sizes的定义如下:
struct cache_sizes {
size_t cs_size;
struct kmem_cache *cs_cachep;
#ifdef CONFIG_ZONE_DMA
struct kmem_cache *cs_dmacachep;
#endif
};

可以看出,无论cache_sizes的如何变,至少都要给cs_size分配一个值。函数一就是对malloc_sizes这个数组进行初始化。在初始化的时候却多了3行代码:
代码一:#define CACHE(x) { .cs_size = (x) },
作用:定义一个CACHE(x)的宏,作用在include里面。

代码二:#include <linux/kmalloc_sizes.h>
作用,引用kmalloc_size.h文件。使malloc_sizes[]得到初始化的值。换个角度看,把函数初始化和依据附加条件分开,使得程序的逻辑更加清晰。在函数中,CACHE仅仅作为一个宏,与具体的实现无关。

代码三:#undef CACHE
作用:撤销代码一中的定义。
 
综合来讲,实现的功能就是:
#include <linux/kmalloc_sizes.h>把kmalloc_sizes.h文件里面的内容原封不动地复制到数组中, 定义了一个宏CACHE(x),用完之后取消。
数组展开之后便成:
struct cache_sizes malloc_sizes[] = {
       { .cs_size = (32) },
       { .cs_size = (64) },
       { .cs_size = (96) },
       ...
        { .cs_size = (ULONG_MAX) }
};

在linux/kmalloc_sizes.h中可以看到,所有的代码做的事,仅仅是针对不同的硬件环境作出不同的反应。除了默认的分配CHACH(x)运算外,针对内存页面、一级缓存大小,和是否支持内存管理模块,是否允许kmalloc分配大于1MB的内存等,分别作出了不同的动作。

在面向对象的编程中,最基本的三个概念为:继承、封装、抽象。继承可以理解为在在当前已经存在的基础上进行革新;封装也就是说将一些内部的东西不给你看,你只需要知道如何操作;抽象的意思就是程序有能力忽略正在处理中信息的某些方面,即对信息主要方面关注的能力。oop对于类的编程一般是这个流程:首先是对当前对象进行初始化,接着针对对象进行一系列的操作,最后对当前对象进行销毁

再回到文首的三个代码运行流程,代码一首先定义一个宏;代码二接收到这个值,并且进行一系列的操作,是内部的,在slab.c中没有描述;代码三,销毁代码一定义的宏。同时,在mm/slab.c和include/linux/slab_def.h中可以多次看到上述三个代码,只是在每个代码的实现中,CACHE(x)定义为不同的宏。
 
用于kmalloc可分配的内存大小范围在32~131027(128k)字节,并且由于它用slab分配器来分配内存的,所以,得到的内存大小可能比你申请的要大一些(它向上取2的N次幂整数)。而且如果开启了CONFIG_LARGE_ALLOCS选项,这个值可以更大,可以达到了32M。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kmalloc分配大小的限制 的相关文章

  • Web学习之JavaScript

    文章目录 一 什么是JavaScript 二 JavaScript 用法 三 Chrome 浏览器中执行 JavaScript 四 JavaScript 语法 五 JavaScript 语句 六 JavaScript 函数 七 JavaSc
  • 【redis】单机安装部署redis7.0版本

    下面我以redis 7 0 5版本 来进行讲解 链接 https pan baidu com s 1FesU8iHJQyW4pVARIqeQAA 提取码 qtqc 单机安装Redis 1 首先需要安装Redis所需要的依赖 yum inst
  • 预测知识

    预测知识 预测技术流程及模型评价 目录 预测知识 预测技术流程及模型评价 神经网络 机器学习 深度学习 参考资料 神经网络 神经网络 neural network 是机器学习的一个重要分支 也是深度学习的核心算法 神经网络的名字和结构 源自
  • 上传图片几种方式解析(上)--file

    浏览器上传图片到服务器时通过input type file 以及onchange事件的配合实现的 element和vant的ui库的图片上传都是基于这个 input的files属性 1 众所周知 一级dom事件不同于addeventlisn
  • c语言三目运算符的一些小细节,赋值不改变变量的值

    C语言三目运算符的一些小细节 赋值不改变变量的值 今天无聊翻翻C语言的课本 看到三目运算符的时候 心想这个和if else 语句用法一样 突然脑海里浮现一个想法 三目运算符结构 表达式1 表达式2 表达式3 表达式1 为逻辑表达式 如果为真
  • 使用左、右、全、内连接及使用where条件语句的区别

    使用左 右 全 内连接及使用 where 条件语句的区别 从学SQL语句到现在 从来没有使用过左右连接 也许会有人感到惊讶 但是确实是没有 因为我一直是使用的WHERE条件语句 我也想试一下效果 今天做了一下测试 终于知道 WHERE 条件
  • MySQL --- 多表查询

    多表查询 事务 以及提升查询效率最有手段的索引 一 多表查询 1 1 多表查询 概述 1 1 1 数据准备 将资料中准备好的多表查询数据准备的SQL脚本导入数据库中 部门表 员工表 1 1 2 介绍 多表查询 指从多张表中查询数据 就是从多
  • 系统架构设计师(第二版)学习笔记----信息安全基础知识

    原文链接 系统架构设计师 第二版 学习笔记 信息系统基础 文章目录 一 信息安全的概念 1 1 信息安全的基本要素 1 2 信息安全的内容 1 3 设备安全的内容 1 4 数据安全的内容 1 5 内容安全的含义 1 6 行为安全的含义 二
  • Python函数常见return返回值类型

    Python函数常见return返回值类型Python函数return返回值类型主要包括 class int class str class tuple class list class dict class bool class None
  • 小明和小强的故事 漫画版

    转载于 https blog 51cto com loofeer 676484
  • 发送arp请求报文

    1 报文格式 2 代码如下 include
  • Python爬虫入门教程(非常详细)

    初学Python之爬虫的简单入门 一 什么是爬虫 1 简单介绍爬虫 爬虫的全称为网络爬虫 简称爬虫 别名有网络机器人 网络蜘蛛等等 网络爬虫是一种自动获取网页内容的程序 为搜索引擎提供了重要的数据支撑 搜索引擎通过网络爬虫技术 将互联网中丰
  • C# 计算两个日期之间的所有日期

    用一个for循环就可以解决 int year Begin Convert ToInt32 this dateBegin Value ToString yyyy int month Begin Convert ToInt32 this dat
  • 解决英文版windows10安装软件中文显示乱码问题

    实验室买了台Thorlabs的设备 配了一台笔记本 带的操作系统是美版的windows10 为了提高笔记本的利用率嘛就在这台笔记本安装了一些中文软件 结果问题就出现了 安装完某些中文软件 能正常打开也能正常操作就是显示的中文乱码 在网上找了
  • [SPSS]系统聚类和kmeans聚类的spss实现——基于多维度对中国各城市聚类

    一 系统聚类 选中系统聚类并把变量移入变量框内 聚类选择按照个案聚类 在Display栏中选择Statistics和Plots复选框 这样在结果输出窗口中可以同时得到聚类结果统计量和统计图 选中绘图中的谱系图 单击保存选项卡 方案范围选择2
  • 教你用go 配置管理神器Viper解析docker-compose文件

    什么是Viper Viper 是一个完整的 Go 应用程序配置解决方案 包括 12 Factor 应用程序 它被设计为在应用程序中工作 并且可以处理所有类型的配置需求和格式 它支持 设置默认值 从 JSON TOML YAML HCL en
  • 后台程序 报错内容:java.sql.SQLException: Java heap space

    原因有以下可能 1 查询没有通过参数 而是直接查询出所有的记录 2 是由于mysql单个字段存储的内容过大导致堆内存溢出 3 JVM启动时 JVM堆会自动设置heap size值 值太小导致
  • 内核LED驱动框架讲解以及led设备注册示例代码

    1 驱动框架介绍 1 内核中驱动部分维护者针对每个种类的驱动设计一套成熟的 标准的 典型的驱动实现 然后把不同厂家的同类硬件驱动中相同的部分抽出来自己实现好 再把不同部分留出接口给具体的驱动开发工程师来实现 这就叫驱动框架 2 内核维护者在
  • 涉密服务器 远程,一种具有远程定位功能的涉密移动存储系统及其实现方法专利_专利查询 - 天眼查...

    1 一种具有远程定位功能的涉密移动存储系统 其特征在于 该系统包括定位管理服 务器和移动存储介质 移动存储介质内设置有移动供电模块 定位通信模块 数据销毁模块 和数据存储模块 移动供电模块分别电连接定位通信模块 数据销毁模块和数据存储模块

随机推荐

  • adworld-pwn-level2

    必要知识点 32位系统函数调用使用堆栈传参 其调用时栈的结构如下 返回地址 gt 参数n gt 参数n 1 gt gt 参数1 将elf文件扔到IDA中 跟进到vulnerable函数 里面有输入函数 可以用来做栈溢出 再看到有system
  • 物联网LoRa系列-19:LoRa终端--射频芯片SX1261 SX1262的6种操作模式及其设置

    本文根据SX1261 2芯片手册 阐述SX161 2射频芯片的8种操作模式及其设置 目录 一 MCU与射频芯片之间的操作接口 二 SX1261 2射频芯片的6种工作模式的含义 三 SX1261 2射频芯片工作模式的设置 四 SX1261 2
  • 数组对象找重复值

    对象内容 let empListData lastName lin phone 154393456 lastName lin phone 154393456 lastName lin phone 154393456 找重方法 let new
  • linux-kali利用BeEF 执行 XSS 攻击

    一 配置靶机环境 1 登录win7靶机 2 访问https www xp cn 下载phpstudy软件 下载最新版的就可以 phpstudy软件可以用来进行站点搭建 3 解压后开始安装phpstudy 4 点击启动Apache服务与MyS
  • 关于 QML Tumbler 自定义日历在响应onWheel事件后,其他原有mouse事件无法响应

    程序是在QWidget窗体上嵌套QML 响应触屏和非触屏上面的一些鼠标滚动 滑动功能 在Tumbler下面的MouseArea中 onWheel响应了鼠标滚轮事件后 原来的其他鼠标事件没响应 help 求指点 工程上传到了百度云 链接 ht
  • 修改JAVA环境变量切换JAVA版本不生效问题

    最近因为项目原因 需要在java8和java11环境来回切换 windows切换环境变量没有Linux简单 通过shell脚本操作也会受到环境变量配置的影响 在修改环境变量来切换java版本时也会时不时出现没有生效的问题 一般出现这种问题
  • 2022年浙江省中职组“网络空间安全”赛项模块B--Linux渗透测试

    2022年中职组浙江省 网络空间安全 赛项 B 2 Linux渗透测试 漏洞原理解析 一 竞赛时间 420分钟 共计7小时 吃饭一小时 二 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第 阶段 单兵模式系统渗透测试 任务一 Wi
  • 万一 Github不让用了,Gitee同步指南请收好

    大家好 我是秋风 最近很多开源项目让一个本该纯粹的地方混入了政治色彩 例如 Node 还有 React 这些超明星级的项目 目前来看 React 的issues 已经沦陷了 大家都在反对一个原本纯粹的地方为什么会有了政治 如果说开源项目涉及
  • 相机 (2)旋转

    1 1 LookAt矩阵 用这3个轴外加一个平移向量来创建一个矩阵 并且你可以用这个矩阵乘以任何向量来将其变换到那个坐标空间 R是右向量 U是上向量 D是方向向量 P是摄像机位置向量 glm LookAt函数需要一个位置 目标和上向量以得到
  • CUDA unknown error - this may be due to an incorrectly set up environment

    运行mmaction2时报错 builtins RuntimeError CUDA unknown error this may be due to an incorrectly set up environment e g changin
  • 最全Arduino控制电机教程说明和资料分享

    1 电机介绍 1 1 作用 电机 gt 电磁感应 电能转化为动能 1 2 电机分类 工作电源 直流电机 DC 交流电机 AC 和交直流两用电机 直流电机分类 有刷直流电机和无刷直流电机 1 3 有刷直流电机模型及工作原理 左手定则 这种情况
  • 一篇文章教会你利用Python网络爬虫实现豆瓣电影采集

    一 项目背景 豆瓣电影提供最新的电影介绍及评论包括上映影片的影讯查询及购票服务 可以记录想看 在看和看过的电影电视剧 顺便打分 写影评 极大地方便了人们的生活 今天以电视剧 美剧 为例 批量爬取对应的电影 写入csv文档 用户可以通过评分
  • (Matlab实现)K-means算法及最佳聚类数目的确定

    目录 摘要 1 K means算法 2 Calinski Harabasz Criterion 卡林斯基 哈拉巴斯指标 CH值 3 Davies Bouldin Criterion 戴维斯 博尔丁指标 DB值 4 Gap Value Gap
  • ChatGPT大流行的思考-设想篇

    在ChatGPT火热当下 我们不妨设想一下它可以应用到我们生活和工作的哪些方面 作者在对ChatGPT有所了解后 从行业 宏观及微观的角度进行设想 积累灵感 并投身到模型建设中 希望对你也有所启发 一 宏观及微观角度的设想 1 宏观角度 行
  • SQL Server远程连接的设置

    SQL Server正常连接时 若不需要远程操控其他电脑 可以用Windows身份验证模式 但是涉及到远程处理时 需要通过SQL Server身份验证登录 具体操作如下 首先 我们在登录时 选择Windows身份验证 然后连接到服务器 图1
  • pip 下载慢——解决方法

    国内源 新版ubuntu要求使用https源 要注意 清华 https pypi tuna tsinghua edu cn simple 阿里云 http mirrors aliyun com pypi simple 中国科技大学 http
  • 手把手教你10分钟快速部署Kubernetes集群

    本文介绍的部署过程主要是为了让读者能够理解 K8S 的运行原理 为了简化流程 这里不涉及高可用 高性能等解决方案 安装说明 本文仅仅是在两个节点上部署所有的组件 如图所示包括 MASTER 和 NODE 所有的组件都安装在 opt comp
  • Java程序开发学习之组件及事件处理

    学习参考书 Java2实用教程第5版 一 GUI编程 容器类 Container 和组件类 Component javax swing包中JComponent类是java awt包中Container类的一个直接子类 java awt包中C
  • 虚拟机环境搭建-CentOS篇

    文章目录 VMware Workstation软件安装 略 Linux环境安装 使用CentOS7 环境配置 基本配置 用 Xshell 访问虚拟机 参考文档 VMware Workstation软件安装 略 VMware Workstat
  • kmalloc分配大小的限制

    kmalloc是通过cache来实现的 只不过每次kmalloc的大小不同 因此是从不同的cache中分配 include linux slab h 注意kmalloc是在头文件中定义的 static inline void kmalloc