http://embexperts.com/viewthread.php?tid=131
在Linux中,per-cpu变量用在多处理器系统中,用来为系统中的每个cpu都生成一个变量的副本,以避开多处理器互斥中的加锁问题,另一个是cpu本地的变量可以充分利用cpu的硬件缓存,提高性能。本贴讨论一下Linux内核对per-cpu变量的代码实现。 静态percpu变量比较好理解,内核的代码也比较简洁明快。 Linux内核对percpu memory allocator使用了所谓chunk的实现方式,它实现了统一的静态per-cpu和动态per-cpu变量的实现(其实静态per-cpu变量的实现不需要chunk,但是为了统一,也把它放到chunk的管理体系,就算是大一统吧).
struct pcpu_chunk {
复制代码
struct list_head list; /* linked to pcpu_slot lists */ int free_size; /* free bytes in the chunk */ int contig_hint; /* max contiguous size hint */ void *base_addr; /* base address of this chunk */ int map_used; /* # of map entries used */ int map_alloc; /* # of map entries allocated */ int *map; /* allocation map */ void *data; /* chunk data */ bool immutable; /* no [de]population allowed */ unsigned long populated[]; /* populated bitmap */ }; contig_hint:该chunk所管理的副本空间中空闲空间大小。 base_addr:简单地说,副本空间首地址。1楼图的副本空间也是由一个chunk来管,称之为first chunk中,副本空间中的dynamic空间用来给动态per-cpu变量使用 map_used:为了对chunk所管理的副本空间分配情况的跟踪,用来表示可以管理的个数 map_alloc:已经分配的小块个数,因为每个分配的小块都是给动态per-cpu使用的,所以其实是已经分配的变量的个数 map:整数数组,用来表示副本空间分配情况。正数表示该空间空闲,负数就已经分配给一个变量了 data:指向分配的页数据 大体上就这些。 动态分配一个per-cpu变量时,在pcpu_slot空间查找空闲空间可以满足需要的chunk,如果找不到这样的chunk,那么重新分配一个chunk,用kzalloc函数。
static struct pcpu_chunk *pcpu_create_chunk(void)
复制代码
{ struct pcpu_chunk *chunk; struct vm_struct **vms; chunk = pcpu_alloc_chunk(); if (!chunk) return NULL; vms = pcpu_get_vm_areas(pcpu_group_offsets, pcpu_group_sizes, pcpu_nr_groups, pcpu_atom_size, GFP_KERNEL); if (!vms) { pcpu_free_chunk(chunk); return NULL; } chunk->data = vms; chunk->base_addr = vms[0]->addr - pcpu_group_offsets[0]; return chunk; } pcpu_group_offsets[0]对于非变态的系统都是0. 所以,动态分配per-cpu变量时,先在chunk所管理的副本空间(在VM区中),然后用到哪个页面就往那个对应的vm上提交物理页面。 |
per cpu 变量
最新推荐文章于 2024-08-09 15:19:12 发布
Linux内核对per-cpu变量的实现
2011-08-01 21:00