国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
slab分配器簡明分析
這還是暑假之前寫的總結(jié)... 這幾天一個kernel群里老有人問關(guān)于slab方面的問題... 所以就在這里把些的總結(jié)貼一下... 獻丑了...

Slab Allocator 邏輯結(jié)構(gòu)如下圖所示:

如圖,主要結(jié)構(gòu)包括 cache 以及 slabs。故相應(yīng)的數(shù)據(jù)結(jié)構(gòu)有 cache 描述符和 slab 描述符。
cache 描述符
          struct kmem_cache_s {
               /* full, partial first, then free */
               struct list_head         slabs_full;
               struct list_head         slabs_partial;
               struct list_head         slabs_free;
               unsigned int             objsize;
            unsigned int         flags;     /* constant flags */
            unsigned int         num;       /* # of objs per slab */
            spinlock_t           spinlock;
      #ifdef CONFIG_SMP
            unsigned int         batchcount;
      #endif
            unsigned int         gfporder;
            unsigned int         gfpflags;
            size_t               colour;         /* cache colouring range */
            unsigned int         colour_off;     /* colour offset */
            unsigned int         colour_next; /* cache colouring */
            kmem_cache_t               *slabp_cache;
            unsigned int         growing;
            unsigned int         dflags;         /* dynamic flags */
            /* constructor func */
            void (*ctor)(void *, kmem_cache_t *, unsigned long);
            /* de-constructor func */
            void (*dtor)(void *, kmem_cache_t *, unsigned long);
            unsigned long        failures;
            char           name[CACHE_NAMELEN];
            struct list_head     next;
      #ifdef CONFIG_SMP
            cpucache_t           *cpudata[NR_CPUS];
      #endif
      #if STATS
            unsigned long        num_active;
            unsigned long        num_allocations;
            unsigned long        high_mark;
            unsigned long        grown;
            unsigned long        reaped;
            unsigned long              errors;
      #ifdef CONFIG_SMP
            atomic_t       allochit;
            atomic_t       allocmiss;
            atomic_t       freehit;
            atomic_t       freemiss;
      #endif
      #endif
};
各個字段含義如下:
slab_*                  保存slabs的鏈表,如上圖,full、partial和empty。
objsize                 裝入緩存器中的每個”對象”的大小。
flags                   決定當(dāng)處理這個緩存器時,分配器的部分行為。見8.1.2
num                     每個slab包含的”對象”的數(shù)量
  spinlock             保護這個結(jié)構(gòu)的自旋鎖,防止并發(fā)訪問
  batchcount           決定對于每個CPU的緩存器,一次所分配的”對象”的數(shù)量
  gfporder             表示slab的頁面的數(shù)量。每slab有2^gfporder個頁面。因為這
                       是伙伴分配器所提供的分配大小。
  gfpflags             保存當(dāng)調(diào)用伙伴分配器分配頁面時所用到GFP標(biāo)識。
  colour               每個slab會盡可能的將”對象”保存到不同的高速緩存行。緩存器著色
                       會在8.1.5節(jié)深入討論。
  colour_off           保持slabs對齊到的字節(jié)數(shù)。例如,對于size-X緩存器里的slab會對齊到
                       L1高速緩存。
  colour_next          下一個要使用的顏色行。當(dāng)這個值達到colour時就會反繞到0。
  growing              設(shè)置這個標(biāo)識可以表示這個緩存器的大小是否增加了。如果增加了,
                       則在內(nèi)存緊張時,選擇它來獲取空閑的slabs的可能性會更小。
  dflags               在緩存器存在期間會改變的動態(tài)標(biāo)識。
  ctor                 一個復(fù)雜的”對象”可以可選的提供一個構(gòu)造函數(shù)來初始化每個新
                       的”對象”。這是指向那個函數(shù)的指針,而且可以是NULL。
  dtor                 析構(gòu)函數(shù)的指針,可以是NULL。
  failure              在代碼中不在使用這個字段,因此都初始化為0。
  name                 每個緩存器的名稱
  next                 緩存器鏈表上的下一個緩存器。
  cpudata              每CPU數(shù)據(jù),指向描述一小組可用”對象”的管理結(jié)構(gòu)。
  num_active           在緩存器中當(dāng)前活躍的”對象”的數(shù)量
  num_allocations      在緩存器中已經(jīng)分配了的”對象”的數(shù)量的總數(shù)。
  high_mark            num_active能夠達到的最大的值
  grown                kmem_cache_grow()被調(diào)用的次數(shù)
  reaped               緩存器被釋放的次數(shù)
  allochit             分配時,從每CPU緩存中分配”對象”的次數(shù)
  allocmiss            與allochit相反
  freehit              將”對象”釋放到每CPU緩存中的次數(shù)
  freemiss             與freehit相反。
  這個結(jié)構(gòu)相當(dāng)?shù)拇?Slab Allocator中對每種”對象”都有一個對應(yīng)的cache。每個cache管理
  多個slab。Slab才是真正存放”對象”的地方。管理這些”對象”的結(jié)構(gòu)就是slab描述符。
  Slab 描述符

  typedef struct slab_s {
        struct list_head    list;
        unsigned long       colouroff;
        void           *s_mem;          /* including colour offset */
        unsigned int        inuse;           /* num of objs active in slab */
        kmem_bufctl_t             free;
  } slab_t;
  各個字段含義如下:
  list                 此 slab 所屬于的鏈表。這個字段是在緩存器中的 slab_full 或者
                       slab_patial 或者 slab_free 上。
  colouroff            這是離在 slab 中的第一個”對象”的基址的著色偏移值。                          第一個對象的
                     地址是 s_mem + colouroff。
  s_mem              給出在 slab 中第一個”對象”的起始地址。
  inuse              在 slab 中的活躍”對象”的個數(shù)。
  free               存儲空閑”對象”的 bufctls 數(shù)組。參見 8.2.3 中的詳細(xì)介紹。
  這個結(jié)構(gòu)僅僅是用來管理”對象”的,在創(chuàng)建 slab 時需要分配存放”對象”的內(nèi)存,所需內(nèi)存
  從 buddy allocator 中申請,內(nèi)存大小為其所屬 cache 中 gfporder 指定。顯然,所申請的內(nèi)
  存是連續(xù)的 2^cachep->gfporder 個頁面。Slab 描述符可以存放在這個所分配的內(nèi)存起始
  處,也可以放在另外的地方。如圖:


