Узнайте, какая задача генерирует много переключений контекста в Linux

Согласно vmstat, мой сервер Linux (2xCore2 Duo 2.5 ГГц) постоянно выполняет около 20 тыс. Переключений контекста в секунду.

# vmstat 3
procs -----------memory----------  ---swap-- -----io----  -system-- ----cpu----
 r  b   swpd   free   buff  cache    si   so    bi    bo   in    cs us sy id wa
 2  0   7292 249472  82340 2291972    0    0     0     0    0     0  7 13 79  0
 0  0   7292 251808  82344 2291968    0    0     0   184   24 20090  1  1 99  0
 0  0   7292 251876  82344 2291968    0    0     0    83   17 20157  1  0 99  0
 0  0   7292 251876  82344 2291968    0    0     0    73   12 20116  1  0 99  0

... но uptime показывает небольшую нагрузку: load average: 0.01, 0.02, 0.01 а также top не показывает процесс с высокой загрузкой процессора.

Как мне узнать, что именно генерирует эти переключатели контекста? Какой процесс / поток?

Я пытался проанализировать pidstat выход:

# pidstat -w 10 1

12:39:13          PID   cswch/s nvcswch/s  Command
12:39:23            1      0.20      0.00  init
12:39:23            4      0.20      0.00  ksoftirqd/0
12:39:23            7      1.60      0.00  events/0
12:39:23            8      1.50      0.00  events/1
12:39:23           89      0.50      0.00  kblockd/0
12:39:23           90      0.30      0.00  kblockd/1
12:39:23          995      0.40      0.00  kirqd
12:39:23          997      0.60      0.00  kjournald
12:39:23         1146      0.20      0.00  svscan
12:39:23         2162      5.00      0.00  kjournald
12:39:23         2526      0.20      2.00  postgres
12:39:23         2530      1.00      0.30  postgres
12:39:23         2534      5.00      3.20  postgres
12:39:23         2536      1.40      1.70  postgres
12:39:23        12061     10.59      0.90  postgres
12:39:23        14442      1.50      2.20  postgres
12:39:23        15416      0.20      0.00  monitor
12:39:23        17289      0.10      0.00  syslogd
12:39:23        21776      0.40      0.30  postgres
12:39:23        23638      0.10      0.00  screen
12:39:23        25153      1.00      0.00  sshd
12:39:23        25185     86.61      0.00  daemon1
12:39:23        25190     12.19     35.86  postgres
12:39:23        25295      2.00      0.00  screen
12:39:23        25743      9.99      0.00  daemon2
12:39:23        25747      1.10      3.00  postgres
12:39:23        26968      5.09      0.80  postgres
12:39:23        26969      5.00      0.00  postgres
12:39:23        26970      1.10      0.20  postgres
12:39:23        26971     17.98      1.80  postgres
12:39:23        27607      0.90      0.40  postgres
12:39:23        29338      4.30      0.00  screen
12:39:23        31247      4.10     23.58  postgres
12:39:23        31249     82.92     34.77  postgres
12:39:23        31484      0.20      0.00  pdflush
12:39:23        32097      0.10      0.00  pidstat

Похоже, что некоторые задачи postgresql выполняют>10 переключений контекста в секунду, но в любом случае это не все в сумме до 20 000.

Любая идея, как копать немного глубже для ответа?

5 ответов

Решение

Ну, довольно интересный случай. Попробуйте наблюдать watch -tdn1 cat /proc/interrupts, Видите ли вы какие-либо ценные изменения там?

Попробуйте использовать

pidstat -wt

Опция 't' также показывает потоки. Это может быть поток, который выполняет переключение контекста.

В более новой версии ядра

sudo perf record -e context-switches -a  # record the events

# then ctrl+c

sudo perf report # inspect the result

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

И вы можете найти причину, вызвавшую переключение контекста, с помощью флагов добавления -g (читаемый результат, определяемый символьной информацией)

sudo perf record -e context-switches -a -g

Переключение контекста нормальное. Процесс присваивается кванту времени, и если он завершает (или приостанавливается из-за необходимости использования ресурсов) то, что он должен сделать, может отпустить процессор.

Тем не менее, чтобы подсчитать, сколько переключений контекста сделано (это становится ответом на stackoverflow.com), потребуется внутренняя команда schedule() для записи в таблицы процессов. A такого нет, если вы запрограммируете свое собственное ядро, которое сможете увидеть, но это довольно сложно.

powertop может сказать вам, как часто процесс пробуждает процессор.

Другие вопросы по тегам