- 论坛徽章:
- 0
|
2007-12-23
mm/mlock.c
提供系统调用 sys_mlock,sys_munlock,sys_mlockall,sys_munlockall.
man mlock.c获取更多信息.
mlock提供一种让用户参与调整内核swap策略的一种方式.用户指定的地址范围
内核保证不交换到磁盘.
入口函数sys_mlock,sys_munlock,sys_mlockall,sys_munlockall效验参数,对
齐开始地址然后转交下级函数.
仅以sys_mlock为例,其余函数应该不在话下.
sys_mlock->do_mlock(start, len, 1);/*对于unlock只是第三个参数为0*/
static int do_mlock(unsigned long start, size_t len, int on)
{
unsigned long nstart, end, tmp;
struct vm_area_struct * vma, * next;
int error;
if (on && !capable(CAP_IPC_LOCK))
return -EPERM;
len = PAGE_ALIGN(len);
end = start + len;
if (end mm, start);/*只保证 startend*/
if (!vma || vma->vm_start > start)/*如果startvm_start vm_end. */
newflags = vma->vm_flags | VM_LOCKED;
if (!on)
newflags &= ~VM_LOCKED;
if (vma->vm_end >= end) {/*已经是最后一个vma了*/
/*mlock_fixup 能够处理各种fixup的情况*/
error = mlock_fixup(vma, nstart, end, newflags);
break;
}
tmp = vma->vm_end;
next = vma->vm_next;
/*mlock_fixup处理vma被分割的各种情况*/
error = mlock_fixup(vma, nstart, tmp, newflags);
if (error)
break;
nstart = tmp;
vma = next;
if (!vma || vma->vm_start != nstart) {
error = -ENOMEM;
break;
}
}
return error;
}
/*[start,end]在[vma_start,vma_end] 之间可以相等,不会超出此范围*/
static int mlock_fixup(struct vm_area_struct * vma,
unsigned long start, unsigned long end, unsigned int newflags)
{
int pages, retval;
if (newflags == vma->vm_flags)
return 0;
if (start == vma->vm_start) {/*起始地址于vma start*/
if (end == vma->vm_end)
retval = mlock_fixup_all(vma, newflags);
else
retval = mlock_fixup_start(vma, end, newflags);
} else {/*起始地址不等*/
if (end == vma->vm_end)
retval = mlock_fixup_end(vma, start, newflags);
else
retval = mlock_fixup_middle(vma, start, end, newflags);
}
if (!retval) {
/* keep track of amount of locked VM */
pages = (end - start) >> PAGE_SHIFT;
if (newflags & VM_LOCKED) {
pages = -pages;
/*锁定后调入指定范围内页面*/
make_pages_present(start, end);
}
vma->vm_mm->locked_vm -= pages;
}
return retval;
}
具体的fixup函数这里不再列举了.
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/79526/showart_1356088.html |
|