Pages Menu
Categories Menu

Опубликовано | Нет комментариев

Отслеживание активности прерываний и DPC

Для отслеживания активности прерываний и DPC можно воспользоваться средством ProcessExplorer, открыв диалоговое окно SystemInformation (Системная информация) и перейдя во вкладку CPU (Центральный процессор), где будет показано количество прерываний и DPC-процедур, зафиксированное при каждом обновлении средством Process Explorer отображаемых результатов (по умолчанию с периодичностью в одну секунду).

системная-информацияпроцессы

Можно также отследить выполнение конкретных процедур обслуживания прерываний и отложенных вызовов процедур, используя встроенное отслеживание событий:

  1. Запустите перехват событий. Откройте окно командной строки, перейдите в каталог Microsoft Windows Performance Toolkit (обычно он находится в каталоге c:\Program Files) и наберите следующую команду1:   xperf –on PROC_THREAD+LOADER+DPC+INTERRUPT
  2. Остановите перехват событий, набрав следующую команду:   xperf –d dpcisr.etl
  3. Сгенерируйте отчеты для перехвата событий, набрав следующее:     xperf dpcisr.etl tracerpt \kernel.etl –report dpcisr.html –f html  В результате будет сгенерирована веб-страница dpcisr.html.
  4. Откройте файл report.html и раскройте подраздел DPC/ISR. Раскройте область DPC/ISR Breakdown и увидите сводку, показывающую время, затраченное на ISR-процедуры и DPC-вызовы каждым драйвером. Например, как на рисунке.

При запуске в отладчике ядра команды ln с указанием адреса каждой записи о событии показывается имя функции, выполняющей DPC или ISR:

lkd> ln 0x806321C7

(806321c7) ndis!ndisInterruptDpc

lkd> ln 0x820AED3F

(820aed3f) nt!IopTimerDispatch

lkd> ln 0x82051312

(82051312) nt!PpmPerfIdleDpc

Первым показан DPC-вызов, помещенный в очередь драйвером мини-порта сетевой карты NDIS. Вторым показан DPC-вызов обработки истечения времени общего таймера ввода-вывода. Третий адрес относится к DPC-вызову, предназначенному для выполнения операции простоя (idle).

Кроме использования этого средства для получения отчета в формате HTML, для просмотра подробного обзора всех DPC- ISR-событий можно воспользоваться средством Xperf Viewer, щелкнув в главном окне Xperf правой кнопкой мыши на пункте DPC and/or ISR CPU Usage graphs (Диаграммы использования центрального процессора DPC и ISR) и выбрав пункт Summary Table (Сводная таблица).

сводная-таблица

Вам будет дана возможность детально рассмотреть каждые DPC и ISR каждого драйвера, а также увидеть продолжительность и количество, как показано на следующем рисунке.

DPC-и-ISR

Механизм потоковых DPC-вызовов включен по умолчанию, но его можно отключить путем добавления нулевого DWORD-значения в параметр HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\kernel\ThreadDpcEnable. Поскольку потоковые DPC-вызовы могут быть выключены, разработчики драйверов, пользующиеся потоковыми DPC-вызовами, должны писать свои процедуры, следуя тем же правилам, которые распространяются на непотоковые вызовы.

Эти процедуры не могут обращаться к выгружаемой памяти, ждать диспетчеризации или выстраивать предположения насчет IRQL-уровня, с которым они выполняются. Кроме того, они не должны использовать API-функции KeAcquire/ReleaseSpinLockAtDpcLevel, поскольку функции предполагают, что центральный процессор имеет уровень dispatch. Вместо этого в потоковых DPC-вызовах нужно использовать функцию KeAcquire/ReleaseSpinLockForDpc, выполняющую соответствующее действие после проверки текущего IRQL.

Прерывания асинхронных вызовов процедур. Асинхронные вызовы процедур (Asynchronous procedure call, APC) дают пользовательским программам и системному коду способ выполнения в контексте конкретного пользовательского потока (а следовательно, в адресном пространстве конкретного процесса).

Поскольку APC-вызовы выстраиваются в очередь на выполнение в контексте конкретного потока и запускаются на IRQL-уровне, который ниже уровня DPC/dispatch, они не подпадают под такие же ограничения, которые накладываются на DPC. APC-процедура может получать ресурсы (объекты), ждать дескрипторов объектов, справляться с ошибками отсутствия страницы и вызывать системные службы.

APC-вызовы описываются объектом управления ядра, называемым APC-объектом. APC-вызовы, ожидающие выполнения, помещаются в управляемую ядром APC-очередь. В отличие от очереди DPC, которая видна всей системе, APC-очередь относится к конкретному потоку — у каждого потока есть своя собственная APC-очередь. При запросе на помещение в очередь APC-вызова ядро вставляет ее в очередь, принадлежащую тому потоку, который будет выполнять APC-процедуру.

Ядро, в свою очередь, запрашивает программное прерывание на APC-уровне а затем, когда поток через некоторое время начнет работать, в нем выполняется APC-вызов.

Существует два вида APC-вызовов: режима ядра и пользовательского режима. APC-вызовы режима ядра не требуют разрешения от целевого потока на запуск в его контексте, а APC-вызовы пользовательского потока требуют такого разрешения. APC-вызовы режима ядра прерывают поток и выполняются без его вмешательства или разрешения. Есть также два вида APC-вызовов режима ядра: обычные и специальные. Специальные APC-вызовы выполняются на уровне APC и позволяют APC-процедуре изменять некоторые APC-параметры.

Обычные APC-вызовы выполняются на уровне passive и получают измененные параметры от специальной APC-процедуры (или исходные параметры, если они не были изменены).

