匿名页面缺页中断

do_anonymous_page 函数分析

static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
{
	struct vm_area_struct *vma = vmf->vma;
	struct mem_cgroup *memcg;
	struct page *page;
	vm_fault_t ret = 0;
	pte_t entry;

	/* File mapping without ->vm_ops ? */
	// 是否共享虚拟映射
	if (vma->vm_flags & VM_SHARED)
		return VM_FAULT_SIGBUS;
    
	 // 分配一个PTE 并且把分配出来的PTE 设置到PMD中vmf->pmd
	if (pte_alloc(vma->vm_mm, vmf->pmd))
		return VM_FAULT_OOM;

	/* See the comment in pte_alloc_one_map() */
	if (unlikely(pmd_trans_unstable(vmf->pmd)))
		return 0;

	/* Use the zero-page for reads */
	// 判断 标记中是否有可写权限,如果没有可写权限使用零页填充 ZERO_PAGE
	if (!(vmf->flags & FAULT_FLAG_WRITE) &&
			!mm_forbids_zeropage(vma->vm_mm)) {
				//my_zero_pfn  获取系统零页帧号
				//pte_mkspecial  设置PTE中的PTE_SPECIAL 表示这是一个特殊的映射
		entry = pte_mkspecial(pfn_pte(my_zero_pfn(vmf->address),
						vma->vm_page_prot));
//pte_offset_map_lock  获取PTE 在获取的过程中会使用    
//spin_lock(__ptl); mm->page_table_lock  使用这个自旋锁进行保护
		vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
				vmf->address, &vmf->ptl);
		if (!pte_none(*vmf->pte))
			goto unlock;
		ret = check_stable_address_space(vma->vm_mm);
		if (ret)
			goto unlock;
		/* Deliver the page fault to userland, check inside PT lock */
		if (userfaultfd_missing(vma)) {
			pte_unmap_unlock(vmf->pte, vmf->ptl);
			return handle_userfault(vmf, VM_UFFD_MISSING);
		}
		goto setpte;
	}
	// 使用   anon_vma_prepare  为建立RMAP做准备
	if (unlikely(anon_vma_prepare(vma)))
		goto oom;
	// 分配一个可移动的匿名页面, 优先使用高端的 zone
	page = alloc_zeroed_user_highpage_movable(vma, vmf->address);
	if (!page)
		goto oom;

	if (mem_cgroup_try_charge_delay(page, vma->vm_mm, GFP_KERNEL, &memcg,
					false))
		goto oom_free_page;

	__SetPageUptodate(page);

// 生成一个新的PTE , 这个新的PTE是基于上面分配的页面帧号来创建的
	entry = mk_pte(page, vma->vm_page_prot);
	if (vma->vm_flags & VM_WRITE)
		entry = pte_mkwrite(pte_mkdirty(entry));

// 获取address对应的PTE,这里会申请一个自旋锁spin_lock(__ptl);
	vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
			&vmf->ptl);
	if (!pte_none(*vmf->pte))
		goto release;

// 检查稳定的地址空间test_bit(MMF_UNSTABLE, &mm->flags)
	ret = check_stable_address_space(vma->vm_mm);
	if (ret)
		goto release;

	/* Deliver the page fault to userland, check inside PT lock */
	if (userfaultfd_missing(vma)) {
		pte_unmap_unlock(vmf->pte, vmf->ptl);
		mem_cgroup_cancel_charge(page, memcg, false);
		put_page(page);
		return handle_userfault(vmf, VM_UFFD_MISSING);
	}

// add_mm_counter_fast  增加进程匿名页面计数
	inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
	// 将匿名页添加到RMAP系统
	page_add_new_anon_rmap(page, vma, vmf->address, false);
	mem_cgroup_commit_charge(page, memcg, false, false);
	// 把匿名页面添加到LRU链表
	// lru_cache_add(page);
	lru_cache_add_active_or_unevictable(page, vma);
setpte:
//   将下面的参数设置到硬件页表中 
	set_pte_at(vma->vm_mm, vmf->address, vmf->pte, entry);

	/* No need to invalidate - it was non-present before */
	update_mmu_cache(vma, vmf->address, vmf->pte);
unlock:
	pte_unmap_unlock(vmf->pte, vmf->ptl);
	return ret;
release:
	mem_cgroup_cancel_charge(page, memcg, false);
	put_page(page);
	goto unlock;
oom_free_page:
	put_page(page);
oom:
	return VM_FAULT_OOM;
}

do_anonymous_page函数流程

 确保VMA不具备VM_SHARED 属性(if (vma->vm_flags & VM_SHARED))
     分配并且设置对应的PMD页表项(pte_alloc(vma->vm_mm, vmf->pmd))
     	 是否为写内存导致的缺页异常  (vmf->flags & FAULT_FLAG_WRITE)
     		N   创建只读页面
     			创建一个基于系统零页的特殊映射的页表项 pte_mkspecial(pfn_pte(my_zero_pfn(vmf->address),vma->vm_page_prot));
			Y   创建可写页面 
                分配物理页面(page = alloc_zeroed_user_highpage_movable(vma, vmf->address);)
                创建一个具有可写属性的PTE(pte_mkwrite(pte_mkdirty(entry));)
                增加匿名页计数(inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);)
                添加到RMAP和LRU链表中(page_add_new_anon_rmap)(lru_cache_add_active_or_unevictable)
        设置到硬件页表中(set_pte_at)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DipsyHu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值