Commit fb155c1619f056ae9765eed272cd6aba6e1a7399

Authored by Linus Torvalds
1 parent e4f5c82a92

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: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 12 additions and 4 deletions Side-by-side Diff

... ... @@ -377,6 +377,8 @@
377 377 unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
378 378 if (pfn == vma->vm_pgoff + off)
379 379 return NULL;
  380 + if (vma->vm_flags & VM_SHARED)
  381 + return NULL;
380 382 }
381 383  
382 384 /*
... ... @@ -1343,9 +1345,6 @@
1343 1345 struct mm_struct *mm = vma->vm_mm;
1344 1346 int err;
1345 1347  
1346   - if (addr != vma->vm_start || end != vma->vm_end)
1347   - return incomplete_pfn_remap(vma, addr, end, pfn, prot);
1348   -
1349 1348 /*
1350 1349 * Physically remapped pages are special. Tell the
1351 1350 * rest of the world about it:
1352 1351  
1353 1352  
... ... @@ -1359,9 +1358,18 @@
1359 1358 * VM_PFNMAP tells the core MM that the base pages are just
1360 1359 * raw PFN mappings, and do not have a "struct page" associated
1361 1360 * with them.
  1361 + *
  1362 + * There's a horrible special case to handle copy-on-write
  1363 + * behaviour that some programs depend on. We mark the "original"
  1364 + * un-COW'ed pages by matching them up with "vma->vm_pgoff".
1362 1365 */
  1366 + if (!(vma->vm_flags & VM_SHARED)) {
  1367 + if (addr != vma->vm_start || end != vma->vm_end)
  1368 + return incomplete_pfn_remap(vma, addr, end, pfn, prot);
  1369 + vma->vm_pgoff = pfn;
  1370 + }
  1371 +
1363 1372 vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
1364   - vma->vm_pgoff = pfn;
1365 1373  
1366 1374 BUG_ON(addr >= end);
1367 1375 pfn -= addr >> PAGE_SHIFT;