¿Qué es exactamente IRQL_NOT_LESS_OR_EQUAL? ¿Qué es IRQL? ¿Qué cosas usan IRQL? ¿Por qué tiene que ser menor o igual? ¿Qué causaría que no fuera menor o igual? ¿Por qué el sistema operativo no puede recuperarse si no es menor o igual? ¿IRQL sólo afecta a Windows?
Este error parece sermuy común. No pido ayuda, pido una explicación.
Respuesta1
Es complicado. ;)
No, de verdad, lo es.
IRQL significa "Nivel de solicitud de interrupción". Es un número que va del 0 al 31 en sistemas Windows x86 y del 0 al 15 en sistemas x64. Representa la "importancia" de una tarea en modo kernel en relación con otras tareas en modo kernel.
IRQL es un estado del procesador definido por Windows, no de un proceso o subproceso, que indica a Windows si lo que esté haciendo ese procesador puede ser interrumpido por otras tareas. Si una nueva tarea (como una rutina de servicio de interrupción) tiene un IRQL más alto que el IRQL actual del procesador, entonces sí, puede interrumpir la tarea actual; De otra manera no. En un sistema multiprocesador cada procesador tiene su propio IRQL. Esto incluye los "Procesadores lógicos" creados mediante hyperthreading.
(Utilizo la palabra "importancia" en lugar de "prioridad" porque "prioridad" en Windows se refiere a las prioridades de los subprocesos y los IRQL son algo diferente. A diferencia de las prioridades de los subprocesos, las tareas del núcleo en el mismo IRQL no están divididas en tiempo y los IRQL no t sujeto a realce y caída automáticos).
(También debo mencionar que el término "tarea del núcleo" aquí no es oficial. Windows realmente no llama a estas cosas "tareas del núcleo", no son objetos administrados como lo son, por ejemplo, procesos y subprocesos, y no hay ninguna relación con la "tarea x86". puertas" ni a nada que se muestra en el "Administrador de tareas". Como yo (y otros) usamos el término aquí, "tarea en modo kernel" realmente cubre "cualquier cosa con un principio y un final definidos que deba realizarse en modo kernel en IRQL 2 o arriba". Una rutina de servicio de interrupción es un ejemplo de una "tarea en modo kernel"; también lo es una rutina DPC. Pero otro ejemplo puede ser código en un subproceso en modo kernel. Dichos subprocesos comienzan en IRQL 0, pero si son parte del códigoelevaa IRQL 2 o superior, hace algo y luego regresa a su IRQL anterior, la parte del código con alto IRQL es un ejemplo de lo que aquí llamo una "tarea del núcleo". )
Performance Monitor muestra el tiempo invertido en IRQL 2 como "% de tiempo DPC" y el tiempo en IRQL > 2 como "% de tiempo de interrupción", independientemente de si el tiempo realmente se dedicó a una rutina DPC o ISR o fue el resultado de elevar IRQL desde un valor más bajo. Cada uno es un subconjunto de lo que PerfMon muestra como "% de tiempo privilegiado", que debería haberse etiquetado como "tiempo en modo kernel".
Una vez que se inicia una tarea del kernel en IRQL 2 o superior, se ejecuta hasta su finalización antes que cualquier otra cosa en elmismoIRQL se iniciará en el mismo procesador. Puede ser interrumpida por una tarea con IRQL superior (que a su vez podría ser interrumpida por una tarea con IRQL aún mayor, etc.), pero cuando se completan las tareas con IRQL superior, el control vuelve a la tarea que interrumpió.
IRQL es principalmente unpublicación por entregasmecanismo. (Muchos dicen "sincronización", pero prefiero esta palabra porque describe más exactamente el resultado). Su propósito es ayudar a garantizar que múltiples tareas en la misma CPU que acceden a ciertos recursos compartidos (en su mayoría estructuras de datos compartidas en el espacio del kernel del sistema operativo) No se les permite interrumpirse entre sí de manera que puedan corromper esas estructuras.
Por ejemplo, una gran cantidad de datos en el kernel de Windows, particularmente los datos de administración de memoria y los datos utilizados por el programador de subprocesos, son"serializado"en IRQL 2. Eso significa que cualquier tarea que quiera modificar dichos datos debe estar ejecutándose en IRQL 2 cuando lo haga. Si una tarea con un IRQL superior intenta escribir dichos datos, eso podría causar corrupción, porque podría haber interrumpido una tarea IRQL 2 que podría estar en medio de un ciclo de lectura, modificación y escritura en esos mismos datos. Por lo tanto, las tareas con IRQL superior simplemente no pueden hacer eso.
Las tareas con IRQL superior son en su mayoría rutinas de servicio de interrupción de los controladores de dispositivos, porque las interrupciones de todos los dispositivos ocurren en IRQL > 2. Esto incluye la interrupción del chip temporizador en la placa base que controla el cronometraje y la actividad controlada por el tiempo en el sistema operativo. Su IRQL está por encima del de todos los dispositivos de hardware "ordinarios".
Los IRQL 2 y superiores se utilizan para tareas del kernel que no se activan mediante interrupciones de hardware pero durante las cuales no se puede realizar la programación normal de subprocesos, incluida la espera. Por lo tanto, una vez que un procesador está en IRQL 2 o superior, no pueden ocurrir cambios de contexto de subproceso en ese procesador hasta que IRQL caiga por debajo de 2.
El código del modo de usuario siempre está en IRQL 0. El código del modo kernel puede ejecutarse en cualquier IRQL desde 0 hasta el máximo. IRQL 1 es un caso especial; es solo el modo kernel, pero no tiene impacto en la programación, y en realidad es más un estado de un subproceso que del procesador; se guarda y restaura durante los cambios de contexto del subproceso, por ejemplo.
Para mantener varias garantías de serialización, la mayoría de las excepciones (cosas como división por cero o violaciones de acceso a la memoria como fallas de página) simplemente no se pueden manejar en IRQL 2 o superior. (Por cierto, IRQL 2 se denomina comúnmente "nivel de envío" o "nivel DPC").
¡Y ahora finalmente podemos explicar este código de verificación de errores!
El caso más común de IRQL_NOT_LESS_OR_EQUAL se debe a un error de página (intento de acceder a una dirección virtual "no residente") o una violación de acceso a la memoria (intento de escribir en una página de solo lectura o de acceder a una página que no está definida en absoluto), que ocurre en IRQL 2 o superior.
Si dichas excepciones se generan en IRQL 0 o 1, se pueden "manejar" mediante el código proporcionado por el sistema (como el controlador de fallas de página) o mediante un controlador de excepciones proporcionado por el desarrollador. Sin embargo, la mayoría de las excepciones no se pueden manejar en absoluto si ocurrieron en IRQL 2 o superior.
Entonces... el código de verificación de errores significa "una excepción de un tipo que sólo puede manejarse en IRQL 0 o 1 ocurrió cuando IRQL estaba en 2 o superior". es decir, "no menor o igual a 1". Extraña redacción, pero ahí está.
Hay algunas otras cosas que pueden desencadenar esta verificación de errores, y el valor al que IRQL no es menor o igual no siempre es 1, pero ocurren solo en raras ocasiones. La documentación de WinDBG los enumera.