Поделиться через


Ограничения на страничные коды в драйверах хранилища

Чтобы предотвратить взаимоблокировку, ни одна часть драйвера хранилища, которая используется для обслуживания запросов на чтение или запись, не должна иметь страничного кода и не должна пытаться получить доступ к доступной для страницы памяти. Это связано с тем, что подпрограммы DispatchRead и DispatchWrite драйвера могут вызываться в IRQL > PASSIVE_LEVEL, а операции ввода-вывода с разбиением по страницам, которые обслуживали ошибку страницы, происходят в IRQL = APC_LEVEL.

Аналогичные правила применяются к подпрограмме диспетчера управления устройством драйвера хранилища DispatchDeviceControl с определенными квалификациями. Подпрограмма диспетчеризации управления устройствами драйвера хранилища не должна содержать страничный код или доступ к странице памяти. Подпрограмма диспетчеризации должна иметь возможность получать запросы IOCTL, предназначенные для других драйверов, в произвольных списках IRQL, и передавать их в стек драйверов. Драйверы должны передавать все необработаенные запросы IOCTL в стеке без изменения IRQL или контекста запроса.

Однако корпорация Майкрософт требует, чтобы все запросы IOCTL хранилища отправлялись в PASSIVE_LEVEL, поэтому, хотя подпрограмма отправки сама по себе не поддерживает страницы, она может вызывать страничные подпрограммы для обработки запросов IOCTL хранилища. Эти подпрограммы также могут обращаться к страничной памяти.

Подпрограммы, такие как DriverEntry, Повторная инициализация и Выгрузка, которые не выполняют ввода-вывода и выполняются в IRQL = PASSIVE_LEVEL также могут иметь страничный код.

Особые рекомендации применяются к драйверам, которые управляют запоминающими устройствами в пути разбиения по страницам. Драйвер находится в "пути подкачки", если он участвует в операциях ввода-вывода в файле подкачки. Если драйвер хранилища находится в пути разбиения по страницам, его подпрограмма DispatchPower для IRP_MJ_POWER запросов не должна быть доступной для страниц.

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