Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230725
b: refs/heads/master
c: fed067d
h: refs/heads/master
i:
  230723: a7d9ec7
v: v3
  • Loading branch information
Michel Lespinasse authored and Linus Torvalds committed Jan 14, 2011
1 parent b1c3fa1 commit 115c6fd
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5ecfda041e4b4bd858d25bbf5a16c2a6c06d7272
refs/heads/master: fed067da46ad3b9acedaf794a5f05d0bc153280b
81 changes: 64 additions & 17 deletions trunk/mm/mlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,18 +377,10 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
int ret = 0;
int lock = newflags & VM_LOCKED;

if (newflags == vma->vm_flags ||
(vma->vm_flags & (VM_IO | VM_PFNMAP)))
if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
is_vm_hugetlb_page(vma) || vma == get_gate_vma(current))
goto out; /* don't set VM_LOCKED, don't count */

if ((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
is_vm_hugetlb_page(vma) ||
vma == get_gate_vma(current)) {
if (lock)
make_pages_present(start, end);
goto out; /* don't set VM_LOCKED, don't count */
}

pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
*prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
vma->vm_file, pgoff, vma_policy(vma));
Expand Down Expand Up @@ -424,14 +416,10 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
* set VM_LOCKED, __mlock_vma_pages_range will bring it back.
*/

if (lock) {
if (lock)
vma->vm_flags = newflags;
ret = __mlock_vma_pages_range(vma, start, end);
if (ret < 0)
ret = __mlock_posix_error_return(ret);
} else {
else
munlock_vma_pages_range(vma, start, end);
}

out:
*prev = vma;
Expand All @@ -444,7 +432,8 @@ static int do_mlock(unsigned long start, size_t len, int on)
struct vm_area_struct * vma, * prev;
int error;

len = PAGE_ALIGN(len);
VM_BUG_ON(start & ~PAGE_MASK);
VM_BUG_ON(len != PAGE_ALIGN(len));
end = start + len;
if (end < start)
return -EINVAL;
Expand Down Expand Up @@ -487,6 +476,58 @@ static int do_mlock(unsigned long start, size_t len, int on)
return error;
}

static int do_mlock_pages(unsigned long start, size_t len, int ignore_errors)
{
struct mm_struct *mm = current->mm;
unsigned long end, nstart, nend;
struct vm_area_struct *vma = NULL;
int ret = 0;

VM_BUG_ON(start & ~PAGE_MASK);
VM_BUG_ON(len != PAGE_ALIGN(len));
end = start + len;

down_read(&mm->mmap_sem);
for (nstart = start; nstart < end; nstart = nend) {
/*
* We want to fault in pages for [nstart; end) address range.
* Find first corresponding VMA.
*/
if (!vma)
vma = find_vma(mm, nstart);
else
vma = vma->vm_next;
if (!vma || vma->vm_start >= end)
break;
/*
* Set [nstart; nend) to intersection of desired address
* range with the first VMA. Also, skip undesirable VMA types.
*/
nend = min(end, vma->vm_end);
if (vma->vm_flags & (VM_IO | VM_PFNMAP))
continue;
if (nstart < vma->vm_start)
nstart = vma->vm_start;
/*
* Now fault in a range of pages within the first VMA.
*/
if (vma->vm_flags & VM_LOCKED) {
ret = __mlock_vma_pages_range(vma, nstart, nend);
if (ret < 0 && ignore_errors) {
ret = 0;
continue; /* continue at next VMA */
}
if (ret) {
ret = __mlock_posix_error_return(ret);
break;
}
} else
make_pages_present(nstart, nend);
}
up_read(&mm->mmap_sem);
return ret; /* 0 or negative error code */
}

SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
{
unsigned long locked;
Expand All @@ -512,6 +553,8 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
error = do_mlock(start, len, 1);
up_write(&current->mm->mmap_sem);
if (!error)
error = do_mlock_pages(start, len, 0);
return error;
}

Expand Down Expand Up @@ -576,6 +619,10 @@ SYSCALL_DEFINE1(mlockall, int, flags)
capable(CAP_IPC_LOCK))
ret = do_mlockall(flags);
up_write(&current->mm->mmap_sem);
if (!ret && (flags & MCL_CURRENT)) {
/* Ignore errors */
do_mlock_pages(0, TASK_SIZE, 1);
}
out:
return ret;
}
Expand Down

0 comments on commit 115c6fd

Please sign in to comment.