マルチCPU(補足)


先のマルチCPUの記載で、プロセスの実行しているCPU ID取得のユーザ空間での実装がされてないとの認識でしたが、さらにCPU IDの検証をしましたら、スペースを区切りとするプロセス状態を表示する/proc/self/statの38項目に実装されています。cutの-f39は出力フォーマットによります。
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
0
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
0
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
1
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
1
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
1
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
0
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
1
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
1
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
0
[root@localhost ~]# cat /proc/self/stat | cut -d ' ' -f39
/proc/tid/statのコールバックです。selfはcurrentで、tidにより起動済み任意プロセスのCPU IDも確認できます。検証では39項目をCPU IDとしてcutコマンドでは取得していますが、do_task_stat()のtask_cpu(task)は38項目です。これはseq_printf()のフォーマットに20項目目を区切りとして0を追加している故です。(区切りなら別の文字の方がいいのでは・・・?)
int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
                       struct pid *pid, struct task_struct *task)
{
       return do_task_stat(m, ns, pid, task, 0);
}

static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
                       struct pid *pid, struct task_struct *task, int whole)
{
       unsigned long vsize, eip, esp, wchan = ~0UL;
       long priority, nice;
       int tty_pgrp = -1, tty_nr = 0;
       sigset_t sigign, sigcatch;
       char state;
       pid_t ppid = 0, pgid = -1, sid = -1;
       int num_threads = 0;
       int permitted;
       struct mm_struct *mm;
       unsigned long long start_time;
       unsigned long cmin_flt = 0, cmaj_flt = 0;
       unsigned long  min_flt = 0,  maj_flt = 0;
       cputime_t cutime, cstime, utime, stime;
       cputime_t cgtime, gtime;
       unsigned long rsslim = 0;
       char tcomm[sizeof(task->comm)];
       unsigned long flags;

       state = *get_task_state(task);
       vsize = eip = esp = 0;
       permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);
       mm = get_task_mm(task);
       if (mm) {
               vsize = task_vsize(mm);
               if (permitted) {
                       eip = KSTK_EIP(task);
                       esp = KSTK_ESP(task);
               }
       }

       get_task_comm(tcomm, task);

       sigemptyset(&sigign);
       sigemptyset(&sigcatch);
       cutime = cstime = utime = stime = 0;
       cgtime = gtime = 0;

       if (lock_task_sighand(task, &flags)) {
               struct signal_struct *sig = task->signal;

               if (sig->tty) {
                       struct pid *pgrp = tty_get_pgrp(sig->tty);
                       tty_pgrp = pid_nr_ns(pgrp, ns);
                       put_pid(pgrp);
                       tty_nr = new_encode_dev(tty_devnum(sig->tty));
               }

               num_threads = get_nr_threads(task);
               collect_sigign_sigcatch(task, &sigign, &sigcatch);

               cmin_flt = sig->cmin_flt;
               cmaj_flt = sig->cmaj_flt;
               cutime = sig->cutime;
               cstime = sig->cstime;
               cgtime = sig->cgtime;
               rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);

               if (whole) {
                       struct task_struct *t = task;
                       do {
                               min_flt += t->min_flt;
                               maj_flt += t->maj_flt;
                               gtime += t->gtime;
                               t = next_thread(t);
                       } while (t != task);

                       min_flt += sig->min_flt;
                       maj_flt += sig->maj_flt;
                       thread_group_times(task, &utime, &stime);
                       gtime += sig->gtime;
               }

               sid = task_session_nr_ns(task, ns);
               ppid = task_tgid_nr_ns(task->real_parent, ns);
               pgid = task_pgrp_nr_ns(task, ns);

               unlock_task_sighand(task, &flags);
       }

       if (permitted && (!whole || num_threads < 2))
               wchan = get_wchan(task);
       if (!whole) {
               min_flt = task->min_flt;
               maj_flt = task->maj_flt;
               task_times(task, &utime, &stime);
               gtime = task->gtime;
       }

       priority = task_prio(task);
       nice = task_nice(task);

       start_time =
               (unsigned long long)task->real_start_time.tv_sec * NSEC_PER_SEC
                               + task->real_start_time.tv_nsec;

       start_time = nsec_to_clock_t(start_time);

       seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu\n",
               pid_nr_ns(pid, ns),
               tcomm,
               state,
               ppid,
               pgid,
               sid,
               tty_nr,
               tty_pgrp,
               task->flags,
               min_flt,                                       <------------------- 10
               cmin_flt,
               maj_flt,
               cmaj_flt,
               cputime_to_clock_t(utime),
               cputime_to_clock_t(stime),
               cputime_to_clock_t(cutime),
               cputime_to_clock_t(cstime),
               priority,
               nice,
               num_threads,                                   <------------------- 20
               start_time,
               vsize,
               mm ? get_mm_rss(mm) : 0,
               rsslim,
               mm ? (permitted ? mm->start_code : 1) : 0,
               mm ? (permitted ? mm->end_code : 1) : 0,
               (permitted && mm) ? mm->start_stack : 0,
               esp,
               eip,
               task->pending.signal.sig[0] & 0x7fffffffUL,    <------------------- 30
               task->blocked.sig[0] & 0x7fffffffUL,
               sigign      .sig[0] & 0x7fffffffUL,
               sigcatch    .sig[0] & 0x7fffffffUL,
               wchan,
               0UL,
               0UL,
               task->exit_signal,
               task_cpu(task),                                <------------------- 38 CPU ID
               task->rt_priority,
               task->policy,
               (unsigned long long)delayacct_blkio_ticks(task),
               cputime_to_clock_t(gtime),
               cputime_to_clock_t(cgtime),
               (mm && permitted) ? mm->start_data : 0,
               (mm && permitted) ? mm->end_data : 0,
               (mm && permitted) ? mm->start_brk : 0);
       if (mm)
               mmput(mm);
       return 0;
}

static inline unsigned int task_cpu(const struct task_struct *p)
{
       return task_thread_info(p)->cpu;
}



最終更新 2016/08/24 19:07:23 - north
(2016/08/24 14:22:40 作成)


検索

アクセス数
3576082
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。