Evitar errores y interbloqueos al usar bloqueos de número

Aunque una rutina de controlador contiene un bloqueo de número, no puede provocar una excepción de hardware ni generar una excepción de software sin bajar el sistema. En otras palabras, el ISR de un controlador y cualquier rutina SynchCritSection que el controlador proporciona en una llamada a KeSynchronizeExecution no debe provocar un error o captura, como un error de página o una excepción aritmética, y no puede generar una excepción de software. Una rutina que llama a KeAcquireSpinLock o KeAcquireInStackQueuedSpinLock tampoco puede provocar una excepción de hardware ni generar una excepción de software hasta que haya liberado su bloqueo de giro ejecutivo y ya no se ejecute en IRQL = DISPATCH_LEVEL.

Rutinas de soporte técnico y datos paginables

Al mantener un bloqueo de número, los controladores no deben llamar a rutinas que tengan acceso a datos paginables. Recuerde que los controladores pueden llamar a ciertas rutinas de soporte técnico que acceden a datos paginables si y solo si se producen sus llamadas mientras se ejecutan en un IRQL estrictamente menor que DISPATCH_LEVEL. Esta restricción IRQL impide llamar a estas rutinas de soporte mientras mantiene un bloqueo de número. Para conocer los requisitos de IRQL para cualquier rutina de soporte técnico específica, consulte la página de referencia de la rutina.

Recursividad

Se garantiza que al intentar adquirir un bloqueo de número recursiva se produce un interbloqueo: la creación de instancias de una rutina recursiva no puede liberar el bloqueo de número mientras una segunda creación de instancias gira, intentando adquirir el mismo bloqueo de giro.

Las instrucciones siguientes describen cómo usar bloqueos de número con rutinas recursivas:

  • La rutina recursiva no debe llamarse a sí misma mientras mantiene un bloqueo de giro o no debe intentar adquirir el mismo bloqueo de giro en las llamadas posteriores.

  • Aunque la rutina recursiva contiene un bloqueo de número, otra rutina del controlador no debe llamar a la rutina recursiva si la recursividad puede provocar un interbloqueo o podría hacer que el autor de la llamada mantenga el bloqueo de giro durante más de 25 microsegundos.

Para obtener más información sobre las rutinas de controladores recursivos, consulte Uso de la pila de kernels.

Adquisiciones de bloqueos de número anidados

Intentar adquirir un segundo bloqueo de giro mientras mantiene otro bloqueo de giro también puede provocar interbloqueos o un rendimiento deficiente del controlador.

Las instrucciones siguientes describen cómo los controladores deben contener bloqueos de giro:

  • El controlador no debe llamar a una rutina de soporte técnico que use un bloqueo de giro a menos que no se pueda producir un interbloqueo.

  • Incluso si no se puede producir un interbloqueo, el controlador no debe llamar a una rutina de soporte técnico que use un bloqueo de giro a menos que las técnicas de codificación alternativas no puedan proporcionar un rendimiento y una funcionalidad de controlador comparables.

  • Si un controlador realiza llamadas anidadas para adquirir bloqueos de número, siempre debe adquirir los bloqueos de giro en el mismo orden cada vez que se adquieren. Este orden ayuda a evitar interbloqueos.

En general, evite usar bloqueos de número anidados para proteger subconjuntos superpuestos o conjuntos discretos de datos y recursos compartidos. Tenga en cuenta lo que puede ocurrir si un controlador usa dos bloqueos de giro ejecutivos para proteger recursos discretos, como un par de objetos de temporizador que podrían establecerse individualmente y colectivamente por varias rutinas de conductor. El controlador interbloqueo interbloqueo intermitentemente en una máquina SMP, cada una de las dos rutinas, cada una de las cuales mantiene un bloqueo de giro, intentó adquirir el otro bloqueo de giro.

Para obtener más información sobre cómo adquirir bloqueos de número anidados, vea Bloqueos, interbloqueos y sincronización.