博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kernel中ksm特性
阅读量:4215 次
发布时间:2019-05-26

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

ksm的全称是kernel samepage mergeing,主要用于合并内容相同的页面,只要用于虚拟机中存在的大量的冗余页面。在kernel中可以通过PageKsm 来判断一个页面是否是ksm页面static __always_inline int PageKsm(struct page *page){	page = compound_head(page);	return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==				PAGE_MAPPING_KSM;}从makefile中可以知道,kernel要使能这个特定的话,必须打开CONFIG_KSMobj-$(CONFIG_KSM) += ksm.okernel中会创建一个thread来专门做这件事static int __init ksm_init(void){	struct task_struct *ksm_thread;	int err;	/* The correct value depends on page size and endianness */	zero_checksum = calc_checksum(ZERO_PAGE(0));	/* Default to false for backwards compatibility */	ksm_use_zero_pages = false;	err = ksm_slab_init();	if (err)		goto out;	#这里有新建一个thread 来合并具有相同页面的page	ksm_thread = kthread_run(ksm_scan_thread, NULL, "ksmd");	if (IS_ERR(ksm_thread)) {		pr_err("ksm: creating kthread failed\n");		err = PTR_ERR(ksm_thread);		goto out_free;	}	return 0;}我们看看其线程的回调函数ksm_scan_threadstatic int ksm_scan_thread(void *nothing){	set_freezable();	set_user_nice(current, 5);	while (!kthread_should_stop()) {		mutex_lock(&ksm_thread_mutex);		wait_while_offlining();		if (ksmd_should_run())		#如果运行thread运行的话,这里调用ksm_do_scan 来找到相同的页面并合并,这里的形参ksm_thread_pages_to_scan 		#表示每次合并的页数			ksm_do_scan(ksm_thread_pages_to_scan);		mutex_unlock(&ksm_thread_mutex);		try_to_freeze();		if (ksmd_should_run()) {		#目前ksm_thread_sleep_millisecs 等于20ms。可以知道这个线程每20ms运行一次			schedule_timeout_interruptible(				msecs_to_jiffies(ksm_thread_sleep_millisecs));		} else {			wait_event_freezable(ksm_thread_wait,				ksmd_should_run() || kthread_should_stop());		}	}	return 0;}static void ksm_do_scan(unsigned int scan_npages){	struct rmap_item *rmap_item;	struct page *uninitialized_var(page);	while (scan_npages-- && likely(!freezing(current))) {		cond_resched();		#rmap 表示通过反向映射的页面,这里找到一个需要合并的页面		rmap_item = scan_get_next_rmap_item(&page);		if (!rmap_item)			return;		#开始合并页面		cmp_and_merge_page(page, rmap_item);		put_page(page);	}}这里需要支持 用户申请的页面只有再通过系统调用madvise显示的加入到ksm中,才会被线程ksm_scan_thread 扫描并合并madvise_behavior->ksm_madvise->__ksm_enterint __ksm_enter(struct mm_struct *mm){	struct mm_slot *mm_slot;	int needs_wakeup;	#分配一个struct mm_slot数据结构	mm_slot = alloc_mm_slot();	if (!mm_slot)		return -ENOMEM;	/* Check ksm_run too?  Would need tighter locking */	needs_wakeup = list_empty(&ksm_mm_head.mm_list);	spin_lock(&ksm_mmlist_lock);	insert_to_mm_slots_hash(mm, mm_slot);	#将mm_slot 添加到ksm_scan.mm_slot->mm_list 中	if (ksm_run & KSM_RUN_UNMERGE)		list_add_tail(&mm_slot->mm_list, &ksm_mm_head.mm_list);	else		list_add_tail(&mm_slot->mm_list, &ksm_scan.mm_slot->mm_list);	spin_unlock(&ksm_mmlist_lock);	#设置标志位,表示这个进程已经被添加到ksm系统中	set_bit(MMF_VM_MERGEABLE, &mm->flags);	mmgrab(mm);	#唤醒前面的ksm_scan_thread 线程来扫描相同页面并merge	if (needs_wakeup)		wake_up_interruptible(&ksm_thread_wait);	return 0;}

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

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