博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核的冷热缓存
阅读量:7106 次
发布时间:2019-06-28

本文共 2927 字,大约阅读时间需要 9 分钟。

缓存为什么会有冷热?

究其原因,是因为对于内存的访问,可能是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.cnblogs.com/long123king/p/3502116.html

你可能感兴趣的文章
惠普10亿美元锻造Helion云品牌
查看>>
拨开云计算迷雾,助力企业业务创新
查看>>
[C# 开发技巧系列]如何动态设置屏幕分辨率
查看>>
Exchange 2013 五个接收连接器功能与解释
查看>>
位图和SVG用法比较
查看>>
响应式设计(Response Web Design)实践
查看>>
Exchange 2010无法创建DAG第二个成员
查看>>
Skype for Business Server 2015-04-前端服务器-4-准备Active Directory
查看>>
52.本地VMware环境虚拟机的异地(Azure)容灾(下)
查看>>
从阿里旺旺看淘宝和ebay的差异,看中国人的信任危机
查看>>
加州Tahoe之行
查看>>
iptables l7-filter扩展模块封QQ、MSN、迅雷等应用层协议
查看>>
谁干的mysql无密码登录?
查看>>
《从零开始学Swift》学习笔记(Day 49)——扩展声明
查看>>
Microsoft Operations Management Suite 配置网络性能监视
查看>>
Android切近实战(三)
查看>>
自定义分页标签模拟谷歌模式
查看>>
618商战大片谢幕,销量冠军竟然有两个?
查看>>
ExtJS应用架构设计(二)
查看>>
基于Windows Media Service的流媒体直播系统
查看>>