免费注册 查看新帖 |

Chinaunix

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

[内核入门] __alloc_pages()疑问 ?? [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-10-14 11:17 |只看该作者 |倒序浏览
  • MARK_USED()
    __alloc_pages()用于分配连续的一组页面,会调用到rmqueue()从空闲区找到合适的页面块并摘下,希望分配4个连续页面时,可能area[2]已经空了,就可以从area[3]分配一个8页面块,割切成两份4页面块,一块挂到area[2],一块作为分配到的页面。
    每个area为了快速知道哪些区间的页面块是空闲的,都对应一个位图,否则通过遍历area中的链表头确认效率太低了。
    问题在于摘下页面块,或者可能进行割切并将小块链入低一级的area时,对相应area的位图操作都是MARK_USED(),按道理应该是“一个MARK_USED(),一个MARK_UNUSED()”呀?
   

    原因是MARK_USED()这个宏函数的名字有点干扰人,至少我自己被干扰到了(为了避免抠字眼造成尴尬,我不敢说很多人了),它不是表示“标记为占用”,而是表示“对占用标记位进行操作”,最终调用到的btcl指令是用于反转,而不是单纯的置1或清0 。
  1. #include <stdio.h>

  2. static void change_bit(int nr, void *addr)
  3. {
  4.     __asm__ __volatile__(
  5.         "btcl %1,%0"
  6.         :"=m"(*(volatile long*)addr)
  7.         :"Ir"(nr));
  8. }

  9. int main()
  10. {
  11.     int n = 0;

  12.     change_bit(8, &n); // bit8由0反转为1
  13.     printf("%d\n", n);
  14.     change_bit(8, &n); // bit8由1反转为0
  15.     printf("%d\n", n);

  16.     return 0;
  17. }
复制代码

  • set_page_count() ??
    从图中的代码可以看出,当分配到需要的页面块后,为什么没有将这组中所有的页面使用计数置1,而只是set_page_count(page, 1),将这组最开始的页面置1?

论坛徽章:
0
2 [报告]
发表于 2016-10-16 11:00 |只看该作者
因为内核中页的分配和释放都是以2^x为单位的,所以只设置开始的页就可以了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP