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 < start)
		return -EINVAL;
	if (end == start)
		return 0;
	/*寻找指定地址对应的vma*/
	vma = find_vma(current->mm, start);/*只保证 start<vma->end*/
	if (!vma || vma->vm_start > start)/*如果start<vm_start 说明vma不存在*/
		return -ENOMEM;

	for (nstart = start ; ; ) {/*遍历指定范围内的每一个vma*/
		unsigned int newflags;

		/* Here we know that  vma->vm_start <= nstart < vma->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函数这里不再列举了.