Обычные и специальные APC-вызовы могут быть отключены путем повышения IRQL на APC-уровень или путем вызова процедуры KeEnterGuardedRegion.

Она отключает APC-доставку, устанавливая поле SpecialApcDisable в структуре KTHREAD вызывающего потока.

Поток может отключить обычные APC-вызовы только путем вызова процедуры KeEnterCriticalRegion, которая устанавливает поле KernelApcDisable в структуре KTHREAD потока. В таблице сведено поведение каждого вида APC-вызова по вставке и доставке APC.

Вставка и доставка APC.

Вид APC-вызоваПоведение, связанное со вставкойПоведение, связанное с доставкой
Специальный (режим ядра)Вставляется в конец
списка APC-вызовов
режима ядра
Доставляется на APC-уровне, как только
понизится IRQL, и при условии, что поток не находится в защищенной области. Даются указатели на аргументы, определенные при
вставке APC-вызова
Обычный (режим ядра)Вставляется сразу
же после последнего
специального APC-вызова (во главе всех
остальных обычных
APC-вызовов)
Доставляется на уровне PASSIVE_LEVEL
после выполнения связанного специального
APC-вызова. Доставке задаются аргументы,
возвращенные связанным специальным APC-
вызовом (это могут быть исходные аргументы, использованные при вставке, или новые
аргументы)
Обычный (пользовательский режим)Вставляется в конец
списка APC-вызовов
пользовательского
режима
Доставляется на уровне PASSIVE_LEVEL,
как только понизится IRQL, и при условии,
что поток не находится в критической (или
защищенной) области, а также если поток
находится в состоянии готовности. Доставке
задаются аргументы, возвращенные связанным специальным APC-вызовом (это могут
быть исходные аргументы, использованные
при вставке, или новые аргументы)
Обычный
(пользовательский режим) Выход из потока(PsExitSpecialApc)
Вставляется в начало
списка APC-вызовов
пользовательского
режима
Доставляется на уровне PASSIVE_LEVEL
по возвращении в пользовательский режим, если находится в готовности к выполнению в состоянии ожидания. Доставке задаются
аргументы, возвращенные специальным APC-
вызовом, завершающим поток

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

Подсистемы среды окружения используют специальные APC-вызовы режима ядра, чтобы заставить поток приостановить или завершить свою работу, или же получить или установить контекст его выполнения в пользовательском режиме. Подсистема для UNIX-приложений использует APC-вызовы режима ядра для имитации доставки UNIX-сигналов процессам подсистемы для UNIX-приложений.

Другое важное применение APC-вызовов режима ядра относится к приостановке или завершению потока. Поскольку эти операции могут инициироваться произвольными потоками и направлены на другие произвольные потоки, ядро использует APC для запроса контекста потока, а также для завершения потока.

Драйверы устройств часто блокируют APC-вызовы или входят в критическую или охраняемую область, чтобы воспрепятствовать выполнению этих операций в тот момент, когда они удерживают блокировку, в противном случае блокировка может быть никогда не снята, и система зависнет.

APC-вызовы режима ядра используются также драйверами устройств.

Например, если инициирована операция ввода-вывода и поток перешел в режим ожидания, может быть спланирован запуск другого потока в другом процессе.

Когда устройство завершит передачу данных, система ввода-вывода должна каким-то образом вернуться в контекст потока, инициировавшего ввод-вывод, чтобы он мог скопировать результаты операции ввода-вывода в буфер в адресном пространстве процесса, содержащего этот поток. Для выполнения этого действия система ввода-вывода использует специальный APC-вызов режима ядра, если только приложение не использовало API-функция SetFileIoOverlappedRange или порты завершения ввода-вывода, — в таком случае либо буфер в памяти будет глобальным, либо копирование его произойдет только после того, как поток извлечет из порта признак завершения.

APC-вызовы пользовательского режима используются несколькими Windows API-функциями, такими как ReadFileEx, WriteFileEx и QueueUserAPC. Например, функции ReadFileEx и WriteFileEx позволяют вызывающему коду указать подпрограмму завершения, вызываемую при окончании операции ввода-вывода.

Завершение ввода-вывода реализуется постановкой APC-вызова в очередь того потока, который выдал запрос на ввод-вывод. Но обратный вызов процедуры завершения не обязательно происходит при постановке APC-вызова в очередь, поскольку APC-вызовы пользовательского режима доставляются потоку только в том случае, когда он находится в готовности к работе в режиме ожидания.

Поток может войти в режим ожидания либо в ожидании дескриптора объекта и обозначении, что его ожидание ведется в готовности к работе (с помощью Windows-функции WaitForMulti pleObjectsEx), либо путем непосредственной проверки на наличие отложенного APC (с помощью функции SleepEx). В обоих случаях, если APC-вызов пользовательского режима отложен, ядро прерывает (извещает) поток, передавая управление APC-процедуре, и возобновляет выполнение потока, когда APC-процедура завершит свою работу. В отличие от APC-вызовов режима ядра, которые могут выполняться на уровне APC, APC-вызовы пользовательского режима выполняются на уровне passive.

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

Если ожидание все еще не разрешено, поток возвращается в состояние ожидания, но теперь он будет в конце списка в отношении тех объектов, которые им ожидаются. Например, поскольку APC-вызовы используются для приостановки выполнения потока, если поток ожидает каких-нибудь объектов, его ожидание удаляется до тех пор, пока не возобновится выполнение потока, после чего этот поток будет в конце списка потоков, ожидающих доступа к объектам, которых он ждет. Поток, выполняющий ожидание в готовности к работе в режиме ядра, будет также разбужен при завершении своей работы. Это позволит такому потоку проверить, разбужен ли он в результате завершения своей работы или по какой-то другой причине.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

↓