More Related Content Similar to Slub data structure Similar to Slub data structure (20) Slub data structure2. README
• このスライドは以下の点に絞ってます
• SLUBのデータ構造
• slab cacheの作成
• 下記資料にあるSLUB data structuresを理解する
• http://events.linuxfoundation.org/sites/events/files/
slides/slaballocators.pdf
• memory control groupも絡むのですが、そこは気にしない方
向でコードリーディングしてます
3. Common variable name
• slub.cでよく使われれる変数名
• このスライドでも単にcと書いている場合はstruct kmem_cache_cpuの変数
を指します
• s
• struct kmem_cacheの変数
• c
• struct kmem_cache_cpuの変数
• n
• struct kmem_cache_nodeの変数
5. Slab allocator
implementations in Linux
• LinuxにおけるSlab allocator実装の一つ
• SLAB
• SunOSのSlab allocatorアルゴリズムに基づく
• SLUB
• 2.6.23からデフォルトのSlab allocatorに
• メモリのフラグメンテーションが発生しにくい
• SLOB
• サイズの小さいallocator
7. SLUB merge
• スラブキャッシュ作成時にすでに同サイズのスラブがあればそこ
にマージ
• slabinfo -aでマージされたSlabを確認可能
• kernel source treeにあるtools/vm/slabinfo.c
:at-0000104 <- sda1 buffer_head
:at-0000320 <- jbd2_transaction_s nfs_direct_cache
:t-0000024 <- scsi_data_buffer numa_policy
:t-0000032 <- sd_ext_cdb dnotify_struct kmalloc-32
:t-0000040 <- khugepaged_mm_slot Acpi-Namespace ext4_system_zone
9. Main structures
• struct kmem_cache
• include/linux/slub_def.h
• slab objectを管理する構造体
• 下記の2つの構造体はkmem_cache構造体のメンバ変数
• struct kmem_cache_cpu
• include/linux/slub_def.h
• slab objectへのアクセスはここから
• struct kmem_cache_node
• mm/slab.h
• NUMAノード毎のslabを指す
• struct page
• freelistへのポインタ、オブジェクト使用数などの変数が追加された
11. Slab object - offset
• struct kmem_cacheの変数offset
• 下記の条件に該当する場合、objectの先頭アドレス+offsetバイト目からをslab
objectにする
• slab objectのfree時にRCUを使う
• SLAB_POISONがセットされている
• コンストラクタが指定されている
• offsetは下記のサイズに設定される
• objectのサイズをsizeof(void *)の境界にあうようにalignしたサイズ
• SLAB_REDZONEがセットされている場合はRED ZONEのサイズも足す
12. struct kmem_cache
struct kmem_cache {
struct kmem_cache_cpu __percpu *cpu_slab;
/* Used for retriving partial slabs etc */
unsigned long flags;
unsigned long min_partial;
int size; /* The size of an object including meta data */
int object_size; /* The size of an object without meta data */
int offset; /* Free pointer offset. */
int cpu_partial; /* Number of per cpu partial objects to keep around
*/
struct kmem_cache_order_objects oo;
∼略∼
struct kmem_cache_node *node[MAX_NUMNODES];
};
Slab Objectの管理
に使う主な変数
13. struct kmem_cache_cpu
struct kmem_cache_cpu {
void **freelist; /* Pointer to next available object */
unsigned long tid; /* Globally unique transaction id */
struct page *page; /* The slab from which we are allocating */
struct page *partial; /* Partially allocated frozen slabs */
#ifdef CONFIG_SLUB_STATS
unsigned stat[NR_SLUB_STAT_ITEMS];
#endif
};
14. struct kmem_cache_node
struct kmem_cache_node {
spinlock_t list_lock;
∼略∼
#ifdef CONFIG_SLUB
unsigned long nr_partial;
struct list_head partial;
#ifdef CONFIG_SLUB_DEBUG
atomic_long_t nr_slabs;
atomic_long_t total_objects;
struct list_head full;
#endif
#endif
debug用途を除くとlistと個
数を保持する変数だけ
15. struct page
struct {
union {
pgoff_t index; /* Our offset within mapping. */
void *freelist; /* sl[aou]b first free object */
∼略∼
}
union {
∼略∼
/* Used for cmpxchg_double in slub */
unsigned long counters;
∼略∼
struct {
union {
∼略
struct { /* SLUB */
unsigned inuse:16;
unsigned objects:15;
unsigned frozen:1;
};
16. Slab data relation
• 現在のcpuで使用しているslabへのアクセス
• cよりアクセス
• c->freelist、c->pageなど
• s->cpu_slabから外されたslab
• s->node[node number]からアクセス
18. Create a slab
• slabの作成はkmem_cache_create()
• KMEM_CACHE(__struct, __flags) マクロもある
• kmem_cache_create()の時点ではslab objectsの作成はしない
• freelistの作成、slab objectの初期化などはkmem_cache_alloc()実行時
• 処理は2段階
• 最初にstruct kmem_cacheのオブジェクトを取得
• 次に取得したsの変数を設定
struct kmem_cache *
kmem_cache_create(const char *name, size_t size,size_t align,
unsigned long flags, void (*ctor)(void *))
19. slab creating flow
kmem_cache_create()
̶> __kmem_cache_alias()
̶> do_kmem_cache_create()
̶> kmem_cache_zalloc()
̶> __kmem_cache_create()
̶> kmem_cache_open()
̶> calucalate_sizes()
̶> init_kmem_cache_nodes()
̶> alloc_kmem_cache_cpus()
主なところ
24. __kmem_cache_create()
• kmem_cache_open()でsの初期化
• sysfsでオブジェクトが見えるように設定
[root@miko slab]# ls -al /sys/kernel/slab/
total 0
drwxr-xr-x 108 root root 0 Dec 14 01:54 .
drwxr-xr-x 9 root root 0 Dec 14 01:54 ..
lrwxrwxrwx 1 root root 0 Dec 13 18:29 Acpi-Namespace -> :t-0000040
lrwxrwxrwx 1 root root 0 Dec 13 18:29 Acpi-Operand -> :t-0000072
lrwxrwxrwx 1 root root 0 Dec 13 18:29 Acpi-Parse -> :t-0000048
lrwxrwxrwx 1 root root 0 Dec 13 18:29 Acpi-ParseExt -> :t-0000072
lrwxrwxrwx 1 root root 0 Dec 13 18:29 Acpi-State -> :t-0000080
drwxr-xr-x 3 root root 0 Dec 14 01:54 anon_vma
lrwxrwxrwx 1 root root 0 Dec 13 18:29 anon_vma_chain -> :t-0000064
drwxr-xr-x 3 root root 0 Dec 14 01:54 :at-0000016
symlinkがalias
(mergeされたもの)
28. alloc_kmem_cache_cpus()
• s->cpu_slabオブジェクトの設定
• __alloc_percpu()を使う
• init_kmem_cache_cpu()でslubで使うトランザ
クションIDの設定
/*
* The transaction ids are globally unique per cpu and per operation on
* a per cpu queue. Thus they can be guarantee that the cmpxchg_double
* occurs on the right processor and that there was no operation on the
* linked list in between.
*/
33. new_slab()
• alloca_slab()でfreelist用のpageを確保
• slab objectを初期化
for_each_object_idx(p, idx, s, start, page->objects) {
setup_object(s, page, p);
if (likely(idx < page->objects))
set_freepointer(s, p, p + s->size);
else
set_freepointer(s, p, NULL);
}
for_each_object_idxマクロの終了条件はidx <= page->objects
37. set_freepointer()
• object + s->offsetのところに次のobjectのアドレス
を設定
static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
{
*(void **)(object + s->offset) = fp;
}
for_each_object_idx(p, idx, s, start, page->objects) {
setup_object(s, page, p);
if (likely(idx < page->objects))
set_freepointer(s, p, p + s->size);
else
set_freepointer(s, p, NULL);
}
39. 参考資料
• Slab allocators in the Linux Kernel: SLAB, SLOB, SLUB
• http://events.linuxfoundation.org/sites/events/files/
slides/slaballocators.pdf
• Linux Kernel Watch番外編 Linuxメモリ管理の最先端を探
る
• http://www.atmarkit.co.jp/flinux/rensai/watch2008/
watchmema.html