提交 fb155c16 编写于 作者: L Linus Torvalds

Allow arbitrary shared PFNMAP's

A shared mapping doesn't cause COW-pages, so we don't need to worry
about the whole vm_pgoff logic to decide if a PFN-remapped page has
gone through COW or not.

This makes it possible to entirely avoid the special "partial remapping"
logic for the common case.
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 e4f5c82a
......@@ -377,6 +377,8 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_
unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
if (pfn == vma->vm_pgoff + off)
return NULL;
if (vma->vm_flags & VM_SHARED)
return NULL;
}
/*
......@@ -1343,9 +1345,6 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
struct mm_struct *mm = vma->vm_mm;
int err;
if (addr != vma->vm_start || end != vma->vm_end)
return incomplete_pfn_remap(vma, addr, end, pfn, prot);
/*
* Physically remapped pages are special. Tell the
* rest of the world about it:
......@@ -1359,9 +1358,18 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
* VM_PFNMAP tells the core MM that the base pages are just
* raw PFN mappings, and do not have a "struct page" associated
* with them.
*
* There's a horrible special case to handle copy-on-write
* behaviour that some programs depend on. We mark the "original"
* un-COW'ed pages by matching them up with "vma->vm_pgoff".
*/
if (!(vma->vm_flags & VM_SHARED)) {
if (addr != vma->vm_start || end != vma->vm_end)
return incomplete_pfn_remap(vma, addr, end, pfn, prot);
vma->vm_pgoff = pfn;
}
vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
vma->vm_pgoff = pfn;
BUG_ON(addr >= end);
pfn -= addr >> PAGE_SHIFT;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册