通用緩存器組
  typedef struct cache_sizes {
       size_t         cs_size;
       kmem_cache_t       *cs_cachep;
       kmem_cache_t       *cs_dmacachep;
  } cache_sizes_t;
  各字段含義如下:
  cs_size              這個通用緩存器的大小
  cs_cachep            用于在普通內(nèi)存中分配”對象”的緩存器指針
  cs_dmacachep         用于在 DMA 內(nèi)存中分配”對象”的緩存器指針
  在系統(tǒng)中靜態(tài)定義了這個類型的一個數(shù)組,其主要為大小不定的一些通用結(jié)構(gòu)分配內(nèi)存。
  例如,如過 Slab 描述符的位置是 Off_Slab,則這個 Slab 描述符以及其后的 kmem_bufctl_t[]
  就放在這個通用緩存器組中的某一個緩存器里。
下面所要將到的數(shù)據(jù)結(jié)構(gòu)是針對 SMP 系統(tǒng)進行優(yōu)化所用到的數(shù)據(jù)結(jié)構(gòu):
每 CPU cache
  typedef struct cpucache_s {
        unsigned int avail;
        unsigned int limit;
  } cpucache_t;
  avail      在這個 cpucache 上空閑”對象”的數(shù)量。
  limit      可以存在的空閑”對象”的總數(shù)。
  每個 CPU 都有一個對應(yīng)的小的本地 cache,這個 cache 并不是上面所提到的 cache 描述符。
  這個 cache 僅僅是特定于某個 cache 描述符所管理的”對象”的數(shù)組。如 mm_struct 相關(guān)
  的 cache 描述符所管理的”對象”就是 mm_struct 類型的,則這個 CPU 的本地 cache 就是
  mm_struct 類型的數(shù)組。在為某 CPU 分配 cpucache_t 結(jié)構(gòu)時,除了分配 cpucache_t 結(jié)構(gòu)
  所需要的內(nèi)存外,也分配 limit*sizeof(void *)字節(jié)的內(nèi)存。當(dāng)然,它們是連續(xù)的。
  如代碼所示:
             ccnew = kmalloc(sizeof(void*)*limit+
                       sizeof(cpucache_t), GFP_KERNEL);
  ccnew 就是 cpucache_t *類型。
  因此 cpucache_t 結(jié)構(gòu)后面就是 limit 個 void 類型的指針。                 所以 avail 還有一個作用就是作
  為空閑”對象”的索引。如在從這個 CPU 本地 cache 分配一個”對象”時就有如下代碼:
             obj = cc_entry(cc)[--cc->avail];
  其中:
             #define cc_entry(cpucache) \
                  ((void **)(((cpucache_t*)(cpucache))+1))
  這個代碼就可以解釋上面所說的一切。
  更新每 CPU cache 信息所用到的數(shù)據(jù)結(jié)構(gòu)

  typedef struct ccupdate_struct_s
  {
        kmem_cache_t *cachep;
        cpucache_t *new[NR_CPUS];
  } ccupdate_struct_t;
  cachep 是正在被更新的緩存器的指針,new 是系統(tǒng)中每個 CPU 的 cpucache 描述符的數(shù)組。
  當(dāng)然僅有在 SMP 系統(tǒng)上設(shè)置 SMP 選項時才可用。
  在每 CPU cache 信息改變之后,在更新每個 CPU cache 信息時就不需要考慮并發(fā)性帶來
  的一致性問題,因為每個 CPU 只為從對應(yīng)的 ccpudata_struct_t->new[ID]中獲取新信息來
  更新自己本地的 cache。這樣就不需要用自旋鎖來保護。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux學(xué)習(xí)筆記
Linux slab
工程師深度:學(xué)通Linux內(nèi)核(含詳細(xì)代碼)
linux 3.4.10 內(nèi)核內(nèi)存管理源代碼分析11:Slab初始化
Linux內(nèi)存管理(二)
linux內(nèi)存管理源碼分析--頁框分配器
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服