Это трудно. ;)
Нет, правда.
IRQL означает «Уровень запроса прерывания». Это число от 0 до 31 в системах Windows x86 и от 0 до 15 в системах x64. Он представляет «важность» задачи режима ядра относительно других задач режима ядра.
IRQL - это определенное в Windows состояние процессора, а не процесса или потока, которое указывает Windows, может ли то, что делает этот процессор, быть прервано другими задачами. Если новая задача (например, подпрограмма обработки прерываний) имеет более высокий IRQL, чем текущий IRQL процессора, то да, она может прервать текущую задачу; в противном случае нет. В многопроцессорной системе каждый процессор имеет свой собственный IRQL. Это включает в себя «логические процессоры», созданные с помощью гиперпоточности.
(Я использую слово «важность», а не «приоритет», потому что «приоритет» в Windows относится к приоритетам потоков, а IRQL - это нечто иное. В отличие от приоритетов потоков, задачи ядра в том же IRQL не разделены по времени, и IRQL не являются ' подвержены автоматическому увеличению и затуханию.)
(Следует также упомянуть, что термин «задача ядра» здесь не является официальным. Windows на самом деле не называет эти вещи «задачами ядра», они не являются управляемыми объектами, как, например, процессы и потоки, и не имеют отношения к задаче x86 » "ни к чему не показывается в" Диспетчере задач ". Поскольку я (и другие) использую здесь термин," задача режима ядра "действительно охватывает" все с определенным началом и концом, что необходимо сделать в режиме ядра на IRQL 2 или выше. "Подпрограмма обслуживания прерываний является одним примером" задачи режима ядра "; как и подпрограмма DPC. Но другим примером может быть код в потоке режима ядра. Такие потоки начинаются с IRQL 0, но если являются частью кода повышениядля IRQL 2 или выше, что-то делает, а затем возвращается к своему предыдущему IRQL, часть кода с высоким IRQL является одним из примеров того, что я называю здесь «задачей ядра». )
Системный монитор отображает время, потраченное на IRQL 2 как «% DPC time», а время при IRQL> 2 как «% interrupt time», независимо от того, было ли время фактически потрачено на процедуру DPC или ISR или было результатом повышения IRQL из более низкое значение. Каждый из них представляет собой подмножество того, что PerfMon показывает как «% привилегированное время», которое должно быть помечено как «время режима ядра».
Как только задача ядра запускается на IRQL 2 или выше, она выполняется до завершения, прежде чем что-либо еще на том же IRQL будет запущено на том же процессоре. Она может быть прервана задачей с более высоким IRQL (которая, в свою очередь, может быть прервана задачей с более высоким IRQL и т. Д.), Но когда задачи с более высоким IRQL завершены, управление возвращается к задаче, которую оно прервало.
IRQL - это прежде всего механизм сериализации . (Многие говорят «синхронизация», но я предпочитаю это слово, так как оно более точно описывает результат.) Его цель - помочь гарантировать, что несколько задач на одном процессоре, которые обращаются к определенным общим ресурсам - в основном, к общим структурам данных в пространстве ядра ОС - не разрешается прерывать друг друга таким образом, чтобы это могло повредить эти структуры.
Например, большое количество данных в ядре Windows, в частности данные управления памятью и данные, используемые планировщиком потоков, «сериализуются» на IRQL 2. Это означает, что любая задача, которая хочет изменить такие данные, должна выполняться на IRQL 2, когда это так. Если задача с более высоким IRQL пытается записать такие данные, это может привести к повреждению, поскольку оно могло прервать задачу IRQL 2, которая может находиться в середине цикла чтения-изменения-записи для этих же данных. Так что задачам с более высоким IRQL просто не разрешено это делать.
Задачи с более высоким IRQL - это в основном подпрограммы обслуживания прерываний драйверов устройств, поскольку прерывания всех устройств происходят при IRQL> 2. Это включает прерывание от микросхемы таймера на материнской плате, которая управляет хронометражем и управляемой временем активностью в ОС. Его IRQL выше, чем у всех «обычных» аппаратных устройств.
IRQL 2 и выше используются для задач ядра, которые не запускаются аппаратными прерываниями, но при которых обычное планирование потоков, включая ожидание, не может быть выполнено. Таким образом, если процессор находится на уровне IRQL 2 или выше, переключение контекста потока на этом процессоре не может произойти, пока IRQL не опустится ниже 2.
Код режима пользователя всегда равен IRQL 0. Код режима ядра может работать на любом уровне IRQL от 0 до максимального значения. IRQL 1 - это особый случай; это только режим ядра, но он не влияет на планирование и в действительности является скорее состоянием потока, чем процессора - он сохраняется и восстанавливается, например, при переключении контекста потока.
Чтобы поддерживать различные гарантии сериализации, большинство исключений (такие как деление на ноль или нарушения доступа к памяти, такие как сбои страниц) просто не могут обрабатываться на IRQL 2 или выше. (Кстати, IRQL 2 обычно называют «уровнем диспетчеризации» или «уровнем DPC».)
И теперь мы можем наконец объяснить этот код проверки на ошибки!
Наиболее распространенный случай IRQL_NOT_LESS_OR_EQUAL связан с ошибкой страницы (попытка доступа к «нерезидентному» виртуальному адресу) или нарушением доступа к памяти (попытка записи на страницу только для чтения или на страницу, которая не определена). вообще), что происходит на IRQL 2 или выше.
Если такие исключения возникают при IRQL 0 или 1, они могут быть «обработаны» либо системным кодом (например, обработчиком ошибок страницы), либо обработчиком исключений, предоставленным разработчиком. Однако большинство исключений не могут быть обработаны вообще, если они произошли в IRQL 2 или выше.
Итак ... код проверки на ошибки означает «исключение типа, которое может быть обработано только при IRQL 0 или 1, когда IRQL был на уровне 2 или выше». то есть "не меньше или равно 1". Странная формулировка, но она есть.
Есть несколько других вещей, которые могут вызвать эту проверку на ошибки, и значение, которое IRQL не меньше или равно, не всегда равно 1, но они встречаются очень редко. Документация WinDBG перечисляет их.