Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
При написании подпрограммы DpcForIsr или CustomDpc следует учитывать следующие моменты:
Подпрограмма DpcForIsr или CustomDpc должна синхронизировать доступ к физическому устройству, а также любые общие сведения о состоянии или ресурсы, которые поддерживает драйвер, с другими подпрограммами драйвера, которые обращаются к тем же устройствам или расположениям памяти.
Если подпрограмма DpcForIsr или CustomDpc предоставляет общий доступ к устройству или состоянию с ISR, он должен вызывать KeSynchronizeExecution, предоставляя адрес подпрограммы SynchCritSection , предоставленной драйвером, которая программирует устройство или обращается к общему состоянию. Дополнительные сведения см. в разделе Использование критически важных разделов.
Если подпрограмма DpcForIsr или CustomDpc использует состояние или ресурсы, такие как заблокированная очередь или объект таймера, с подпрограммами, отличными от ISR, она должна защитить общее состояние или ресурсы с помощью инициализированной драйвером исполнительной спин-блокировки. Дополнительные сведения см. в разделе "Замки спина".
Подпрограммы DpcForIsr и CustomDpc выполняются на уровне IRQL = DISPATCH_LEVEL, что ограничивает набор вспомогательных подпрограмм, которые они могут вызывать.
Например, подпрограммы DpcForIsr и CustomDpc не могут получать доступ к страницам памяти и не могут выделять их, и они не могут ожидать, пока объекты диспетчера ядра будут переведены в сигнальное состояние. С другой стороны, они могут получить и освободить исполнительный спин-блокировку водителя с KeAcquireSpinLockAtDpcLevel и KeReleaseSpinLockFromDpcLevel, которые выполняются быстрее , чем KeAcquireSpinLock и KeReleaseSpinLock.
Хотя подпрограмма DPC не может выполнять блокирующие вызовы, она может ставить рабочий элемент в очередь для запуска в рабочем потоке системы , работающем в IRQL, равном PASSIVE_LEVEL. Рабочий элемент может выполнять блокирующие вызовы, ожидая завершения объектов диспетчера. Чтобы поставить рабочий элемент в очередь, функция DpcForIsr обычно вызывает процедуру, например, IoQueueWorkItem, а функция CustomDpc обычно вызывает процедуру ExQueueWorkItem.
Подпрограммы DpcForIsr и CustomDpc обычно отвечают за запуск следующей операции ввода-вывода на устройстве.
Для драйверов физических устройств с низким уровнем, использующих прямые операции ввода-вывода, эта ответственность может включать использование подпрограммы SynchCritSection для программирования устройства на передачу дополнительных данных для удовлетворения текущего IRP перед вызовом IoStartNextPacket.
Подпрограммы DpcForIsr и CustomDpc должны выполняться только в течение коротких периодов и должны делегировать максимальное количество обработки рабочим потокам.
Хотя подпрограмма DPC выполняется на процессоре, все потоки не могут работать на одном процессоре. Другие подпрограммы DPC, которые находятся в очереди и готовы к выполнению, могут быть заблокированы до завершения текущей процедуры DPC. Чтобы избежать снижения скорости реагирования системы, обычная подпрограмма DPC должна выполняться не более чем на 100 микросекунд при каждом вызове. Если задача требует более 100 микросекунд и должна выполняться на IRQL, равном DISPATCH_LEVEL, подпрограмма DPC должна завершиться после 100 микросекунд и запланировать выполнение одной или нескольких подпрограмм CustomTimerDpc, чтобы завершить задачу позже. Для получения дополнительной информации о подпрограммах CustomTimerDpc см. раздел Объекты таймера и DPC.
Подпрограмма DPC должна выполнять только задачи, которые должны выполняться на уровне DISPATCH_LEVEL, а затем делегировать оставшуюся работу, связанную с прерываниями, потокам, которые работают на уровне IRQL = PASSIVE_LEVEL. Например, подпрограмма DPC может ставить рабочий элемент в очередь для запуска в системном рабочем потоке.
Подпрограммы DPC, вызывающие процедуру KeStallExecutionProcessor для задержки выполнения, не должны указывать задержки более 100 микросекунд.
Используйте средства анализа производительности в WDK для оценки времени выполнения подпрограмм DPC. Пример, использующий средство Tracelog для отслеживания времени выполнения DPC, см. в примере 15. Измерение времени DPC/ISR.
Если драйвер использует DMA и его процедура AdapterControl возвращает KeepObject или DeallocateObjectKeepRegisters (тем самым сохраняя канал системного контроллера DMA или адаптер шины для дополнительных операций передачи), процедура DpcForIsr или CustomDpc отвечает за освобождение объекта адаптера или регистров карты с помощью FreeAdapterChannel или FreeMapRegisters перед завершением выполнения текущего IRP и возвратом управления.
Если драйвер физического устройства низкого уровня настраивает объект контроллера для синхронизации операций ввода-вывода с помощью контроллера с подключенными устройствами, его подпрограмма DpcForIsr или CustomDpc отвечает за освобождение объекта контроллера с помощью IoFreeController , прежде чем завершить текущий IRP и возвратить элемент управления.
Подпрограммы DpcForIsr и CustomDpc обычно отвечают за ведение журнала ошибок устройств, возникших во время обработки данного запроса, повторения текущего запроса при необходимости и возможности, а также для настройки блока состояния ввода-вывода и вызова IoCompleteRequest для текущего IRP.
Если драйвер и устройство поддерживают перекрывающиеся операции ввода-вывода, драйвер должен следовать правилам обработки перекрывающихся операций ввода-вывода.
Подпрограмма DpcForIsr или CustomDpc любого драйвера обычно завершает обработку ввода-вывода только для подмножества открытых кодов управления ввода-вывода, которые драйвер должен поддерживать. В частности, подпрограмма DPC выполняет операции для запросов управления устройствами со следующими характеристиками:
Запросы, изменяющие состояние физического устройства
Запросы, требующие возврата по сути переменных сведений о физическом устройстве