Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Cykl życia buforu pamięci obejmuje czas od momentu utworzenia buforu do momentu jego usunięcia. W tym temacie opisano scenariusze użycia buforu oraz ich wpływ na moment usunięcia buforu.
W platformie sterowników trybu jądra (KMDF) obiekt żądania reprezentuje żądanie I/O. Każdy obiekt żądania jest skojarzony z co najmniej jednym obiektem pamięci, a każdy obiekt pamięci reprezentuje bufor używany do danych wejściowych lub wyjściowych w żądaniu.
Gdy platforma tworzy obiekty żądania i pamięci reprezentujące przychodzące żądanie we/wy, ustawia obiekt żądania jako obiekt nadrzędny skojarzonych obiektów pamięci. W związku z tym obiekt pamięci może być trwały nie dłużej niż okres istnienia obiektu żądania. Gdy sterownik oparty na ramach ukończy żądanie we/wy, ramy usuwają obiekt żądania i obiekt pamięci, przez co handlery do tych dwóch obiektów stają się nieprawidłowe.
Jednak podstawowy bufor jest inny. W zależności od tego, który składnik utworzył bufor i sposób jego utworzenia, bufor może mieć liczbę odwołań i może być własnością obiektu pamięci — lub nie. Jeśli obiekt pamięci jest właścicielem buforu, bufor ma liczbę odwołań, a jego okres istnienia jest ograniczony do tego obiektu pamięci. Jeśli jakiś inny składnik utworzył bufor, okresy istnienia buforu i obiektu pamięci nie są powiązane.
Sterownik oparty na frameworku może również utworzyć własne obiekty żądań do wysyłania do docelowych urządzeń we/wy. Żądanie utworzone przez sterownik może ponownie użyć istniejącego obiektu pamięci odebranego przez sterownik w żądaniu we/wy. Sterownik, który często wysyła żądania do docelowych obiektów wejścia/wyjścia, może ponownie użyć obiektów żądań, które tworzy.
Zrozumienie czasów życia obiektu żądania, obiektu pamięci i bufora bazowego jest ważne, aby upewnić się, że sterownik nie próbuje odwołać się do nieprawidłowego uchwytu lub wskaźnika buforu.
Rozważ następujące scenariusze użycia:
- Scenariusz 1: sterownik otrzymuje żądanie we/wy z Kernel-Mode Driver Framework (KMDF), obsługuje je i kończy.
- Scenariusz 2: Sterownik odbiera żądanie we/wy z KMDF i przekazuje je do docelowego celu we/wy.
- Scenariusz 3: Sterownik wystawia żądanie we/wy korzystające z istniejącego obiektu pamięci.
- Scenariusz 4: Sterownik wystawia żądanie we/wy używające nowego obiektu pamięci.
- Scenariusz 5. Sterownik ponownie używa utworzonego obiektu żądania.
Scenariusz 1: Sterownik otrzymuje żądanie wejścia/wyjścia z KMDF, obsługuje je i kończy.
W najprostszym scenariuszu KMDF wysyła żądanie do sterownika, który wykonuje operacje we/wy i kończy żądanie. W takim przypadku podstawowy bufor mógł zostać utworzony przez aplikację w trybie użytkownika, przez inny sterownik lub przez sam system operacyjny. Aby uzyskać informacje na temat dostępu do buforów danych, patrz Uzyskiwanie dostępu do buforów w Framework-Based Drivers.
Gdy sterownik ukończy żądanie, struktura usuwa obiekt pamięci. Wskaźnik buforu jest wtedy nieprawidłowy.
Scenariusz 2: Sterownik odbiera żądanie we/wy z KMDF i przekazuje je do obiektu docelowego we/wy.
W tym scenariuszu sterownik przekazuje żądanie do obiektu docelowego we/wy. Poniższy przykładowy kod pokazuje, jak sterownik pobiera dojścia do obiektu pamięci z obiektu żądania przychodzącego, formatuje żądanie wysyłane do obiektu docelowego we/wy i wysyła żądanie:
VOID
EvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status;
WDFMEMORY memory;
WDFIOTARGET ioTarget;
BOOLEAN ret;
ioTarget = WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue));
status = WdfRequestRetrieveOutputMemory(Request, &memory);
if (!NT_SUCCESS(status)) {
goto End;
}
status = WdfIoTargetFormatRequestForRead(ioTarget,
Request,
memory,
NULL,
NULL);
if (!NT_SUCCESS(status)) {
goto End;
}
WdfRequestSetCompletionRoutine(Request,
RequestCompletionRoutine,
WDF_NO_CONTEXT);
ret = WdfRequestSend (Request, ioTarget, WDF_NO_SEND_OPTIONS);
if (!ret) {
status = WdfRequestGetStatus (Request);
goto End;
}
return;
End:
WdfRequestComplete(Request, status);
return;
}
Gdy obiekt docelowy we/wy zakończył żądanie, platforma wywołuje funkcję zwrotną zakończenia ustawioną przez sterownik dla żądania. Poniższy kod przedstawia proste wywołanie zwrotne uzupełniania:
VOID
RequestCompletionRoutine(
IN WDFREQUEST Request,
IN WDFIOTARGET Target,
PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
IN WDFCONTEXT Context
)
{
UNREFERENCED_PARAMETER(Target);
UNREFERENCED_PARAMETER(Context);
WdfRequestComplete(Request, CompletionParams->IoStatus.Status);
return;
}
Gdy sterownik wywołuje WdfRequestComplete podczas wywołania zwrotnego ukończenia, struktura usuwa obiekt pamięci. Uchwyt obiektu pamięci, który pobrał sterownik, jest teraz nieprawidłowy.
Scenariusz 3. Sterownik wystawia żądanie we/wy korzystające z istniejącego obiektu pamięci.
Niektóre sterowniki wysyłają własne żądania we/wy i kierują je do obiektów docelowych, które są reprezentowane przez cele we/wy. Sterownik może utworzyć własny obiekt żądania lub ponownie użyć obiektu żądania utworzonego przez platformę. Korzystając z jednej z technik, sterownik może ponownie użyć obiektu pamięci z poprzedniego żądania. Sterownik nie może zmienić buforu bazowego, ale może przekazać przesunięcie buforu podczas formatowania nowego żądania we/wy.
Aby uzyskać informacje na temat formatowania nowego żądania we/wy używającego istniejącego obiektu pamięci, zobacz Wysyłanie żądań we/wy do ogólnych obiektów docelowych we/wy.
Gdy platforma formatuje żądanie wysłania do obiektu docelowego we/wy, pobiera odwołanie do obiektu pamięci z recyklingu w imieniu obiektu docelowego we/wy. Obiekt docelowy we/wy zachowuje to odwołanie do momentu wystąpienia jednej z następujących akcji:
- Żądanie zostało ukończone.
- Sterownik ponownie formatuje obiekt żądania, wywołując jedną z metod WdfIoTargetFormatRequestXxx lub WdfIoTargetSendXxxSynchronously metod. Aby uzyskać więcej informacji na temat tych metod, zobacz Framework I/O Target Object Methods .
- Sterownik wywołuje WdfRequestReuse.
Po zakończeniu nowego żądania we/wy framework wywołuje funkcję zwrotną ukończenia we/wy, którą sterownik ustawił dla tego żądania. W tym momencie obiekt docelowy I/O nadal przechowuje odniesienie do obiektu pamięci. W związku z tym, w wywołaniu zwrotnym dopełnienia I/O, sterownik musi wywołać WdfRequestReuse na utworzonym przez sterownik obiekcie żądania, zanim ukończy oryginalne żądanie, z którego uzyskano obiekt pamięci. Jeśli sterownik nie wywołuje WdfRequestReuse, występuje sprawdzanie błędów z powodu dodatkowego odwołania.
Scenariusz 4. Sterownik wystawia żądanie we/wy używające nowego obiektu pamięci.
Platforma udostępnia trzy sposoby tworzenia nowych obiektów pamięci w zależności od źródła buforu bazowego. Aby uzyskać więcej informacji, zobacz Using Memory Buffers.
Jeśli bufor jest przydzielany przez platformę lub z listy lookaside utworzonej przez sterownik , obiekt pamięci jest właścicielem buforu, więc wskaźnik buforu pozostaje prawidłowy, o ile obiekt pamięci istnieje. Sterowniki, które wystawiają asynchroniczne żądania we/wy, powinny zawsze używać buforów należących do obiektów pamięci, aby platforma mogła zapewnić, że bufory będą utrzymywane do momentu, gdy żądanie we/wy zostanie zakończone i powróci do sterownika wystawiającego.
Jeśli sterownik przypisuje wcześniej przydzielony bufor do nowego obiektu pamięci przez wywołanie WdfMemoryCreatePreallocated, obiekt pamięci nie jest właścicielem buforu. W takim przypadku okres istnienia obiektu pamięci i okresu istnienia buforu bazowego nie są powiązane. Sterownik musi zarządzać czasem życia buforu i nie może próbować używać nieprawidłowego wskaźnika buforu.
Scenariusz 5. Sterownik ponownie używa utworzonego obiektu żądania.
Sterownik może ponownie użyć tworzonych obiektów żądania, ale musi ponownie zainicjować każdy taki obiekt, wywołując WdfRequestReuse przed każdym ponownym użyciem. Aby uzyskać więcej informacji, zobacz Ponowne wykorzystanie obiektów żądań frameworku.
Przykładowy kod, który ponownie inicjuje obiekt żądania, można znaleźć w przykładach Toaster i NdisEdge dostarczanych z wydaniem KMDF.