Commit fb155c1619f056ae9765eed272cd6aba6e1a7399
1 parent
e4f5c82a92
Exists in
master
and in
4 other branches
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
mm/memory.c
... | ... | @@ -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; |