免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: f22jay
打印 上一主题 下一主题

[内存管理] 怎么区分一个物理页面属于内核还是用户空间 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2013-04-19 20:58 |显示全部楼层
f22jay 发表于 2013-04-19 11:21
在内存回收的时候,内核的页面不是不能回收吗,内存回收貌似是从管理区的inactive链表里面遍历的,那么内核 ...

只有文件映射,匿名映射等作为cache的page才会被加入lru链表,内核申请内存的方式如kmalloc、vmalloc或者直接alloc_page,都不会主动加入lru链表

论坛徽章:
0
2 [报告]
发表于 2013-04-19 22:26 |显示全部楼层
回复 11# amarant
是指直接对“/dev/mem” mmap 吗?buddy应该不感知吧


   

论坛徽章:
0
3 [报告]
发表于 2013-04-21 10:56 |显示全部楼层
回复 15# embeddedlwp
hugetlb page使用自己的freelist管理,不归回收算法管,不过THP之后好像支持了大页换出的功能

用户程序占用的页表资源属于内核态使用的资源,建立修改清除都是内核来做的;

/dev/mem不能访问系统的全内存吗?


   

论坛徽章:
0
4 [报告]
发表于 2013-04-21 16:10 |显示全部楼层
回复 20# embeddedlwp
对于/dev/mem设备文件来说,这个offset的意义就是物理地址的偏移吧
drivers/char/mem.c, mem设备文件的fops:
  1. static const struct file_operations mem_fops = {
  2.         .llseek                = memory_lseek,
  3.         .read                = read_mem,
  4.         .write                = write_mem,
  5.         .mmap                = mmap_mem,
  6.         .open                = open_mem,
  7.         .get_unmapped_area = get_unmapped_area_mem,
  8. };
复制代码
其中mmap和read接口来完成的内存的访问:

  1. /*
  2. * This funcion reads the *physical* memory. The f_pos points directly to the
  3. * memory location.
  4. */
  5. static ssize_t read_mem(struct file *file, char __user *buf,
  6.                         size_t count, loff_t *ppos)
  7. {
  8.         unsigned long p = *ppos;
  9.         ssize_t read, sz;
  10.         char *ptr;

  11.         if (!valid_phys_addr_range(p, count))
  12.                 return -EFAULT;
  13.         read = 0;
  14. #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
  15.         /* we don't have page 0 mapped on sparc and m68k.. */
  16.         if (p < PAGE_SIZE) {
  17.                 sz = size_inside_page(p, count);
  18.                 if (sz > 0) {
  19.                         if (clear_user(buf, sz))
  20.                                 return -EFAULT;
  21.                         buf += sz;
  22.                         p += sz;
  23.                         count -= sz;
  24.                         read += sz;
  25.                 }
  26.         }
  27. #endif

  28.         while (count > 0) {
  29.                 unsigned long remaining;

  30.                 sz = size_inside_page(p, count);

  31.                 if (!range_is_allowed(p >> PAGE_SHIFT, count))
  32.                         return -EPERM;

  33.                 /*
  34.                  * On ia64 if a page has been mapped somewhere as uncached, then
  35.                  * it must also be accessed uncached by the kernel or data
  36.                  * corruption may occur.
  37.                  */
  38.                 ptr = xlate_dev_mem_ptr(p);
  39.                 if (!ptr)
  40.                         return -EFAULT;

  41.                 remaining = copy_to_user(buf, ptr, sz);
  42.                 unxlate_dev_mem_ptr(p, ptr);
  43.                 if (remaining)
  44.                         return -EFAULT;

  45.                 buf += sz;
  46.                 p += sz;
  47.                 count -= sz;
  48.                 read += sz;
  49.         }

  50.         *ppos += read;
  51.         return read;
  52. }
复制代码
mmap实现:

  1. static int mmap_mem(struct file *file, struct vm_area_struct *vma)
  2. {
  3.         size_t size = vma->vm_end - vma->vm_start;

  4.         if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
  5.                 return -EINVAL;

  6.         if (!private_mapping_ok(vma))
  7.                 return -ENOSYS;

  8.         if (!range_is_allowed(vma->vm_pgoff, size))
  9.                 return -EPERM;

  10.         if (!phys_mem_access_prot_allowed(file, vma->vm_pgoff, size,
  11.                                                 &vma->vm_page_prot))
  12.                 return -EINVAL;

  13.         vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
  14.                                                  size,
  15.                                                  vma->vm_page_prot);

  16.         vma->vm_ops = &mmap_mem_ops;

  17.         /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
  18.         if (remap_pfn_range(vma,
  19.                             vma->vm_start,
  20.                             vma->vm_pgoff,
  21.                             size,
  22.                             vma->vm_page_prot)) {
  23.                 return -EAGAIN;
  24.         }
  25.         return 0;
  26. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP