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

Linux内核的缓存

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

缓存为什么会有冷热?

究其原因,是因为对于内存的访问,可能是CPU发起的,也可以是DMA设备发起的。

如果是CPU发起的,在CPU的硬件缓存中,就会保存相应的页内容。如果这个页本来没有存在于硬件缓存中,那么它的到来,势必会将原本为其他的页缓存的内容挤出硬件缓存。

但是,如果对于内存的访问是由DMA设备发起的,那么该页不会被CPU访问,就不需要在CPU的硬件缓存中进行缓存,也不会对已经缓存在硬件缓存中的页内容造成伤害。

在Linux操作系统中,每个内存区域(Zone)都分配了hot cache和cold cache,hot cache用来缓存那些很可能被CPU的硬件缓存收纳了的页。

hot/cold cache只处理单页分配的情况。

1: /*
   2:  * Really, prep_compound_page() should be called from __rmqueue_bulk().  But
   3:  * we cheat by calling it from here, in the order > 0 path.  Saves a branch
   4:  * or two.
   5:  */
   6: static inline
   7: struct page *buffered_rmqueue(struct zone *preferred_zone,
   8:             struct zone *zone, int order, gfp_t gfp_flags,
   9:             int migratetype)
  10: {
  11:     unsigned long flags;
  12:     struct page *page;
  13:     int cold = !!(gfp_flags & __GFP_COLD);
  14:  
  15: again:
  16:     if (likely(order == 0)) {
  17:         struct per_cpu_pages *pcp;
  18:         struct list_head *list;
  19:  
  20:         local_irq_save(flags);
  21:         pcp = &this_cpu_ptr(zone->pageset)->pcp;
  22:         list = &pcp->lists[migratetype];
  23:         if (list_empty(list)) {
  24:             pcp->count += rmqueue_bulk(zone, 0,
  25:                     pcp->batch, list,
  26:                     migratetype, cold);
  27:             if (unlikely(list_empty(list)))
  28:                 goto failed;
  29:         }
  30:  
  31:         if (cold)
  32:             page = list_entry(list->prev, struct page, lru);
  33:         else
  34:             page = list_entry(list->next, struct page, lru);
  35:  
  36:         list_del(&page->lru);
  37:         pcp->count--;
  38:     } else {
  39:         if (unlikely(gfp_flags & __GFP_NOFAIL)) {
  40:             /*
  41:              * __GFP_NOFAIL is not to be used in new code.
  42:              *
  43:              * All __GFP_NOFAIL callers should be fixed so that they
  44:              * properly detect and handle allocation failures.
  45:              *
  46:              * We most definitely don't want callers attempting to
  47:              * allocate greater than order-1 page units with
  48:              * __GFP_NOFAIL.
  49:              */
  50:             WARN_ON_ONCE(order > 1);
  51:         }
  52:         spin_lock_irqsave(&zone->lock, flags);
  53:         page = __rmqueue(zone, order, migratetype);
  54:         spin_unlock(&zone->lock);
  55:         if (!page)
  56:             goto failed;
  57:         __mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
  58:     }
  59:  
  60:     __count_zone_vm_events(PGALLOC, zone, 1 << order);
  61:     zone_statistics(preferred_zone, zone, gfp_flags);
  62:     local_irq_restore(flags);
  63:  
  64:     VM_BUG_ON(bad_range(zone, page));
  65:     if (prep_new_page(page, order, gfp_flags))
  66:         goto again;
  67:     return page;
  68:  
  69: failed:
  70:     local_irq_restore(flags);
  71:     return NULL;
  72: }

buffered_rmqueue用于从冷热分配器中分配单页的缓存页。

如果gfp_flags中指定的__GFP_COLD,则从冷缓存中分配一页,否则,从热缓存中分配。

原文来自: https://www.linuxprobe.com/caching-linux-kernel.html

转载于:https://my.oschina.net/ssdlinux/blog/3015261

相关文章:

  • Javascript Promise 学习(上)
  • windows下mongoDB的环境配置
  • 使用Sublime Text 2 编辑Markdown
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • 03Go 类型总结
  • PHP打印常量
  • Route配置实现通信实验报告
  • 区块链技术特点之去中心化特性
  • SqlBulkCopy类进行大数据(10000万条以上)插入测试
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 【Linux系统编程】快速查找errno错误码信息
  • 关于aspx.designer.cs的研究
  • 精彩代码 vue.js
  • 霍夫变换直线检测
  • Netflix 混沌工程手册 Part 3:实践方法
  • 分享的文章《人生如棋》
  • JavaScript设计模式系列一:工厂模式
  • leetcode388. Longest Absolute File Path
  • npx命令介绍
  • Promise面试题2实现异步串行执行
  • socket.io+express实现聊天室的思考(三)
  • springMvc学习笔记(2)
  • Tornado学习笔记(1)
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 看域名解析域名安全对SEO的影响
  • 使用 QuickBI 搭建酷炫可视化分析
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #define 用法
  • #mysql 8.0 踩坑日记
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (145)光线追踪距离场柔和阴影
  • (2.2w字)前端单元测试之Jest详解篇
  • (30)数组元素和与数字和的绝对差
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (笔试题)合法字符串
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (五)MySQL的备份及恢复
  • (小白学Java)Java简介和基本配置
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET与 java通用的3DES加密解密方法
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • [ SNOI 2013 ] Quare
  • [2017][note]基于空间交叉相位调制的两个连续波在few layer铋Bi中的全光switch——
  • [22]. 括号生成
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [C#]DataTable常用操作总结【转】
  • [elastic 8.x]java客户端连接elasticsearch与操作索引与文档
  • [GN] DP学习笔记板子
  • [IT生活推荐]大家一起来玩游戏喽,来的都进!
  • [pluginviteimport-analysis] vite 提示jsx语法报错