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

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

hot3.png

缓存为什么会有冷热?

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

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

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

在操作系统中,每个内存区域(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://my.oschina.net/ssdlinux/blog/3015261

你可能感兴趣的文章
GUI鼠标相关设置
查看>>
使用 <Iframe>实现跨域通信
查看>>
闭包--循序学习
查看>>
项目实战之集成邮件开发
查看>>
解决C3P0在Linux下Failed to get local InetAddress for VMID问题
查看>>
1531 山峰 【栈的应用】
查看>>
巧用美女照做微信吸粉,你会做吗?
查看>>
wcf学习总结《上》
查看>>
ERROR (ClientException)
查看>>
Load Balance 产品横向比较
查看>>
Java代理程序实现web方式管理邮件组成员
查看>>
【编译打包】tengine 1.5.1 SRPM
查看>>
看图说话:手动清除病毒文件流程
查看>>
一句话下拖库
查看>>
Deploy Office Communications Server 2007R2 Group Chat Server(二)
查看>>
在Cacti上实现MSN报警机制
查看>>
如何对C++虚基类构造函数
查看>>
XFire WebService开发快速起步
查看>>
JavaScript 函数replace揭秘
查看>>
QTP解决内嵌IE窗体方法2
查看>>