缓存为什么会有冷热?

究其原因,是因为对于内存的访问,可能是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内核的冷热缓存的更多相关文章

  1. linux内核的冷热页分配器

    先说说cpu的cache,和cpu的cache比起来访问主内存是非常慢的,为了加快速度根据本地性原则,cpu在访问主内存的时候会把附近的一块数据都加载到cpu的cache里,之后读写这块数据都是在ca ...

  2. 20169207《Linux内核原理与分析》第十周作业

    这周除了阅读学习教材「Linux内核设计与实现 (Linux Kernel Development)」第教材第15,16章外.我们还需要接着完成学习MOOC「Linux内核分析」第八讲「Linux系统 ...

  3. 2017-2018-1 20179202《Linux内核原理与分析》第九周作业

    进程的切换和系统的一般执行过程 1.知识总结 (1)进程调度的时机: 中断处理过程直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(). 内核线程是一 ...

  4. 2017-2018-1 20179205《Linux内核原理与设计》第九周作业

    <Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多 ...

  5. Linux内核设计与实现 总结笔记(第十六章)页高速缓存和页回写

    页高速缓存是Linux内核实现磁盘缓存.磁盘告诉缓存重要源自:第一,访问磁盘的速度要远远低于访问内存. 第二,数据一旦被访问,就很有可能在短期内再次被访问到.这种短时期内集中访问同一片数据的原理称作临 ...

  6. 模仿Linux内核kfifo实现的循环缓存

    想实现个循环缓冲区(Circular Buffer),搜了些资料多数是基于循环队列的实现方式.使用一个变量存放缓冲区中的数据长度或者空出来一个空间来判断缓冲区是否满了.偶然间看到分析Linux内核的循 ...

  7. linux内核数据结构学习总结

    目录 . 进程相关数据结构 ) struct task_struct ) struct cred ) struct pid_link ) struct pid ) struct signal_stru ...

  8. 内存管理——linux内核学习

    买了<深入Linux内核架构>这本书准备了解一下linux内核机制.但是最开始看了十几页感觉看着很累,本来都准备弃了 过了段时间看见一个面经有linux内核的内容,于是就照着那个先把内存管 ...

  9. Linux内核内存管理架构

    内存管理子系统可能是linux内核中最为复杂的一个子系统,其支持的功能需求众多,如页面映射.页面分配.页面回收.页面交换.冷热页面.紧急页面.页面碎片管理.页面缓存.页面统计等,而且对性能也有很高的要 ...

随机推荐

  1. IDEA 配置远程debug

    1. 启动远程服务配置debug参数 远程服务启动时配置如下debug相关参数 java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address= ...

  2. vue-textarea 自适应高度

    需求简介 一个搜索页面,上面输入框,下面列表展示搜索到的结果. 重点是:产品要求搜索框默认显示一行,当输入的文字超过一行时,输入框的高度会随着改变,直到输入完毕. 解决思路设想 本想利用textare ...

  3. Python内置函数(8)——bytes

    英文文档: class bytes([source[, encoding[, errors]]]) Return a new “bytes” object, which is an immutable ...

  4. Python内置函数(10)——chr

    英文文档: chr(i) Return the string representing a character whose Unicode code point is the integer i. F ...

  5. github学习:如何从本地把项目上传到github&&如何把github项目通过clone复制下来,详细教程

    一.第一步---注册一个Github账号 首先要在GitHub上创建一个帐号,可以去官方网站注册一个账号. 前提:本地安装一个git 本人github:https://github.com/saucx ...

  6. Object类toString()

    Object类是java所有类的始祖,在java中每个类都是由它扩展而来. toString()方法返回一个包含类名与内存地址的文本形式的字符串  即打印对象的时候便会调用此方法. 强烈建议为自定义的 ...

  7. spring原理案例-基本项目搭建 03 创建工程运行测试 spring ioc原理实例示例

    下面开始项目的搭建 使用 Java EE - Eclipse 新建一 Dynamic Web Project Target Runtime 选 Apache Tomcat 7.0(不要选 Apache ...

  8. MySQLSource-Flume

    1. 自定义Source说明 实时监控MySQL,从MySQL中获取数据传输到HDFS或者其他存储框架,所以此时需要我们自己实现MySQLSource. 2. 自定义MySQLSource步骤 根据官 ...

  9. Docker日志管理--docker部署安装ELK (十一)--技术流ken

    Docker logs 对于一个运行的容器,Docker 会将日志发送到 容器的 标准输出设备(STDOUT)和标准错误设备(STDERR),STDOUT 和 STDERR 实际上就是容器的控制台终端 ...

  10. 【小o地图Excel插件版】不止能做图表,还能抓58、大众点评网页数据...

    小o地图Excel插件版:一款基于Excel软件开发的地图软件,提供基于Excel表格进行地理数据挖掘.地理数据分析.地图绘制.地图图表等功能的工具类软件.具有易用.高效.稳定的特点,能够满足地理数据 ...