Re: mlockall and mmap of IO devices don't mix

Andrew Morton
2003-10-03T23:15:46Z

Joe Korty <joe.korty@ccur.com> wrote:
>
> Sigh. No go; it *looks* good but my app still locks up....

Or we could use that VM_RESERVED thing?

25-akpm/mm/memory.c | 15 +++++++++++----
drivers/char/mem.c | 0
2 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 16:12:50 2003
+++ 25-akpm/mm/memory.c Fri Oct 3 16:15:07 2003
@@ -683,6 +683,7 @@ int get_user_pages(struct task_struct *t
struct page **pages, struct vm_area_struct **vmas)
{
int i;
+ int special;
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))
+ special = vma->vm_flags & (VM_IO | VM_RESERVED);
+ 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 or
+ * mappings of /dev/mem - they may have no pageframes.
+ * And the caller passed NULL for `pages' anyway.
+ */
+ while (!special && !(map=follow_page(mm,start,write)) {
spin_unlock(&mm->page_table_lock);
switch (handle_mm_fault(mm,vma,start,write)) {
case VM_FAULT_MINOR:
diff -puN drivers/char/mem.c~get_user_pages-handle-VM_IO drivers/char/mem.c

_