無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

/proc/slabinfo


/proc/slabinfoはスラブの状態を表示してくれます。その処理はmm/slab.cのs_show関数で行われます。

for_each_online_node(node)でループしているのは、NUMシステムを考慮してのことです。X86では0です。l3 = cachep->nodelists[node]でスラブを登録しているリストを取得します。このリストに全て未使用/一部使用/全て使用のスラブがリスト登録されています。

list_for_each_entryで、まず全て使用のスラブリストl3->slabs_fullを調べます。cachep->numは1スラブ内のオブジェクトの数で、slabp->inuseは使用中(実際kmallocで割り当てられているというのでなく、貸し出し用にプールしている配列に登録されていると言う事。)で、全て使用のスラブリスト故に、if (slabp->inuse != cachep->num && !error)ならprintkでその旨エラーメッセージを出すようにします。

active_objs += cachep->numで使用中オブジェクトを加算し、active_slabs++で使用中スラブをインクリメントします。

次のlist_for_each_entryは、部分使用としてのl3->slabs_partialの処理です。 部分使用しているはずだけにif (slabp->inuse == cachep->num && !error)ならエラー表示です。また!slabp->inuseまったく使用してないことになるため、これもエラー表示です。

active_objs += slabp->inuseで実際に使用中の分をactive_objsに加算します。active_slabs++をインクリメントしています。このことからactive_slabsはスラブ内の一部でもそのオブジェクトが使われているなら、active_slabsとなるようです。

最後のlist_for_each_entryは全く未使用のl3->slabs_freeの処理です。slabp->inuseは0であるはずです。使用/未使用のスラブ総数となるnum_slabsをインクリメントしています。

3つのスラブリストの処理が終わると、num_slabs += active_slabsで使用中スラブを足しこんで総スラブ数をセットし、num_objs = num_slabs * cachep->numでnum_objs にオブジェクトの総数をセットします。

あとは、seq_printfで各情報を表示するだけです。
static int s_show(struct seq_file *m, void *p)
{
       struct kmem_cache *cachep = list_entry(p, struct kmem_cache, next);
       struct slab *slabp;
       unsigned long active_objs;
       unsigned long num_objs;
       unsigned long active_slabs = 0;
       unsigned long num_slabs, free_objects = 0, shared_avail = 0;
       const char *name;
       char *error = NULL;
       int node;
       struct kmem_list3 *l3;

       active_objs = 0;
       num_slabs = 0;
       for_each_online_node(node) {
               l3 = cachep->nodelists[node];
               if (!l3)
                       continue;

               check_irq_on();
               spin_lock_irq(&l3->list_lock);

               list_for_each_entry(slabp, &l3->slabs_full, list) {
                       if (slabp->inuse != cachep->num && !error)
                               error = "slabs_full accounting error";
                       active_objs += cachep->num;
                       active_slabs++;
               }
               list_for_each_entry(slabp, &l3->slabs_partial, list) {
                       if (slabp->inuse == cachep->num && !error)
                               error = "slabs_partial inuse accounting error";
                       if (!slabp->inuse && !error)
                               error = "slabs_partial/inuse accounting error";
                       active_objs += slabp->inuse;
                       active_slabs++;
               }
               list_for_each_entry(slabp, &l3->slabs_free, list) {
                       if (slabp->inuse && !error)
                               error = "slabs_free/inuse accounting error";
                       num_slabs++;
               }
               free_objects += l3->free_objects;
               if (l3->shared)
                       shared_avail += l3->shared->avail;

               spin_unlock_irq(&l3->list_lock);
       }
       num_slabs += active_slabs;
       num_objs = num_slabs * cachep->num;
       if (num_objs - active_objs != free_objects && !error)
               error = "free_objects accounting error";

       name = cachep->name;
       if (error)
               printk(KERN_ERR "slab: cache %s error: %s\n", name, error);

       seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
                  name, active_objs, num_objs, cachep->buffer_size,
                  cachep->num, (1 << cachep->gfporder));
       seq_printf(m, " : tunables %4u %4u %4u",
                  cachep->limit, cachep->batchcount, cachep->shared);
       seq_printf(m, " : slabdata %6lu %6lu %6lu",
                  active_slabs, num_slabs, shared_avail);

       seq_putc(m, '\n');
       return 0;
}
nameスラブ名
active_objs貸し出しオブジェクト総数
num_objs全オブジェクトの総数
cachep->buffer_size1オブジェクトのサイズ
cachep->num1スラブ内のオブジェクト数
(1 << cachep->gfporder)1スラブのページ数(2を基底としている)

cachep->limit貸し出しプール配列サイズ
cachep->batchcount貸し代プール配列に設定する単位
cachep->shared補助貸し出しプール配列サイズ(cachep->shared×cachep->batchcountがサイズ(たぶん)

active_slabs一部でも使用しているスラブ総数
num_slabs全スラブ総数
shared_avail補助貸し出しプール配列の空き数

なお、#if STATSでコンパイルした場合、スラブ獲得処理における統計情報も表示されるようになっています。

最終更新 2011/02/21 17:05:01 - north
(2011/02/21 17:04:26 作成)