/var/log/messages

Sep 25, 2014 - 2 minute read - Comments - Linux kernel

kernel/fork.c の do_fork 始点で掘削してみる

と、言いつつ kernel/fork.c で定義されている手続きを確認したい欲もあり。とりあえず https://github.com/torvalds/linux.git から取得した repository の master branch 見てます。先頭 branch は f3670394c29f みたいです。

とりあえず

system call な i/f からのソレは kernel/fork.c で定義されているのかどうか。入口としては

  • kernel_thread 手続き
  • fork な system call
  • vfork な system call
  • clone な system call

なのかどうか。

とりあえずメモリ空間を確保するあたりに着目して確認、ってことで

    p = copy_process(clone_flags, stack_start, stack_size,
                     child_tidptr, NULL, trace);

から掘削開始。copy_process 手続きも kernel/fork.c にて定義されてます。もの凄く直感的なアレなのですが

    p = dup_task_struct(current);
    if (!p)
        goto fork_out;

に着目。この手続きも kernel/fork.c ですね。手続きの定義が以下。

static struct task_struct *dup_task_struct(struct task_struct *orig)

おそらくは orig なコピィを作って戻してるはず。あら、よく考えてみるに dup なソレってコピィは作らずに、なのだったような気がしてきていたり。

dup_task_struct 手続き確認

先頭の以下なあたり、順に掘ってみます。

    struct task_struct *tsk;
    struct thread_info *ti;
    unsigned long *stackend;
    int node = tsk_fork_get_node(orig);
    int err;

    tsk = alloc_task_struct_node(node);
    if (!tsk)
            return NULL;

    ti = alloc_thread_info_node(tsk, node);
    if (!ti)
            goto free_tsk;

    err = arch_dup_task_struct(tsk, orig);
    if (err)
            goto free_ti;

まず、tsk_fork_get_node から。定義は kernel/kthread.c で以下なコメントがあります。

/* called from do_fork() to get node information for about to be created task */
int tsk_fork_get_node(struct task_struct *tsk)

int 型の node って何なのかな。実装見るに NUMA 特有の実装みたい。つうか NUMA って何だったかと言いつつ wikipedia 見てみるに processor と memory の対を node と呼ぶ、とのこと。

基本的にはコピー元の task_struct なオブジェクトが kthread_task な場合に限定されている模様。で、alloc_task_struct_node は tsk_fork_get_node から戻される int の値が渡されています。

alloc_task_struct_node 手続きを掘削してみるに

  • arch/ia64/include/asm/thread_info.h で定義されている
  • kernel/fork.c で定義されている
  • kernel/fork.c の定義は CONFIG_ARCH_TASK_STRUCT_ALLOCATOR が #define されていない場合に有効な模様
  • kernel/fork.c の定義では kmem_cache_alloc_node の戻りを戻しています
  • kmem_cache_alloc_node の定義は mm/slab.c, mm/slob.c, mm/slub.c に存在

SLAB アロケータというやつか。slub なソレを見れば良いのかどうか。でも slub.c で定義されている kmem_cache_alloc_node は CONFIG_NUMA が定義されているの前提ですね。

最近の、は NUMA 前提なのかな。SMP なマシンが普通だし。

とりあえず

mm/slub.c で定義されている slab_alloc_node 手続きをコメント見つつ確認な方向。つうかそれ以前のもっと基本的な部分について確認する必要があるはず。

次回の #okidevops で kgdb で云々するはずなので、current から色々ほじくり回す、というのはどうなのか。