免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: chishanmingshen

[内核同步] 关于per-cpu的疑问。。。 [复制链接]

论坛徽章:
0
发表于 2014-03-24 22:52 |显示全部楼层
本帖最后由 l4rmbr 于 2014-03-24 22:57 编辑

回复 1# chishanmingshen


chishanmingshen,

动态的per_cpu数据的分配 ,主要实现是一种叫pcpu_chunk的重要数据结构。
它有效的组织per_cpu数据的创建,管理,分配,回收。

这个per_cpu分配接口是基于虚拟内存的底层实现的,Linux中采取了两种分配所需虚拟内存的方式,一种是基于
slab的kmalloc接口,一种就是基于vmalloc接口。

mm/percpu.c是实现percpu数据分配接口的主要文件,
至于底层的内存分配,该文件根据不同的配置,可以基于上述
kmalloc接口或vmalloc接口实现。看代码(v3.14-rc7):
  1. 637 /*
  2. 638  * Chunk management implementation.
  3. 639  *
  4. 640  * To allow different implementations, chunk alloc/free and
  5. 641  * [de]population are implemented in a separate file which is pulled
  6. 642  * into this file and compiled together.  The following functions
  7. 643  * should be implemented.
  8. 644  *
  9. 645  * pcpu_populate_chunk          - populate the specified range of a chunk
  10. 646  * pcpu_depopulate_chunk        - depopulate the specified range of a chunk
  11. 647  * pcpu_create_chunk            - create a new chunk
  12. 648  * pcpu_destroy_chunk           - destroy a chunk, always preceded by full depop
  13. 649  * pcpu_addr_to_page            - translate address to physical address
  14. 650  * pcpu_verify_alloc_info       - check alloc_info is acceptable during init
  15. 651  */
  16. 652 static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size);
  17. 653 static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size);
  18. 654 static struct pcpu_chunk *pcpu_create_chunk(void);
  19. 655 static void pcpu_destroy_chunk(struct pcpu_chunk *chunk);
  20. 656 static struct page *pcpu_addr_to_page(void *addr);
  21. 657 static int __init pcpu_verify_alloc_info(const struct pcpu_alloc_info *ai);
  22. 658
  23. 659 #ifdef CONFIG_NEED_PER_CPU_KM
  24. 660 #include "percpu-km.c"
  25. 661 #else
  26. 662 #include "percpu-vm.c"
  27. 663 #endif
复制代码
根据需要,底层分配代码是基于vmalloc的mm/percpu-vm.c, 或基于kmalloc的mm/percpu-km.c

所以,看mm/percpu-vm.c , 其中有个pcpu_create_chunk()函数,创建用于分配per_cpu的chunk,
其实现正是调用了pcpu_get_vm_areas()

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-03-25 10:08 |显示全部楼层
@Tinnal
@l4rmbr


感谢回帖,谢谢!

貌似这些动态静态的空间是在一起的:(发现percpu相关的编译配置宏很多,我列出的应该只是其中一条路径

from 3.10
  1. pcpu_page_first_chunk():
  2.      vm.size = num_possible_cpus() * ai->unit_size;

  3. * @ai->unit_size specifies unit size and must be aligned to PAGE_SIZE
  4. * and equal to or larger than @ai->static_size + @ai->reserved_size +
  5. * @ai->dyn_size.
复制代码

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-03-25 13:39 |显示全部楼层
本帖最后由 chishanmingshen 于 2014-03-25 15:25 编辑

我的理解:应该是连续的了!如有错误,请不吝指点!

现在不清楚chunk的作用:

如果连续了,还要复杂的chunk allocation机制何用?而且chunk时也会调用pcpu_get_vm_areas重新映射?

请点津啊,谢谢!

论坛徽章:
0
发表于 2014-03-25 16:31 |显示全部楼层
本帖最后由 l4rmbr 于 2014-03-25 16:36 编辑
chishanmingshen 发表于 2014-03-25 13:39
我的理解:应该是连续的了!如有错误,请不吝指点!

现在不清楚chunk的作用:

如果连续了,还要复杂的chunk allocation机制何用?而且chunk时也会调用pcpu_get_vm_areas重新映射?


chishanmingshen,

首先,要明白percpu分配器的作用,它更多的use case是动态分配每cpu数据结构。

mm/percpu.c中定义了percpu分配器的接口:__alloc_percpu()函数。

内核其它模块的使用者,只需要传给这个函数一个要分配的数据结构大小和对齐要求两个参数就可以。
至于内部如何实现,不用关心。

其次,percpu分配器的内部实现是基于内核更底层的分配接口,即

              percpu分配器
                      |
              -----------------
             |                    |
          vmalloc         kmalloc

它采用一种叫pcpu_chunk的数据结构来有效的管理和组织由vmalloc/kmalloc分配而来的连续的
虚拟内存空间,每当外界通过__alloc_percpu()接口要求分配时,percpu分配器就从pcpu_chunk
中返回合适的空间;如果空间不够,再通过vmalloc/kmalloc接口分配更多内存。

你可以类比为:
堆空间是从内存中预先分配一块空间,然后响应用户的malloc()/free()要求。至于malloc()/free()
是如何管理这部分空间的,属于实现细节,不影响接口语义。这里malloc()就对应__alloc_percpu(),
chunk属于内部实现细节。

P.S. 我的博客是基于github page和jekyll的静态页面博客,不用使用数据库,通过git版本管理,挺方便。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-03-25 17:41 |显示全部楼层
本帖最后由 chishanmingshen 于 2014-03-25 20:00 编辑

回复 14# l4rmbr

谢谢解答!

   

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
发表于 2014-03-25 20:15 |显示全部楼层
回复 1# chishanmingshen


    我在2.6内核版本看到的percpu变量动态实现似乎有两种:一种利用vmalloc(这种是你代码提出的那种percpu分配器) 在mm/percpu.c,一种很简单利用的是kmalloc分配NR_CPUS * sizeof(object)的内存 在mm/allocpercpu.c.

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-03-25 20:27 |显示全部楼层
回复 16# kiongf


谢谢!基本明白了,我看的是最新版本,也一样,有2种实现。

   

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-03-26 09:41 |显示全部楼层
回复 14# l4rmbr

就是确实如1楼所说,空间是连续的!只是中间(chunk层)加了一层做分配和释放,维护使用情况。

如有错误,还请指正,谢谢!


   

论坛徽章:
0
发表于 2014-03-26 10:35 |显示全部楼层
回复 18# chishanmingshen

NO

除非是用kmalloc去要記憶體,這樣phy addr才會連續

vmalloc的話,只是virtual addr連續,在phy addr不見得連續


   

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-03-26 12:56 |显示全部楼层
回复 19# wth0722

谢谢!

不过,这个问题不涉及phy的!

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP