Подтвердить что ты не робот

Что такое __kernel_vsyscall?

У меня есть ядро, которое сильно отличается от тех, которые я обычно получаю - большинство потоков находятся в __kernel_vsyscall():

  9 process 11334  0xffffe410 in __kernel_vsyscall ()
  8 process 11453  0xffffe410 in __kernel_vsyscall ()
  7 process 11454  0xffffe410 in __kernel_vsyscall ()
  6 process 11455  0xffffe410 in __kernel_vsyscall ()
  5 process 11474  0xffffe410 in __kernel_vsyscall ()
  4 process 11475  0xffffe410 in __kernel_vsyscall ()
  3 process 11476  0xffffe410 in __kernel_vsyscall ()
  2 process 11477  0xffffe410 in __kernel_vsyscall ()
  1 process 11323  0x08220782 in MyClass::myfunc ()

Что это значит?

EDIT: В частности, я обычно вижу много потоков в "pthread_cond_wait" и "___newselect_nocancel", и теперь они находятся во втором кадре в каждом потоке - почему это другое ядро?

4b9b3361

Ответ 1

__kernel_vsyscal - это метод, используемый linux-gate.so(частью ядра Linux) для создания системного вызова с использованием самого быстрого доступного метода, предпочтительно команды sysenter. Это объясняется Johan Petersson.

Ответ 2

Когда вы делаете системный вызов (например, чтение из файла, разговор с оборудованием, запись в сокеты), вы фактически создаете прерывание. Затем система обрабатывает прерывание в режиме ядра, и ваш вызов возвращается с результатом. В большинстве случаев для вас необычно иметь много потоков в syscall, если вы не делаете блокирующие вызовы, и в этом случае он ожидал.

В частности, это означает, что поток ожидает системный вызов на уровне ядра. Но это (к сожалению, по моим пунктам) уже в названии:)

Ответ 3

В дополнение к уже предоставленной хорошей ссылке на объяснение того, что linux-gate.so, я бы хотел ответить "почему это ядро ​​отличается?". Самые последние (более новые версии, чем 2.5.68) 32-разрядные Linux-системы используют страницу VDSO (aka linux-gate.so.1), и вскоре начнут работать 64-разрядные системы (64-битный VDSO был представлен в ядре 2.6.24).

Если вы разрабатываете более старую систему или старый glibc, то вы никогда не увидите __kernel_vsyscall(), потому что ядро ​​вообще не создавало VDSO, или потому что (старый) glibc не использует его даже когда присутствует VDSO.

Ответ 4

Как сказал Адам, главной причиной является производительность. См. Эту ссылку для некоторых старых номеров http://lkml.org/lkml/2002/12/9/13.

Если у вас есть ядро ​​с поддержкой vDSO, вы не используете прерывания для запуска системных вызовов, как сказал Стефан, на самом деле это было из-за того, что прерывания становились все медленнее, когда вся информация vDSO была добавлена ​​в ядро.