Hey,
For some reason, My driver is full of calls to “__alloca_probe” / “_chkstk”. We saw these calls during performance profiling and I think they are completely useless in kernel mode. This is my logic and I want to make sure I’m correct:
- The chkstk function is only useful for the case where stack pages are paged out and they are paged in as the thread stack grows (The PAGE_GUARD thing in user mode). It exist in order to make sure that the thread will not skip a page (because of large buffer allocations) and crash with an access violation.
- The only case where kernel thread stacks are paged out is when the kernel thread enters a “UserMode” wait (+ some limitations apply such as the thread priority level)
- When a thread runs code in kernel mode (After the context switch is finished) the kernel stack of this thread must be entirely paged in. This is because:
- The kernel cannot handle page faults in DISPATCH_LEVEL. A thread may acquire a spinlock and continue reading from the stack, So the stack must be in memory.
- A kernel thread may enter a filesystem stack context and trying to page in the kernel stack can cause deadlocks.
- The conclusion: Enabling the stack checking compiler flag is completely useless. This compiler option is only relevant for user mode code. I can safely remove the chkstk calls from my driver.
- In case more stack space is needed for some reason (Invoking functions deep down in the I/O stack that may overflow the stack) it’s possible to use KeExpandKernelStackAndCalloutEx.
My questions:
- Can someone confirm these statements?
- If a “UserMode” wait can trigger a page fault as a result thread stack paging, Is it unsafe to perform a ‘UserMode’ wait inside a FileSystem stack? Or the OS checks whether FsRtlEnterFileSystem was invoked before paging out the thread’s stack?
Thank you!