免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5270 | 回复: 9
打印 上一主题 下一主题

分析一下do_mlock [复制链接]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-28 14:05 |只看该作者 |倒序浏览
如下代码来自于linux 2.4.18版本。中代码mlock.c


  1. static int do_mlock(unsigned long start, size_t len, int on)
  2. {
  3.         unsigned long nstart, end, tmp;
  4.         struct vm_area_struct * vma, * next;
  5.         int error;

  6.         if (on && !capable(CAP_IPC_LOCK))
  7.                 return -EPERM;
  8.         len = PAGE_ALIGN(len);
  9.         end = start + len;
  10.         if (end < start)
  11.                 return -EINVAL;
  12.         if (end == start)
  13.                 return 0;
  14.         vma = find_vma(current->;mm, start);
  15.         if (!vma || vma->;vm_start >; start)
  16.                 return -ENOMEM;

  17.         for (nstart = start ; ; ) {
  18.                 unsigned int newflags;

  19.                 /* Here we know that  vma->;vm_start <= nstart < vma->;vm_end. */

  20.                 newflags = vma->;vm_flags | VM_LOCKED;
  21.                 if (!on)
  22.                         newflags &= ~VM_LOCKED;

  23.                 if (vma->;vm_end >;= end) {
  24.                         error = mlock_fixup(vma, nstart, end, newflags);
  25.                         break;
  26.                 }

  27.                 tmp = vma->;vm_end;
  28.                 next = vma->;vm_next;
  29.                 error = mlock_fixup(vma, nstart, tmp, newflags);
  30.                 if (error)
  31.                         break;
  32.                 nstart = tmp;
  33.                 vma = next;
  34.                 if (!vma || vma->;vm_start != nstart) {
  35.                         error = -ENOMEM;
  36.                         break;
  37.                 }
  38.         }
  39.         return error;
  40. }
复制代码

                             
这个系统调用有函数sys_mlock调用。实现屏蔽内存中某些用户进程所要求的页。在函数sys_mlock中的开始部分,最len做了一些初始化,如下:

  1.         len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
  2.         start &= PAGE_MASK;

  3.         locked = len >;>; PAGE_SHIFT;
  4.         locked += current->;mm->;locked_vm;

  5.         lock_limit = current->;rlim[RLIMIT_MEMLOCK].rlim_cur;
  6.         lock_limit >;>;= PAGE_SHIFT;
复制代码


  1. 如此处理后在do_mlock之前
  2. len=(len+(start &~PAGE_MASK)+ ~PAGE_MASK)&PAGE_MASK;
  3. start &=PAGE_MASK;
  4. 在do_mlock初始话后,len可能如下
  5. len=(len+~PAGE_MASK)&PAGE_MASK;

  6. 这样一来,mlock要对由start所在页的起始地址开始,长度为len(注:len=(len+(start&~PAGE_MASK)+ ~PAGE_MASK)&PAGE_MASK)的内存区域的页进行加锁。

  7. 接下来,一起分析一下这个函数。并且有几个疑问。
  8. 1、这些具体内存区域的页是不是必须是常驻内存的?
  9. 2、通过fork()调用所创建的子进程能不能够继承由父进程调用mlock锁住的页面?
  10. 3、内存加锁没有使用压栈技术,这样被锁住多次的页面可以通过调用一次munlock或者munlockall释放相应的页面会不会出现问题?
复制代码

[ 本帖最后由 mq110 于 2006-3-13 19:14 编辑 ]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2003-07-30 11:36 |只看该作者

分析一下do_mlock

大鹰,menp9999,帮忙分析一下啊。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2003-07-30 12:13 |只看该作者

分析一下do_mlock

嗯,看到了,所以帮你置顶,最近太忙了,公司项目一大堆,一般我都是工作上碰到什么技术问题提出来大家交流,估计你的时间比较多吧,或者你在工作中遇到这样的难题?这一块我没怎么认真去看,主要实际工作用不到

等我忙完有闲功夫了,帮你好好分析一下,这贴子先置顶,你先和menp9999讨论哈

论坛徽章:
0
4 [报告]
发表于 2003-08-16 23:21 |只看该作者

分析一下do_mlock

偶然看到这个帖子,我没有多少时间来看核心,而且我觉得也没有
必要,除非工作需要,那令当别论。
仔细看了内容,感觉程序本是没有什么太多可探讨的,倒是几个疑问
很有讨论的价值,我在这里说说我的理解:

1、这些具体内存区域的页是不是必须是常驻内存的?

这些页不一定在内存中,其实 do_mlock 就是做了一个 VM_LOCKED
的标志,这样在换页时,核心不会将已加锁的页换出,同时如果它
不在物理内存中,则将它加入到 active_list 中。再次换页时,
会将它调入内存,这些都可以在 vmscan.c  中看到。

2、通过fork()调用所创建的子进程能不能够继承由父进程调用mlock锁住的页面?

这个问题恐怕不可能,fork 中复制子进程时直接将 VM_LOCKED 标识
取消,这也可以理解,如果 mlock 了一块普通内存,其目的就是强制
内存驻留,子进程无法访问父进程的内存区域,显然不需要,而如果
mlock 了一块共享内存,那么也没有必要在子进程中继承这个状态,
我想这可能更多的时为性能考虑,毕竟物理内存是宝贵的,所以设计者
要求你显式的调用。

3、内存加锁没有使用压栈技术,这样被锁住多次的页面可以通过调用一次munlock或者munlockall释放相应的页面会不会出现问题?  

我想这个问题应该从应用的角度来考虑,单独在核心看来,不会有任何
问题,内存常驻无非是为了性能,即使没有常驻,也仅仅是性能的损失,
没有其他问题。

论坛徽章:
0
5 [报告]
发表于 2003-10-31 04:02 |只看该作者

分析一下do_mlock

楼上说的前两点我都同意。
我再说一点我对第三点的补充: 不用压栈确实不应该。我觉得不应该光从内核的角度来考虑。还是要从安全的角度来考虑才行。

论坛徽章:
0
6 [报告]
发表于 2003-11-01 05:50 |只看该作者

分析一下do_mlock

完全同意 CHEYENNE 的~~~~~~~

论坛徽章:
0
7 [报告]
发表于 2004-02-06 15:04 |只看该作者

分析一下do_mlock

我是新手,在读内核,还没有读完,所以就这个问题额外问一下大家,
do_mlock()最后会调用mlock_fixup_all ,
static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags)
{
        spin_lock(&vma->;vm_mm->;page_table_lock);
        vma->;vm_flags = newflags;
        spin_unlock(&vma->;vm_mm->;page_table_lock);
        return 0;
}

vma->;vm_flags = newflags之前,有spin_lock()(这个函数我还没有读到),如果执行spin_lock时进程被挂起了,是不是内核有什么机制保证
vma所指向的vm_area_struct结构以及它所代表的区间中的那些物理页
不被其他的进程(比如kswapd)操作?
如果有?大概是怎么回事情啊???

谢谢。

论坛徽章:
0
8 [报告]
发表于 2004-07-13 22:12 |只看该作者

分析一下do_mlock

我顶!!!

论坛徽章:
0
9 [报告]
发表于 2004-10-27 10:24 |只看该作者

分析一下do_mlock

小小狗不要到处灌水!

论坛徽章:
0
10 [报告]
发表于 2006-03-13 13:19 |只看该作者
谢谢 收藏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP