Linux内核的冷热缓存
缓存为什么会有冷热?
究其原因,是因为对于内存的访问,可能是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,则从冷缓存中分配一页,否则,从热缓存中分配。
Linux内核的冷热缓存的更多相关文章
- linux内核的冷热页分配器
先说说cpu的cache,和cpu的cache比起来访问主内存是非常慢的,为了加快速度根据本地性原则,cpu在访问主内存的时候会把附近的一块数据都加载到cpu的cache里,之后读写这块数据都是在ca ...
- 20169207《Linux内核原理与分析》第十周作业
这周除了阅读学习教材「Linux内核设计与实现 (Linux Kernel Development)」第教材第15,16章外.我们还需要接着完成学习MOOC「Linux内核分析」第八讲「Linux系统 ...
- 2017-2018-1 20179202《Linux内核原理与分析》第九周作业
进程的切换和系统的一般执行过程 1.知识总结 (1)进程调度的时机: 中断处理过程直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(). 内核线程是一 ...
- 2017-2018-1 20179205《Linux内核原理与设计》第九周作业
<Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多 ...
- Linux内核设计与实现 总结笔记(第十六章)页高速缓存和页回写
页高速缓存是Linux内核实现磁盘缓存.磁盘告诉缓存重要源自:第一,访问磁盘的速度要远远低于访问内存. 第二,数据一旦被访问,就很有可能在短期内再次被访问到.这种短时期内集中访问同一片数据的原理称作临 ...
- 模仿Linux内核kfifo实现的循环缓存
想实现个循环缓冲区(Circular Buffer),搜了些资料多数是基于循环队列的实现方式.使用一个变量存放缓冲区中的数据长度或者空出来一个空间来判断缓冲区是否满了.偶然间看到分析Linux内核的循 ...
- linux内核数据结构学习总结
目录 . 进程相关数据结构 ) struct task_struct ) struct cred ) struct pid_link ) struct pid ) struct signal_stru ...
- 内存管理——linux内核学习
买了<深入Linux内核架构>这本书准备了解一下linux内核机制.但是最开始看了十几页感觉看着很累,本来都准备弃了 过了段时间看见一个面经有linux内核的内容,于是就照着那个先把内存管 ...
- Linux内核内存管理架构
内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射.页面分配.页面回收.页面交换.冷热页面.紧急页面.页面碎片管理.页面缓存.页面统计等,而且对性能也有很高的要 ...
随机推荐
- Dockerfile指令介绍
FROM:指定基础镜像 在Dockerfile中FROM是必备的指令,用于指定基础的镜像. FROM centos:latest LABEL:指定镜像标签 LABEL指令用来指定镜像的标签. 格式: ...
- 说一说MVC的MenuCard(五)
1.数据库设计 create database BookShop go use bookshop go --模块表 create table Module ( ModuleID ,), ModuleN ...
- Java导出CSV文件
以前导出总是用POI导出为Excel文件,后来当我了解到CSV以后,我发现速度飞快. 如果导出的数据不要求格式.样式.公式等等,建议最好导成CSV文件,因为真的很快. 虽然我们可以用Java再带的文件 ...
- MongoDB添加secondary节点的两种方法
前段时间维护的一个事业群的其中一条业务线的开发找到运维,提出来了一个MongoDB的优化问题,那段时间MongoDB正在从op管理移交给db进行维护,整个部门都对MongoDB的运维经验缺乏,Mong ...
- springboot+mybatis+dubbo+aop日志第三篇
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等. Spring AOP模块提供截取拦截应用程序的拦截器,例如,当执行方法时,可以在执行方法之前或之后添加 ...
- Java开发知识之Java的包装类
Java开发知识之Java的包装类 一丶什么是包装类 包装类的意思就是对基本数据类型封装成一个类.这些类都是Number的子类.区别就是封装数据类型不同.包含的方法基本相同. 具体可以查询JAVA A ...
- JDK源码分析(3)之 ArrayList 相关
ArrayList的源码其实比较简单,所以我并没有跟着源码对照翻译,文本只是抽取了一些我觉得有意思或一些有疑惑的地方分析的. 一.成员变量 private static final int DEFAU ...
- Spring之BeanFactory和FactoryBean接口的区别
目录 一.BeanFactory接口 二.FactoryBean接口 1.简单实现 2.增强实现 3.FactoryBean的实际使用案例 三.总结 @ Spring框架中的BeanFactory ...
- Asp.net Core 项目中如何使用 MongoDB 数据库
内容来源 https://blog.csdn.net/qq_26900081/article/details/83272132 一.添加依赖 1.MongoDB.Driver 2.MongoDB.Bs ...
- [MySQL] explain中的using where和using index
1. 查看表中的所有索引 show index from modify_passwd_log; 有两个 一个是id的主键索引 , 一个是email_id的普通索引 2. using index表示 ...