Написание системного вызова для подсчета переключений контекста процесса - PullRequest
8 голосов
/ 15 февраля 2012

Мне нужно сделать системный вызов для подсчета добровольных и недобровольных переключений контекста процесса.Я уже знаю шаги по добавлению нового системного вызова в ядро ​​Linux, но я понятия не имею, с чего начать для функции переключения контекста.Есть идеи?

Ответы [ 4 ]

9 голосов
/ 16 февраля 2012

Если ваш системный вызов должен сообщать только статистику, вы можете использовать код подсчета переключений контекста, который уже находится в ядре.

системный вызов wait3 или системный вызов getrusage уже сообщает о количестве переключений контекста в struct rusage полях:

struct rusage {
 ...
    long   ru_nvcsw;         /* voluntary context switches */
    long   ru_nivcsw;        /* involuntary context switches */
};

Вы можете попробовать это, запустив:

$ /usr/bin/time -v /bin/ls -R
....
    Voluntary context switches: 1669
    Involuntary context switches: 207

где "/bin/ls -R" - любая программа.

Поиск "struct rusage" в исходных кодах ядра позволяет найти this accumulate_thread_rusage в kernel / sys.c, который обновляет структуру rusage. Читается с struct task_struct *t; поля t->nvcsw; и t->nivcsw;:

1477  static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r)
1478  {
1479        r->ru_nvcsw += t->nvcsw;    // <<=== here
1480        r->ru_nivcsw += t->nivcsw;
1481        r->ru_minflt += t->min_flt;
1482        r->ru_majflt += t->maj_flt;

Затем вам нужно поискать nvcsw и nivcsw в папке ядра, чтобы узнать, как они обновляются ядром.

asmlinkage void __sched schedule (void) :

4124     if (likely(prev != next)) {         // <= if we are switching between different tasks
4125            sched_info_switch(prev, next);
4126            perf_event_task_sched_out(prev, next);
4127
4128            rq->nr_switches++;          
4129            rq->curr = next;
4130            ++*switch_count;     // <= increment nvcsw or nivcsw via pointer
4131
4132            context_switch(rq, prev, next); /* unlocks the rq */

Указатель switch_count из строки 4091 или строки 4111 того же файла.

PS: ссылка из perreal отличная: http://oreilly.com/catalog/linuxkernel/chapter/ch10.html (поиск context_swtch)

5 голосов
/ 16 февраля 2012

Это уже существует: виртуальный файл /proc/NNNN/status (где NNNN - десятичный идентификатор процесса, о котором вы хотите знать) содержит, среди прочего, количество как произвольных, так и недобровольных переключений контекста.В отличие от getrusage это позволяет узнать количество переключений контекста для любого процесса, а не только дочерних элементов.Подробнее см. Справочную страницу proc(5) .

0 голосов
/ 30 марта 2015

Общее количество переключений контекста

cat /proc/PID/sched|grep nr_switches

Добровольное переключение контекста

cat /proc/PID/sched | grep nr_voluntary_switches

Непроизвольное переключение контекста

cat /proc/PID/sched|grep nr_involuntary_switches

, где PID - это идентификатор процесса, который вы хотите отслеживать.

Однако, если вы хотитечтобы получить эту статистику путем исправления (создания перехвата) источника linux, код, связанный с планированием, находится в папке

kernel / sched /

дерева исходного кода.В частности,

kernel / sched / core.c содержит функцию schedule (), которая является кодом планировщика linux.Код CFS (полностью честный планировщик), который является одним из нескольких планировщиков, представленных в Linux, и наиболее часто используемый, присутствует в планировщике

/ kernel / sched / fair.c

() выполняется, когда когда-либо установлен флаг TIF_NEED_RESCHED, поэтому выясните, из каких мест устанавливается этот флаг (используйте cscope на источнике linux), что даст вам представление о типах переключений контекста, происходящих в процессе.

0 голосов
/ 16 февраля 2012

Процесс выполнит переключение контекста в случае блокировки, истечения кванта времени или прерываний и т. Д. В конце концов вызывается функция schedule ().Поскольку вы хотите посчитать его для каждого процесса отдельно, вы должны сохранить новую переменную для каждого процесса для подсчета количества переключений контекста.И вы можете обновлять эту переменную каждый раз в расписании веселья для текущего процесса.Используя ваш системный вызов, вы можете прочитать это значение.Вот фрагмент расписания функции пинто,

static void
schedule (void) 
{
  struct thread *cur = running_thread ();
  struct thread *next = next_thread_to_run ();
  struct thread *prev = NULL;

  ASSERT (intr_get_level () == INTR_OFF);
  ASSERT (cur->status != THREAD_RUNNING);
  ASSERT (is_thread (next));<br/>

  if (cur != next)
    prev = switch_threads (cur, next);  <== here you can update count of "cur"   
  thread_schedule_tail (prev);
}  
...