隔离可分页代码
不能对使用旋转锁的例程进行分页。 但是,在某些情况下,可以在单独的例程中隔离需要旋转锁的操作,该例程不会包含在可分页节中。
例如,请考虑以下片段:
// PAGED_CODE();
KeInitializeEvent( &event, NotificationEvent, FALSE );
irp = IoBuildDeviceIoControlRequest( IRP_MJ_DEVICE_CONTROL,
DeviceObject,
(PVOID) NULL,
0,
(PVOID) NULL,
0,
FALSE,
&event,
&ioStatus );
if (irp) {
irpSp = IoGetNextIrpStackLocation( irp );
irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
irpSp->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM;
status = IoCallDriver( DeviceObject, irp );
if (status == STATUS_PENDING) {
(VOID) KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
(PLARGE_INTEGER) NULL );
}
}
SPINLOCKUSE !
KeAcquireSpinLock( &IopDatabaseLock, &irql );
// Code inside spin lock ...
DeviceObject->ReferenceCount--;
if (!DeviceObject->ReferenceCount && !DeviceObject->AttachedDevice) {
//Unload the driver
.
.
.
} else {
KeReleaseSpinLock( &IopDatabaseLock, irql );
}
(将引用旋转锁的几行代码移动到单独的例程中,) 节省大约 160 个字节,就可以使上述例程变得可分页。
此外,请记住,如果驱动程序代码调用任何 KeXxx 支持例程(如 KeReleaseMutex 或 KeReleaseSemaphore),其中 Wait 参数设置为 TRUE,则不得将其标记为可分页。 此类调用在 DISPATCH_LEVEL 返回 IRQL。