Menyiapkan dan Menggunakan Antrean Yang Saling Diblokir
Driver baru harus menggunakan kerangka kerja antrean IRP batal aman di preferensi metode yang diuraikan di bagian ini.
Driver dengan utas atau driver khusus perangkat yang menggunakan utas pekerja eksekutif, seperti sebagian besar FSD sistem, adalah jenis driver yang paling mungkin untuk mengelola antrean internal run-time IRP mereka sendiri dalam antrean yang saling diblokir. Semua driver PnP, termasuk driver WDM, juga harus mengantre runtime integrasi tertentu secara internal sambil melakukan transisi PnP dan status daya.
Biasanya, driver ini menyiapkan antrean yang saling terhubung dua arah; setiap IRP berisi anggota jenis LIST_ENTRY, yang dapat digunakan driver untuk menautkan IRP dua kali lipat yang saat ini disimpan. Driver tidak dapat mengantre ulang IRP untuk mencoba kembali jika menyiapkan antrean yang ditautkan secara senyap.
Driver harus mengatur antrean yang saling diblokir pada inisialisasi perangkat. Gambar berikut mengilustrasikan antrean yang saling terhubung dua kali lipat, rutinitas dukungan yang harus dipanggil driver untuk mengatur antrean seperti itu, dan satu set rutinitas ExInterlockedXxx yang dapat dipanggil driver untuk memasukkan RUNPS ke dalam dan menghapus RUNPS dari antrean.
Seperti yang ditunjukkan oleh gambar ini, driver harus menyediakan penyimpanan untuk antrean itu sendiri dan untuk yang berikut ini untuk menyiapkan antrean yang saling terhubung dua kali lipat:
Kunci spin eksekutif, yang harus dipanggil keInitializeSpinLock untuk menginisialisasi . Biasanya, driver menginisialisasi kunci putar ketika mengatur ekstensi perangkat untuk objek perangkatnya dalam rutinitas AddDevice-nya .
Kepala daftar untuk antrean, yang harus diinisialisasi driver dengan memanggil InitializeListHead.
Sebagian besar driver yang menggunakan antrean yang saling ditautkan ganda menyediakan penyimpanan yang diperlukan dalam ekstensi perangkat objek perangkat yang dibuat driver. Antrean dan kunci putar eksekutif dapat berada di ekstensi pengontrol (jika driver menggunakan objek pengontrol) atau di kumpulan yang tidak di-patahkan yang dialokasikan oleh driver.
Saat driver menerima permintaan I/O, driver dapat memasukkan IRP ke dalam antreannya dengan memanggil salah satu rutinitas dukungan berikut jika ListHead berjenis LIST_ENTRY, seperti yang ditunjukkan pada gambar sebelumnya:
ExInterlockedInsertTailList untuk menempatkan IRP di akhir antrean
ExInterlockedInsertHeadList untuk menempatkan IRP di bagian depan antrean. Driver biasanya memanggil rutinitas ini hanya ketika mereka harus mencoba kembali permintaan tertentu.
Driver harus meneruskan pointer ke IRP (ListEntry), serta penunjuk ListHead dan kunci putar eksekutif (Lock) yang sebelumnya diinisialisasi, ke masing-masing rutinitas Daftar ExInterlockedInsertXxx ini. Hanya penunjuk ke ListHead dan Lock yang diperlukan ketika driver menghapus antrean IRP dengan memanggil ExInterlockedRemoveHeadList. Untuk mencegah kebuntuan, pengemudi tidak boleh memegang ExecutiveSpinLock yang diteruskan ke rutinitas Xxx ExInterlocked.
Karena antrean yang saling terhubung dilindungi oleh kunci putaran eksekutif, pengemudi dapat memasukkan RUNPS ke dalam antrean yang dua kali ditautkan dan menghapusnya dengan cara yang aman multiprosesor dari rutinitas driver apa pun yang berjalan pada kurang dari atau sama dengan IRQL = DISPATCH_LEVEL.
Antrean dengan ListHead jenis LIST_ENTRY, seperti yang ditunjukkan pada gambar sebelumnya, adalah daftar dua kali lipat yang ditautkan. Satu dengan ListHead jenis SLIST_HEADER adalah daftar yang ditautkan secara berurutan. Driver menginisialisasi ListHead untuk antrean tertaut yang ditautkan secara berurutan dengan memanggil ExInitializeSListHead.
Driver yang tidak pernah mencoba kembali operasi I/O dapat menggunakan ExInterlockedPushEntrySList dan ExInterlockedPopEntrySList untuk mengelola antrean IRP secara internal dalam antrean yang ditautkan secara berurutan dan saling ditautkan. Setiap driver yang menggunakan jenis antrean yang saling diblokir ini juga harus menyediakan penyimpanan residen untuk ListHead jenis SLIST_HEADER dan untuk ExecutiveSpinLock, seperti yang ditunjukkan pada gambar sebelumnya. Ini harus menginisialisasi kunci putar dan mengatur antreannya sebelum memanggil ExInterlockedPushEntrySList untuk memasukkan entri awal ke dalam antreannya.
Untuk informasi selengkapnya, lihat Mengelola Prioritas Perangkat Keras dan Kunci Spin. Untuk persyaratan IRQL untuk rutinitas dukungan tertentu, lihat halaman referensi rutin.
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk