当前位置: 首页 > news >正文

内存管理篇-06Per-CPU页帧缓存

per-CPU缓存是对伙伴系统的完善,也是伙伴系统中的一部分。再回顾一下zone结构体的内容,这里的__percpu *pageset实际上就是Per-CPU的实现机制,所以这里的内存实际上最少有三部分,(1)free_area管理了大部分的公共伙伴系统内存;(2)lowmem_reserve预留了一部分;(3)然后就是__percpu *pagset这里对每个CPU都分配一部分管理起来:

1.per-CPU缓存的定义 

        是一种缓存机制,对伙伴系统的完善。由于伙伴系统管理的页面都是全局的,每个进程在申请页面的时候都需要加锁解锁等操作,极大的引入了开销。为了提高效率就引入页帧缓存,为每个cpu提供一个变量指针__percpu *pageset(定义在struct zone),这样每个cpu就不用去加锁解锁申请,直接使用本地物理页面。

        把单个物理页面的申请和释放做成缓存,每个cpu都有这个链表。给每个cpu本地定义一个页表,维护这样一个变量。因此,不需要去全局伙伴系统上去申请释放。

2.核心结构体和实现

        可以理解为struct zone 把内存分为了几大块,__percpu *pageset指针(每个CPU都有这么一个指针),指向了一片内存区域。这片区域不需要再各个CPU之间进行同步,struct list_head list[3], 指向了三种不同页表链表(可移动的,不可移动的,可回收的),并且三个链表都是的块大小都是4KB。

3.每个CPU分配缓存如何实现

        struct per_cpu_pageset __percpu *pageset;这里就是宏,在每个CPU定义这样一个变量,并且每个CPU自己申请和释放内存的时候,不会去从伙伴系统申请释放内存,而是从自己的缓存中。。

        在 Linux 内核中,__percpu 是一个特殊的类型修饰符,用于表示一个变量在每个 CPU 上都有一个独立的副本。struct per_cpu_pageset 是一个用于在每个 CPU 上维护一个页面集合的数据结构。这种机制允许每个 CPU 在本地访问页面集合,从而减少跨 CPU 的同步开销。在内核启动时,为每个 CPU 分配一个 struct per_cpu_pageset 的实例,并将其指针存储在一个全局数组中。通过调用 get_cpu_var() 函数来访问当前 CPU 的 struct per_cpu_pageset 实例。访问完之后,通常需要调用 put_cpu_var() 函数来释放对 struct per_cpu_pageset 的引用。

4.使用示例

#include <linux/percpu.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/mmzone.h>#define NR_PERCPU_PAGES 16struct per_cpu_pageset {spinlock_t lock;struct page *pages[NR_PERCPU_PAGES];unsigned long nr_pages;
};static DEFINE_PER_CPU(struct per_cpu_pageset *, pageset);static void init_per_cpu_pageset(void)
{int cpu;for_each_possible_cpu(cpu) {struct per_cpu_pageset *ps = alloc_percpu(struct per_cpu_pageset);if (!ps) {printk(KERN_ERR "Failed to allocate per-cpu pageset\n");continue;}ps->nr_pages = 0;spin_lock_init(&ps->lock);per_cpu(pageset, cpu) = ps;}
}static void release_per_cpu_pageset(void)
{int cpu;for_each_possible_cpu(cpu) {free_percpu(per_cpu(pageset, cpu));}
}static void add_page_to_set(struct page *page)
{int cpu = raw_smp_processor_id();struct per_cpu_pageset *ps = per_cpu(pageset, cpu);spin_lock(&ps->lock);// 检查是否还有空间添加页面if (ps->nr_pages < NR_PERCPU_PAGES) {ps->pages[ps->nr_pages++] = page;} else {printk(KERN_WARNING "Per-CPU pageset full on CPU %d\n", cpu);}spin_unlock(&ps->lock);
}static void remove_page_from_set(struct page *page)
{int cpu = raw_smp_processor_id();struct per_cpu_pageset *ps = per_cpu(pageset, cpu);int i;spin_lock(&ps->lock);// 查找页面并移除for (i = 0; i < ps->nr_pages; i++) {if (ps->pages[i] == page) {ps->pages[i] = ps->pages[--ps->nr_pages];break;}}spin_unlock(&ps->lock);
}static int __init init_module(void)
{init_per_cpu_pageset();return 0;
}static void __exit cleanup_module(void)
{release_per_cpu_pageset();
}module_init(init_module);
module_exit(cleanup_module);

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • toRaw 与 markRaw
  • 【机器学习】逻辑回归
  • ArcGIS Pro基础:如何将数据和引用地图样式一起打包分享
  • leetcode53:最大子数组和
  • Neo4J下载安装
  • 宿州申报!宿州市首台套重大技术装备申报奖补条件
  • 39-nacos eureka zookeeper区别
  • 飞书应用机器人文件上传
  • 【C++】12.智能指针
  • Jupyter Notebook 使用多个Kernel
  • 技术文档索引
  • Linux 内核源码分析---组播/策略路由选择
  • 内存函数memcpy和memmove
  • 谷歌chrome浏览器显示“版本太旧”又无法更新情况下,如何关闭“Chrome版本太旧”提示,包括直接启动Google浏览器,或者通过其他应用启动
  • Web层统一实体规范封装
  • Android 架构优化~MVP 架构改造
  • C# 免费离线人脸识别 2.0 Demo
  • FineReport中如何实现自动滚屏效果
  • Laravel5.4 Queues队列学习
  • Laravel核心解读--Facades
  • linux安装openssl、swoole等扩展的具体步骤
  • MySQL数据库运维之数据恢复
  • ng6--错误信息小结(持续更新)
  • Quartz初级教程
  • redis学习笔记(三):列表、集合、有序集合
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 二维平面内的碰撞检测【一】
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 离散点最小(凸)包围边界查找
  • 利用DataURL技术在网页上显示图片
  • 免费小说阅读小程序
  • 微服务核心架构梳理
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 系统认识JavaScript正则表达式
  • puppet连载22:define用法
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • #etcd#安装时出错
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (arch)linux 转换文件编码格式
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (PySpark)RDD实验实战——取最大数出现的次数
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)php投票系统 毕业设计 121500
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (十二)Flink Table API
  • (转)linux 命令大全
  • (转)一些感悟
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .Net 6.0--通用帮助类--FileHelper
  • .net dataexcel 脚本公式 函数源码
  • .net 反编译_.net反编译的相关问题