Bagikan melalui


Kesalahan di Lingkungan Multiproscessor

Pada sistem operasi berbasis NT, driver multithreaded; mereka dapat menerima beberapa permintaan I/O dari utas yang berbeda secara bersamaan. Dalam merancang driver, Anda harus berasumsi bahwa driver akan dijalankan pada sistem SMP dan mengambil langkah-langkah yang sesuai untuk memastikan integritas data.

Secara khusus, setiap kali driver mengubah data objek global atau file, driver harus menggunakan kunci atau urutan yang saling dikunci untuk mencegah kondisi balapan.

Mengalami kondisi balapan saat mereferensikan data khusus objek global atau file

Dalam cuplikan kode berikut, kondisi balapan dapat terjadi ketika driver mengakses data global di Data.LpcInfo:

   PLPC_INFO pLpcInfo = &Data.LpcInfo; //Pointer to global data
   ...
   ...
   // This saved pointer may be overwritten by another thread.
   pLpcInfo->LpcPortName.Buffer = ExAllocatePool(
                                     PagedPool,
                                     arg->PortName.Length);

Beberapa utas yang memasukkan kode ini sebagai akibat dari panggilan IOCTL dapat menyebabkan kebocoran memori saat penunjuk ditimpa. Untuk menghindari masalah ini, driver harus menggunakan rutinitas Xxx exInterlocked atau beberapa jenis kunci ketika mengubah data global. Persyaratan driver menentukan jenis kunci yang dapat diterima. Untuk informasi lebih lanjut, lihat Spin Locks, Kernel Dispatcher Objects, dan ExAcquireResourceSharedLite.

Contoh berikut mencoba mengalokasikan ulang buffer khusus file (Endpoint-LocalAddress>) untuk menahan alamat titik akhir:

   Endpoint = FileObject->FsContext;

    if ( Endpoint->LocalAddress != NULL &&
         Endpoint->LocalAddressLength <
                   ListenEndpoint->LocalAddressLength ) {

      FREE_POOL (Endpoint->LocalAddress,
                 LOCAL_ADDRESS_POOL_TAG
                 );
      Endpoint->LocalAddress  = NULL;
   }

    if ( Endpoint->LocalAddress == NULL ) {
       Endpoint->LocalAddress =
            ALLOCATE_POOL (NonPagedPool,
                           ListenEndpoint->LocalAddressLength,
                           LOCAL_ADDRESS_POOL_TAG);
   }

Dalam contoh ini, kondisi balapan dapat terjadi dengan akses ke objek file. Karena driver tidak menahan kunci apa pun, dua permintaan untuk objek file yang sama dapat memasukkan fungsi ini. Hasilnya mungkin referensi ke memori yang dikosongkan, beberapa upaya untuk membebaskan memori yang sama, atau kebocoran memori. Untuk menghindari kesalahan ini, dua pernyataan jika harus diapit dalam kunci putar.