Messages in this thread Patch in this message | | | Date | Fri, 3 Oct 2003 15:23:49 -0700 | From | Andrew Morton <> | Subject | Re: mlockall and mmap of IO devices don't mix |
| |
Joe Korty <joe.korty@ccur.com> wrote: > > 2.6.0-test6: the use of mlockall(2) in a process that has mmap(2)ed > the registers of an IO device will hang that process uninterruptibly. > The task runs in an infinite loop in get_user_pages(), invoking > follow_page() forever.
whoops.
I think the right fix is in get_user_pages(): if the region is VM_IO then don't call follow_page() at all.
Something like this?
25-akpm/mm/memory.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-)
diff -puN mm/memory.c~get_user_pages-handle-VM_IO mm/memory.c --- 25/mm/memory.c~get_user_pages-handle-VM_IO Fri Oct 3 15:22:18 2003 +++ 25-akpm/mm/memory.c Fri Oct 3 15:22:18 2003 @@ -683,6 +683,7 @@ int get_user_pages(struct task_struct *t struct page **pages, struct vm_area_struct **vmas) { int i; + int vm_io; unsigned int flags; /* @@ -739,8 +740,8 @@ int get_user_pages(struct task_struct *t } #endif - if (!vma || (pages && (vma->vm_flags & VM_IO)) - || !(flags & vma->vm_flags)) + vm_io = vma->vm_flags & VM_IO; + if (!vma || (pages && vm_io) || !(flags & vma->vm_flags)) return i ? : -EFAULT; if (is_vm_hugetlb_page(vma)) { @@ -750,8 +751,14 @@ int get_user_pages(struct task_struct *t } spin_lock(&mm->page_table_lock); do { - struct page *map; - while (!(map = follow_page(mm, start, write))) { + struct page *map = NULL; + + /* + * We don't follow pagetables for VM_IO regions - they + * have no pageframes. And the caller passed NULL + * for `pages' anyway. + */ + while (!vm_io && !(map = follow_page(mm,start,write))) { spin_unlock(&mm->page_table_lock); switch (handle_mm_fault(mm,vma,start,write)) { case VM_FAULT_MINOR: _
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |