博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lru的加入与删除
阅读量:4215 次
发布时间:2019-05-26

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

LRU的全称是least recently used的缩写,在kernel中当内存紧张是总是有限换出page cache的页面针对LRU换出页面的的算法旧版采用的是FIFO算法,新版采用的是second chance算法。将page加入到lru中的flow如下:lru_cache_add->__lru_cache_add->__pagevec_lru_add->pagevec_lru_move_fn->void __pagevec_lru_add(struct pagevec *pvec){	pagevec_lru_move_fn(pvec, __pagevec_lru_add_fn, NULL);}可见这里的回调函数是__pagevec_lru_add_fnstatic void pagevec_lru_move_fn(struct pagevec *pvec,	void (*move_fn)(struct page *page, struct lruvec *lruvec, void *arg),	void *arg){	int i;	struct pglist_data *pgdat = NULL;	struct lruvec *lruvec;	unsigned long flags = 0;	for (i = 0; i < pagevec_count(pvec); i++) {		struct page *page = pvec->pages[i];		struct pglist_data *pagepgdat = page_pgdat(page);		if (pagepgdat != pgdat) {			if (pgdat)				spin_unlock_irqrestore(&pgdat->lru_lock, flags);			pgdat = pagepgdat;			spin_lock_irqsave(&pgdat->lru_lock, flags);		}		#注意这里的变量lruvec 是每个node节点都有一个。		lruvec = mem_cgroup_page_lruvec(page, pgdat);		(*move_fn)(page, lruvec, arg);	}}加入我们没有定义cgroup的话static inline struct lruvec *mem_cgroup_page_lruvec(struct page *page,						    struct pglist_data *pgdat){	return &pgdat->lruvec;}从这个函数很容易看出lruvec是没有个node 节点都有一个。从这里也可以知道lru的管理是一个numa node每最大支持范围。__pagevec_lru_add_fn->add_page_to_lru_liststatic __always_inline void add_page_to_lru_list(struct page *page,				struct lruvec *lruvec, enum lru_list lru){	update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));	list_add(&page->lru, &lruvec->lists[lru]);}可见最后通过update_lru_size 来更新lru的size,然后在通过list_add 将page->lru 添加到lruvec->lists[lru] 中当内存不足时会调用reclaim_clean_pages_from_list或者shrink_inactive_list 来回收lru中的页面,这两个函数最终都会调用shrink_page_liststatic unsigned long shrink_page_list(struct list_head *page_list,				      struct pglist_data *pgdat,				      struct scan_control *sc,				      enum ttu_flags ttu_flags,				      struct reclaim_stat *stat,				      bool force_reclaim){#调用下面这两个函数来从lru的list中删除page		page = lru_to_page(page_list);		list_del(&page->lru);}其中#define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) 可以得到一个页面,然后调用list_del来删除这个页面.

转载地址:http://jnnmi.baihongyu.com/

你可能感兴趣的文章
c++ 运算符重载
查看>>
android使用已安装程序实现分享功能
查看>>
android实现截图功能
查看>>
android 网络连接状态判断与数据类型
查看>>
android webview 实现网页加载进度
查看>>
《人性的弱点》
查看>>
《大师们是如何工作的》
查看>>
c++ 中的多重继承和其权限问题
查看>>
那些年
查看>>
android listview 图文并茂
查看>>
c++中的拷贝构造函数
查看>>
北漂小记—黑客马拉松.北京站
查看>>
《浪潮之巅》1 AT&T
查看>>
《浪潮之巅》2蓝色巨人 IBM公司
查看>>
《浪潮之巅》3水果公司的复兴
查看>>
《浪潮之巅》4计算机工业的生态链
查看>>
《浪潮之巅》5奔腾的芯 英特尔公司
查看>>
《浪潮之巅》7 互联网的金门大桥 -—思科公司
查看>>
《浪潮之巅》8英名不朽---杨致远、菲洛和雅虎公司
查看>>
《浪潮之巅》9硅谷的见证人———惠普公司
查看>>