歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux內存管理之slab機制(概述)

Linux內存管理之slab機制(概述)

日期:2017/2/28 15:59:49   编辑:Linux教程

通過前面所有代碼的分析和總結,已經把各個部分熟悉了一遍,在此對Linux內核中slab機制做最後的總結。

伙伴系統算法采用頁作為基本內存區,這適合於大塊內存的請求。對於小內存區的申請,比如說幾十或幾百個字節,我們用slab機制。

Slab分配器把對象分組放進高速緩存。每個高速緩存都是同類型對象的一種“儲備”。包含高速緩存的主內存區被劃分為多個slab,每個slab由一個活多個連續的頁組成,這些頁中既包含已分配的對象,也包含空閒的對象。

相關閱讀:http://www.linuxidc.com/Linux/2012-01/51348.htm 與 http://www.linuxidc.com/Linux/2012-01/51349.htm

1,cache對象管理器

Cache對象管理器為kmem_cache結構,如下:

[cpp]

  1. /*
  2. * struct kmem_cache
  3. *
  4. * manages a cache.
  5. */
  6. struct kmem_cache {
  7. /* 1) per-cpu data, touched during every alloc/free */
  8. struct array_cache *array[NR_CPUS];/*local cache*/
  9. /* 2) Cache tunables. Protected by cache_chain_mutex */
  10. unsigned int batchcount;
  11. unsigned int limit;
  12. unsigned int shared;
  13. unsigned int buffer_size;/*slab中對象大小*/
  14. u32 reciprocal_buffer_size;/*slab中對象大小的倒數*/
  15. /* 3) touched by every alloc & free from the backend */
  16. unsigned int flags; /* constant flags */
  17. unsigned int num; /* # of objs per slab */
  18. /* 4) cache_grow/shrink */
  19. /* order of pgs per slab (2^n) */
  20. unsigned int gfporder;
  21. /* force GFP flags, e.g. GFP_DMA */
  22. gfp_t gfpflags;
  23. size_t colour;/*著色塊個數*/ /* cache colouring range */
  24. unsigned int colour_off;/* cache的著色塊的單位大小 */ /* colour offset */
  25. struct kmem_cache *slabp_cache;
  26. unsigned int slab_size;/*slab管理區大小,包含slab對象和kmem_bufctl_t數組*/
  27. unsigned int dflags; /* dynamic flags */
  28. /* constructor func */
  29. void (*ctor)(void *obj);
  30. /* 5) cache creation/removal */
  31. const char *name;
  32. struct list_head next;
  33. /* 6) statistics */
  34. #ifdef CONFIG_DEBUG_SLAB
  35. unsigned long num_active;
  36. unsigned long num_allocations;
  37. unsigned long high_mark;
  38. unsigned long grown;
  39. unsigned long reaped;
  40. unsigned long errors;
  41. unsigned long max_freeable;
  42. unsigned long node_allocs;
  43. unsigned long node_frees;
  44. unsigned long node_overflow;
  45. atomic_t allochit;/*cache命中計數,在分配中更新*/
  46. atomic_t allocmiss;/*cache未命中計數,在分配中更新*/
  47. atomic_t freehit;
  48. atomic_t freemiss;
  49. /*
  50. * If debugging is enabled, then the allocator can add additional
  51. * fields and/or padding to every object. buffer_size contains the total
  52. * object size including these internal fields, the following two
  53. * variables contain the offset to the user object and its size.
  54. */
  55. int obj_offset;
  56. int obj_size;
  57. #endif /* CONFIG_DEBUG_SLAB */
  58. /*
  59. * We put nodelists[] at the end of kmem_cache, because we want to size
  60. * this array to nr_node_ids slots instead of MAX_NUMNODES
  61. * (see kmem_cache_init())
  62. * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
  63. * is statically defined, so we reserve the max number of nodes.
  64. */
  65. struct kmem_list3 *nodelists[MAX_NUMNODES];
  66. /*
  67. * Do not add fields after nodelists[]
  68. */
  69. };

在初始化的時候我們看到,為cache對象、三鏈結構、本地cache對象預留了三個cache共分配。其他為通用數據cache,整體結構如下圖


其中,kmalloc使用的對象按照大小分屬不同的cache,32、64、128、……,每種大小對應兩個cache節點,一個用於DMA,一個用於普通分配。通過kmalloc分配的對象叫作通用數據對象。

可見通用數據cache是按照大小進行劃分的,結構不同的對象,只要大小在同一個級別內,它們就會在同一個general cache中。專用cache指系統為特定結構創建的對象,比如struct file,此類cache中的對象來源於同一個結構。

2,slab對象管理器

Slab結構如下

[cpp]
  1. /*
  2. * struct slab
  3. *
  4. * Manages the objs in a slab. Placed either at the beginning of mem allocated
  5. * for a slab, or allocated from an general cache.
  6. * Slabs are chained into three list: fully used, partial, fully free slabs.
  7. */
  8. struct slab {
  9. struct list_head list;
  10. /* 第一個對象的頁內偏移,對於內置式slab,colouroff成員不僅包括著色區
  11. ,還包括管理對象占用的空間
  12. ,外置式slab,colouroff成員只包括著色區。*/
  13. unsigned long colouroff;
  14. void *s_mem;/* 第一個對象的虛擬地址 *//* including colour offset */
  15. unsigned int inuse;/*已分配的對象個數*/ /* num of objs active in slab */
  16. kmem_bufctl_t free;/* 第一個空閒對象索引*/
  17. unsigned short nodeid;
  18. };

關於slab管理對象的整體框架以及slab管理對象與對象、頁面之間的聯系在前面的slab創建一文中已經總結的很清楚了。

3,slab著色

CPU訪問內存時使用哪個cache line是通過低地址的若干位確定的,比如cache line大小為32,那麼是從bit5開始的若干位。因此相距很遠的內存地址,如果這些位的地址相同,還是會被映射到同一個cache line。Slab cache中存放的是相同大小的對象,如果沒有著色區,那麼同一個cache內,不同slab中具有相同slab內部偏移的對象,其低地址的若干位是相同的,映射到同一個cache line。如圖所示。


如此一來,訪問cache line沖突的對象時,就會出現cache miss,不停的在cache line和內存之間來回切換,與此同時,其他的cache line可能無所事事,嚴重影響了cache的效率。解決這一問題的方法是通過著色區使對象的slab內偏移各不相同,從而避免cache line沖突。

著色貌似很好的解決了問題,實質不然,當slab數目不多時,著色工作的很好,當slab數目很多時,著色發生了循環,仍然存在cache line沖突的問題。

Copyright © Linux教程網 All Rights Reserved