缓存为什么会有冷热?

究其原因,是因为对于内存的访问,可能是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. Java数据结构与算法 - 外部存储

    Q: 什么是外部存储? A: 外部存储特指某类磁盘系统,例如在大多数台式电脑或服务器中的硬盘. Q: 如何访问外部存储? A: 我们所学的数据结构都是假设数据存储在内存中,但是,在很多情况下要处理的数 ...

  2. iOS学习——Quartz2D学习之UIKit绘制

    iOS学习——Quartz2D学习之UIKit绘制 1.总述 在IOS中绘图技术主要包括:UIKit.Quartz 2D.Core Animation和OpenGL ES.其中Core Animati ...

  3. C#基础语法

    究极入门之Hello world static void Main(string[] args) { //你好,世界 Console.WriteLine("HELLO WORLD" ...

  4. Java String:重要到别人只能当老二的字符串类

    字符串,是Java中最重要的类.这句肯定的推断不是Java之父詹姆斯·高斯林说的,而是沉默王二说的,因此你不必怀疑它的准确性. 关于字符串,有很多的面试题,但我总觉得理论知识绕来绕去没多大意思.你比如 ...

  5. C# 获取 ipv4的方法

    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adap ...

  6. 『素数 Prime判定和线性欧拉筛法 The sieve of Euler』

    素数(Prime)及判定 定义 素数又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数,否则称为合数. 1既不是素数也不是合数. 判定 如何判定一个数是否是素数呢?显然,我 ...

  7. Python:zip 函数的用法

    zip() 接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个 tuple,然后返回由这些 tuple 组成的 list. 若传入参数的长度不等,则返回 list 的长度和参数中长度最短的 ...

  8. 初学Java Web(2)——搭建Java Web开发环境

    虽然说 html 和 css 等前端技术,是对于 Web 来说不可或缺的技术,但是毕竟更为简单一些,所以就不详细介绍了,没有基础的同学可以去菜鸟教程或者W3school进行自主学习,最好的方式还是做一 ...

  9. 环境与工具1:微信群刷屏 | itchat

    在微信群里面,"刷屏"的行为是被谴责的,伴随着"快发红包道歉"与"送飞机票"的出现.那如果小程硬是要做到"刷屏"来验证自 ...

  10. leetcode — remove-duplicates-from-sorted-list

    /** * Source : https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list/ * * * Given a so ...