Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
IRQL di mana suatu rutinitas driver dijalankan menentukan rutinitas pendukung driver mode kernel mana yang dapat dipanggilnya. Misalnya, beberapa rutinitas dukungan driver mengharuskan pemanggil berjalan di IRQL = DISPATCH_LEVEL. Yang lain tidak dapat dipanggil dengan aman jika penelepon berjalan di IRQL apa pun yang lebih tinggi dari PASSIVE_LEVEL.
Berikut ini adalah daftar IRQL di mana rutinitas driver standar yang paling umum diimplementasikan dipanggil. IRQL tercantum dari prioritas terendah hingga tertinggi.
PASSIVE_LEVEL
Interrupt Dimatikan - Tidak ada.
Rutinitas Driver Dipanggil pada PASSIVE_LEVEL - DriverEntry, AddDevice, Reinitialize, Unload rutinitas, sebagian besar rutinitas dispatch, thread yang dibuat oleh driver, callback thread pekerja.
APC_LEVEL
Interupsi Dimatikan - Interupsi APC_LEVEL dimatikan.
Rutinitas Driver Dipanggil pada APC_LEVEL - Beberapa rutinitas pengiriman (lihat Dispatch Routines dan IRQL).
DISPATCH_LEVEL
Gangguan Ditutup - gangguan DISPATCH_LEVEL dan APC_LEVEL terblokir. Gangguan perangkat, jam, dan daya dapat terjadi.
Rutinitas Driver Dipanggil pada DISPATCH_LEVEL - StartIo, AdapterControl, AdapterListControl, ControllerControl, IoTimer, Cancel (sambil menahan kunci spin pembatalan), DpcForIsr, CustomTimerDpc, CustomDpc rutinitas.
DIRQL
Interupsi Ditutupi - Semua interupsi pada IRQL <= DIRQL dari objek interupsi pengemudi. Gangguan perangkat dengan nilai DIRQL yang lebih tinggi dapat terjadi, bersama dengan jam dan gangguan kegagalan daya.
Rutinitas Driver Dipanggil di DIRQL - Rutinitas InterruptService, SynchCritSection .
Satu-satunya perbedaan antara APC_LEVEL dan PASSIVE_LEVEL adalah bahwa proses yang dijalankan pada APC_LEVEL tidak bisa mendapatkan gangguan APC. Tetapi kedua IRQL menyiratkan konteks utas dan keduanya menyiratkan bahwa kode dapat dipindahkan ke halaman.
Pengendali tingkat terendah memproses IRPs saat berjalan di salah satu dari tiga IRQL.
PASSIVE_LEVEL, tanpa gangguan ditutupi pada prosesor, dalam rutinitas Pengiriman pengemudi
Rutinitas DriverEntry, AddDevice, Reinitialize, dan Unload juga dijalankan pada PASSIVE_LEVEL, seperti halnya utas sistem yang dibuat driver.
DISPATCH_LEVEL, dengan interupsi DISPATCH_LEVEL dan APC_LEVEL diblokir di prosesor, dalam rutinitas StartIo
AdapterControl, AdapterListControl, ControllerControl, IoTimer, Cancel (saat memegang kunci spin pembatalan), dan rutinitas CustomTimerDpc juga dijalankan pada DISPATCH_LEVEL, seperti halnya rutinitas DpcForIsr dan CustomDpc .
IRQL Perangkat (DIRQL), dengan semua gangguan kurang dari atau sama dengan SynchronizeIrql objek interupsi driver yang ditutupi pada prosesor, dalam rutinitas ISR dan SynchCritSection
Sebagian besar driver tingkat lebih tinggi memproses IRP saat berjalan di salah satu dari dua IRQL:
PASSIVE_LEVEL, tanpa interupsi yang tidak aktif di prosesor, dalam rutinitas dispatch pengemudi
Rutinitas DriverEntry, Reinitialize, AddDevice, dan Unload juga dijalankan pada PASSIVE_LEVEL, seperti halnya rangkaian sistem yang dibuat driver atau rutinitas panggilan balik alur kerja atau driver sistem file.
DISPATCH_LEVEL, dengan interupsi DISPATCH_LEVEL dan APC_LEVEL dimatikan pada prosesor, dalam rutinitas IoCompletion driver
Rutinitas IoTimer, Cancel, dan CustomTimerDpc juga dijalankan pada DISPATCH_LEVEL.
Dalam beberapa keadaan, driver tingkat menengah dan terendah dari perangkat penyimpanan massal dipanggil di IRQL APC_LEVEL. Secara khusus, ini dapat terjadi pada kesalahan halaman di mana driver sistem file mengirim permintaan IRP_MJ_READ ke driver yang lebih rendah.
Sebagian besar rutinitas driver standar dijalankan pada IRQL yang memungkinkan mereka hanya untuk memanggil rutinitas dukungan yang sesuai. Misalnya, driver perangkat harus memanggil AllocateAdapterChannel saat berjalan di IRQL DISPATCH_LEVEL. Karena sebagian besar driver perangkat memanggil rutinitas ini dari rutinitas StartIo, biasanya mereka sudah beroperasi pada DISPATCH_LEVEL.
Driver perangkat yang tidak memiliki rutinitas StartIo karena mengatur dan mengelola antrean IRP-nya sendiri tidak selalu berjalan di DISPATCH_LEVEL IRQL ketika harus memanggil AllocateAdapterChannel. Driver seperti itu harus menempatkan panggilannya ke AllocateAdapterChannel di antara panggilan ke KeRaiseIrql dan KeLowerIrql sehingga berjalan pada IRQL yang diperlukan ketika memanggil AllocateAdapterChannel dan mengembalikan IRQL asli ketika rutin panggilan mendapatkan kembali kontrol.
Saat memanggil rutinitas dukungan driver, waspadai hal berikut.
Memanggil KeRaiseIrql dengan nilai input NewIrql yang kurang dari IRQL saat ini menyebabkan kesalahan fatal. Memanggil KeLowerIrql kecuali untuk memulihkan IRQL asli (yaitu, setelah panggilan ke KeRaiseIrql) juga menyebabkan kesalahan fatal.
Saat berjalan di IRQL >= DISPATCH_LEVEL, memanggil KeWaitForSingleObject atau KeWaitForMultipleObjects untuk objek dispatcher yang ditentukan kernel untuk menunggu interval nonzero menyebabkan kesalahan fatal.
Satu-satunya rutinitas pengemudi yang dapat dengan aman menunggu peristiwa, semaphores, mutex, atau timer yang akan diatur ke status sinyal adalah yang berjalan dalam konteks utas nonarbitrer di IRQL PASSIVE_LEVEL, seperti utas yang dibuat driver, DriverEntry dan Menginisialisasi ulang rutinitas, atau mengirimkan rutinitas untuk operasi I/O yang secara inheren sinkron (seperti sebagian besar permintaan kontrol I/O perangkat).
Bahkan saat berjalan di IRQL PASSIVE_LEVEL, kode driver yang dapat dipindahkan ke halaman tidak boleh memanggil KeSetEvent, KeReleaseSemaphore, atau KeReleaseMutex dengan parameter Wait input diatur ke TRUE. Panggilan seperti itu dapat menyebabkan kesalahan fatal pada halaman.
Rutinitas apa pun yang beroperasi pada tingkat lebih tinggi dari IRQL APC_LEVEL tidak dapat mengalokasikan memori dari paged pool atau mengakses memori di paged pool dengan aman. Jika rutinitas yang berjalan di IRQL lebih besar dari APC_LEVEL menyebabkan kesalahan halaman, maka itu merupakan kesalahan fatal.
Driver harus berjalan di IRQL DISPATCH_LEVEL ketika memanggil KeAcquireSpinLockAtDpcLevel dan KeReleaseSpinLockFromDpcLevel.
Driver dapat berjalan di IRQL <= DISPATCH_LEVEL ketika memanggil KeAcquireSpinLock tetapi harus melepaskan kunci spin tersebut dengan memanggil KeReleaseSpinLock. Dengan kata lain, ini adalah kesalahan pemrograman untuk melepaskan kunci putaran yang diperoleh dengan KeAcquireSpinLock dengan memanggil KeReleaseSpinLockFromDpcLevel.
Driver tidak boleh memanggil KeAcquireSpinLockAtDpcLevel, KeReleaseSpinLockFromDpcLevel, KeAcquireSpinLock, atau KeReleaseSpinLock saat berjalan di IRQL > DISPATCH_LEVEL.
Memanggil rutinitas dukungan yang menggunakan spinlock, seperti rutinitas ExInterlockedXxx meningkatkan IRQL pada prosesor saat ini menjadi DISPATCH_LEVEL atau DIRQL jika pemanggil belum berjalan pada IRQL yang dinaikkan.
Kode driver yang berjalan di IRQL > PASSIVE_LEVEL harus dijalankan secepat mungkin. Semakin tinggi IRQL tempat rutinitas berjalan, semakin penting untuk performa keseluruhan menjadi baik dengan menyetel rutinitas agar dijalankan secepat mungkin. Misalnya, setiap driver yang memanggil KeRaiseIrql harus melakukan panggilan timbal balik ke KeLowerIrql sesegera mungkin.
Untuk informasi selengkapnya tentang menentukan prioritas, lihat makalah putih Penjadwalan, Konteks Utas, dan IRQL.