Utilisation de la pile du noyau

La taille de la pile en mode noyau est limitée à environ trois pages. Par conséquent, lors de la transmission de données à des routines internes, les pilotes ne peuvent pas transmettre de grandes quantités de données sur la pile du noyau.

Pour éviter de manquer d’espace de pile en mode noyau, suivez les instructions de conception suivantes :

  • Évitez d’effectuer des appels profondément imbriqués d’une routine de pilote interne à une autre, si chaque routine transmet des données sur la pile du noyau.

  • Veillez à limiter le nombre d’appels récursifs qui peuvent se produire si vous concevez un pilote qui a une routine récursive.

En d’autres termes, la structure de l’arborescence des appels d’un pilote doit être relativement plate. Vous pouvez appeler les routines IoGetStackLimits et IoGetRemainingStackSize pour déterminer l’espace de pile du noyau disponible, ou KeExpandKernelStackAndCallout pour le développer. Notez que la taille de la pile en mode noyau peut varier selon les plateformes matérielles et les différentes versions du système d’exploitation.

L’épuisement de l’espace de pile du noyau entraîne une erreur système irrécupérable. Par conséquent, il est préférable pour un pilote d’allouer de la mémoire de l’espace système plutôt que de manquer d’espace de pile du noyau. Toutefois, le pool non paginé est également une ressource système limitée.

En règle générale, la pile en mode noyau réside dans la mémoire, mais elle peut parfois être paginée si le thread entre dans un état d’attente qui spécifie le mode utilisateur. Pour plus d’informations sur la désactivation temporaire de la pagination de la pile du noyau pour le thread actif, consultez KeSetKernelStackSwapEnable . Pour des raisons de performances, il n’est pas recommandé de désactiver globalement la pagination de la pile du noyau, mais si vous le souhaitez pendant une session de débogage, consultez Désactiver la pagination des piles de noyau

Étant donné que la pile du noyau peut être désintégrée, soyez prudent quand vous passez des mémoires tampons basées sur la pile (c’est-à-dire des variables locales) à DMA ou à toute routine qui s’exécute à DISPATCH_LEVEL ou au-dessus.