Re: Race between vmtruncate and mapped areas?

Dave McCracken
2003-05-13T23:00:08Z

[-- Attachment #1: Type: text/plain, Size: 946 bytes --]

--On Tuesday, May 13, 2003 15:49:29 -0700 William Lee Irwin III
<wli@holomorphy.com> wrote:

> That doesn't sound like it's going to help, there isn't a unique
> mmap_sem to be taken and so we just get caught between acquisitions
> with the same problem.

Actually it does fix it. I added code in vmtruncate_list() to do a
down_write(&vma->vm_mm->mmap_sem) around the zap_page_range(), and the
problem went away. It serializes against any outstanding page faults on a
particular page table. New faults will see that the page is no longer in
the file and fail with SIGBUS. Andrew's test case stopped failing.

I've attached the patch so you can see what I did.

Can anyone think of any gotchas to this solution?

Dave McCracken

======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
dmccr@us.ibm.com T/L 678-3059

[-- Attachment #2: vmtrunc-2.5.69-mm3-1.diff --]
[-- Type: text/plain, Size: 982 bytes --]

--- 2.5.69-mm3/mm/memory.c 2003-05-13 10:34:56.000000000 -0500
+++ 2.5.69-mm3-test/mm/memory.c 2003-05-13 17:39:45.000000000 -0500
@@ -1085,21 +1085,21 @@ static void vmtruncate_list(struct list_
len = end - start;

/* mapping wholly truncated? */
- if (vma->vm_pgoff >= pgoff) {
- zap_page_range(vma, start, len);
- continue;
- }
+ if (vma->vm_pgoff < pgoff) {

- /* mapping wholly unaffected? */
- len = len >> PAGE_SHIFT;
- diff = pgoff - vma->vm_pgoff;
- if (diff >= len)
- continue;
-
- /* Ok, partially affected.. */
- start += diff << PAGE_SHIFT;
- len = (len - diff) << PAGE_SHIFT;
+ /* mapping wholly unaffected? */
+ len = len >> PAGE_SHIFT;
+ diff = pgoff - vma->vm_pgoff;
+ if (diff >= len)
+ continue;
+
+ /* Ok, partially affected.. */
+ start += diff << PAGE_SHIFT;
+ len = (len - diff) << PAGE_SHIFT;
+ }
+ down_write(&vma->vm_mm->mmap_sem);
zap_page_range(vma, start, len);
+ up_write(&vma->vm_mm->mmap_sem);
}
}