|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 03/03] Use list of targets
Replace target array with target list
Remove Pdo reference count and remove event
Destroy Pdo in response to Remove Irp
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
src/xenvbd/fdo.c | 176 +++++++++++++++++++++++++++----------------------------
src/xenvbd/fdo.h | 8 +--
src/xenvbd/pdo.c | 109 ++++++++++------------------------
src/xenvbd/pdo.h | 8 ++-
4 files changed, 126 insertions(+), 175 deletions(-)
diff --git a/src/xenvbd/fdo.c b/src/xenvbd/fdo.c
index df3e9ff..526c6c9 100644
--- a/src/xenvbd/fdo.c
+++ b/src/xenvbd/fdo.c
@@ -84,7 +84,7 @@ struct _XENVBD_FDO {
// Targets
KSPIN_LOCK TargetLock;
- PXENVBD_PDO Targets[XENVBD_MAX_TARGETS];
+ LIST_ENTRY Targets;
// Target Enumeration
PXENVBD_THREAD RescanThread;
@@ -124,48 +124,36 @@ __FdoSetDevicePowerState(
__checkReturn
static FORCEINLINE PXENVBD_PDO
-__FdoGetPdoAlways(
+___FdoGetPdo(
__in PXENVBD_FDO Fdo,
__in ULONG TargetId,
__in PCHAR Caller
)
{
- PXENVBD_PDO Pdo;
KIRQL Irql;
+ PLIST_ENTRY ListEntry;
ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS);
KeAcquireSpinLock(&Fdo->TargetLock, &Irql);
- Pdo = Fdo->Targets[TargetId];
- if (Pdo) {
- __PdoReference(Pdo, Caller);
- }
- KeReleaseSpinLock(&Fdo->TargetLock, Irql);
-
- return Pdo;
-}
+ for (ListEntry = Fdo->Targets.Flink;
+ ListEntry != &Fdo->Targets;
+ ListEntry = ListEntry->Flink) {
+ PXENVBD_PDO Pdo = PdoFromListEntry(ListEntry);
-__checkReturn
-static FORCEINLINE PXENVBD_PDO
-___FdoGetPdo(
- __in PXENVBD_FDO Fdo,
- __in ULONG TargetId,
- __in PCHAR Caller
- )
-{
- PXENVBD_PDO Pdo = NULL;
- KIRQL Irql;
+ if (PdoIsMissing(Pdo))
+ continue;
+ if (PdoGetTargetId(Pdo) != TargetId)
+ continue;
- ASSERT3U(TargetId, <, XENVBD_MAX_TARGETS);
+ __PdoReference(Pdo, Caller);
+ KeReleaseSpinLock(&Fdo->TargetLock, Irql);
- KeAcquireSpinLock(&Fdo->TargetLock, &Irql);
- if (Fdo->Targets[TargetId] &&
- __PdoReference(Fdo->Targets[TargetId], Caller) > 0) {
- Pdo = Fdo->Targets[TargetId];
+ return Pdo;
}
KeReleaseSpinLock(&Fdo->TargetLock, Irql);
- return Pdo;
+ return NULL;
}
#define __FdoGetPdo(f, t) ___FdoGetPdo(f, t, __FUNCTION__)
@@ -209,52 +197,54 @@ __FdoDereference(
}
return Result;
}
+static FORCEINLINE BOOLEAN
+ListContains(
+ IN PLIST_ENTRY Head,
+ IN PLIST_ENTRY Find
+ )
+{
+ PLIST_ENTRY ListEntry;
+
+ for (ListEntry = Head->Flink;
+ ListEntry != Head;
+ ListEntry = ListEntry->Flink) {
+ if (ListEntry == Find)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
BOOLEAN
FdoLinkPdo(
- __in PXENVBD_FDO Fdo,
- __in PXENVBD_PDO Pdo
+ IN PXENVBD_FDO Fdo,
+ IN PLIST_ENTRY ListEntry
)
{
KIRQL Irql;
- PXENVBD_PDO Current;
- BOOLEAN Result = FALSE;
- ULONG TargetId = PdoGetTargetId(Pdo);
KeAcquireSpinLock(&Fdo->TargetLock, &Irql);
- Current = Fdo->Targets[TargetId];
- if (Fdo->Targets[TargetId] == NULL) {
- Fdo->Targets[TargetId] = Pdo;
- Result = TRUE;
- }
+ InsertTailList(&Fdo->Targets, ListEntry);
KeReleaseSpinLock(&Fdo->TargetLock, Irql);
- if (!Result) {
- Warning("Target[%d] : Current 0x%p, New 0x%p\n", TargetId, Current,
Pdo);
- }
- return Result;
+ return TRUE;
}
BOOLEAN
FdoUnlinkPdo(
- __in PXENVBD_FDO Fdo,
- __in PXENVBD_PDO Pdo
+ IN PXENVBD_FDO Fdo,
+ IN PLIST_ENTRY ListEntry
)
{
KIRQL Irql;
- PXENVBD_PDO Current;
BOOLEAN Result = FALSE;
- ULONG TargetId = PdoGetTargetId(Pdo);
KeAcquireSpinLock(&Fdo->TargetLock, &Irql);
- Current = Fdo->Targets[TargetId];
- if (Fdo->Targets[TargetId] == Pdo) {
- Fdo->Targets[TargetId] = NULL;
+ if (ListContains(&Fdo->Targets, ListEntry)) {
Result = TRUE;
}
+ RemoveEntryList(ListEntry);
KeReleaseSpinLock(&Fdo->TargetLock, Irql);
- if (!Result) {
- Warning("Target[%d] : Current 0x%p, Expected 0x%p\n", TargetId,
Current, Pdo);
- }
return Result;
}
@@ -357,7 +347,7 @@ FdoDebugCallback(
)
{
PXENVBD_FDO Fdo = Context;
- ULONG TargetId;
+ PLIST_ENTRY ListEntry;
if (Fdo == NULL || Fdo->DebugCallback == NULL)
return;
@@ -388,22 +378,22 @@ FdoDebugCallback(
BufferDebugCallback(&Fdo->Debug);
- for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
+ for (ListEntry = Fdo->Targets.Flink;
+ ListEntry != &Fdo->Targets;
+ ListEntry = ListEntry->Flink) {
// no need to use __FdoGetPdo (which is locked at DISPATCH) as called
at HIGH_LEVEL
- PXENVBD_PDO Pdo = Fdo->Targets[TargetId];
- if (Pdo == NULL)
- continue;
+ PXENVBD_PDO Pdo = PdoFromListEntry(ListEntry);
XENBUS_DEBUG(Printf, &Fdo->Debug,
"FDO: ====> Target[%-3d] : 0x%p\n",
- TargetId, Pdo);
+ PdoGetTargetId(Pdo), Pdo);
// call Target's debug callback directly
PdoDebugCallback(Pdo, &Fdo->Debug);
XENBUS_DEBUG(Printf, &Fdo->Debug,
"FDO: <==== Target[%-3d] : 0x%p\n",
- TargetId, Pdo);
+ PdoGetTargetId(Pdo), Pdo);
}
Fdo->MaximumSrbs = Fdo->CurrentSrbs;
@@ -715,19 +697,26 @@ FdoLogTargets(
__in PXENVBD_FDO Fdo
)
{
- ULONG TargetId;
+ PLIST_ENTRY ListEntry;
+ KIRQL Irql;
+ KeAcquireSpinLock(&Fdo->TargetLock, &Irql);
Verbose("%s ===>\n", Caller);
- for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
- PXENVBD_PDO Pdo = __FdoGetPdoAlways(Fdo, TargetId, __FUNCTION__);
- if (Pdo) {
- const CHAR* Reason = PdoMissingReason(Pdo);
- Verbose("%s : Target[%d] = 0x%p %s\n", Caller, TargetId, Pdo,
- (Reason != NULL) ? Reason : "(present)");
- PdoDereference(Pdo);
- }
+ for (ListEntry = Fdo->Targets.Flink;
+ ListEntry != &Fdo->Targets;
+ ListEntry = ListEntry->Flink) {
+ PXENVBD_PDO Pdo = PdoFromListEntry(ListEntry);
+
+ const CHAR* Reason = PdoMissingReason(Pdo);
+ Verbose("%s : Target[%d] = 0x%p (0x%p) %s\n",
+ Caller,
+ PdoGetTargetId(Pdo),
+ Pdo,
+ PdoGetDeviceObject(Pdo),
+ (Reason != NULL) ? Reason : "(present)");
}
Verbose("%s <===\n", Caller);
+ KeReleaseSpinLock(&Fdo->TargetLock, Irql);
}
__checkReturn
@@ -1226,6 +1215,7 @@ __FdoInitialize(
ASSERT3U(KeGetCurrentIrql(), <=, DISPATCH_LEVEL);
// initialize the memory
Fdo->DevicePower = PowerDeviceD3;
+ InitializeListHead(&Fdo->Targets);
KeInitializeSpinLock(&Fdo->TargetLock);
KeInitializeSpinLock(&Fdo->Lock);
KeInitializeEvent(&Fdo->RemoveEvent, SynchronizationEvent, FALSE);
@@ -1299,8 +1289,6 @@ __FdoTerminate(
__in PXENVBD_FDO Fdo
)
{
- ULONG TargetId;
-
Trace("=====> (%d)\n", KeGetCurrentIrql());
DriverUnlinkFdo(Fdo);
@@ -1334,18 +1322,22 @@ __FdoTerminate(
Fdo->LowerDeviceObject = NULL;
// delete targets
- for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
- PXENVBD_PDO Pdo = __FdoGetPdoAlways(Fdo, TargetId, __FUNCTION__);
- if (Pdo) {
- // Pdo may not be in Deleted state yet, force it as Fdo is
terminating
- if (PdoGetDevicePnpState(Pdo) != Deleted)
- PdoSetDevicePnpState(Pdo, Deleted);
- // update missing (for debug output more than anything else
- PdoSetMissing(Pdo, "FdoTerminate");
- // drop ref-count acquired in __FdoGetPdo *before* destroying Pdo
- PdoDereference(Pdo);
- PdoDestroy(Pdo);
- }
+ for (;;) {
+ PLIST_ENTRY ListEntry;
+ PXENVBD_PDO Pdo;
+
+ ListEntry = RemoveHeadList(&Fdo->Targets);
+ if (ListEntry == &Fdo->Targets)
+ break;
+
+ Pdo = PdoFromListEntry(ListEntry);
+
+ // Pdo may not be in Deleted state yet, force it as Fdo is terminating
+ if (PdoGetDevicePnpState(Pdo) != Deleted)
+ PdoSetDevicePnpState(Pdo, Deleted);
+ // update missing (for debug output more than anything else
+ PdoSetMissing(Pdo, "FdoTerminate");
+ PdoDestroy(Pdo, FALSE);
}
// cleanup memory
@@ -1358,6 +1350,7 @@ __FdoTerminate(
Fdo->CurrentSrbs = Fdo->MaximumSrbs = Fdo->TotalSrbs = 0;
RtlZeroMemory(&Fdo->Enumerator, sizeof(ANSI_STRING));
RtlZeroMemory(&Fdo->TargetLock, sizeof(KSPIN_LOCK));
+ RtlZeroMemory(&Fdo->Targets, sizeof(LIST_ENTRY));
RtlZeroMemory(&Fdo->Lock, sizeof(KSPIN_LOCK));
RtlZeroMemory(&Fdo->RemoveEvent, sizeof(KEVENT));
__FdoZeroInterfaces(Fdo);
diff --git a/src/xenvbd/fdo.h b/src/xenvbd/fdo.h
index fcb5803..0b31bdd 100644
--- a/src/xenvbd/fdo.h
+++ b/src/xenvbd/fdo.h
@@ -64,14 +64,14 @@ __FdoDereference(
// Link PDOs
extern BOOLEAN
FdoLinkPdo(
- __in PXENVBD_FDO Fdo,
- __in PXENVBD_PDO Pdo
+ IN PXENVBD_FDO Fdo,
+ IN PLIST_ENTRY ListEntry
);
extern BOOLEAN
FdoUnlinkPdo(
- __in PXENVBD_FDO Fdo,
- __in PXENVBD_PDO Pdo
+ IN PXENVBD_FDO Fdo,
+ IN PLIST_ENTRY ListEntry
);
// Query Methods
__checkReturn
diff --git a/src/xenvbd/pdo.c b/src/xenvbd/pdo.c
index 76b0112..bd822db 100644
--- a/src/xenvbd/pdo.c
+++ b/src/xenvbd/pdo.c
@@ -60,8 +60,6 @@ typedef struct _XENVBD_SG_LIST {
ULONG Length;
} XENVBD_SG_LIST, *PXENVBD_SG_LIST;
-#define PDO_SIGNATURE 'odpX'
-
typedef struct _XENVBD_LOOKASIDE {
KEVENT Empty;
LONG Used;
@@ -72,11 +70,9 @@ typedef struct _XENVBD_LOOKASIDE {
} XENVBD_LOOKASIDE, *PXENVBD_LOOKASIDE;
struct _XENVBD_PDO {
- ULONG Signature;
+ LIST_ENTRY ListEntry;
PXENVBD_FDO Fdo;
PDEVICE_OBJECT DeviceObject;
- KEVENT RemoveEvent;
- LONG ReferenceCount;
DEVICE_PNP_STATE DevicePnpState;
DEVICE_PNP_STATE PrevPnpState;
DEVICE_POWER_STATE DevicePowerState;
@@ -123,6 +119,14 @@ struct _XENVBD_PDO {
ULONG64 SegsBounced;
};
+PXENVBD_PDO
+PdoFromListEntry(
+ IN PLIST_ENTRY ListEntry
+ )
+{
+ return CONTAINING_RECORD(ListEntry, XENVBD_PDO, ListEntry);
+}
+
//=============================================================================
#define PDO_POOL_TAG 'odPX'
#define REQUEST_POOL_TAG 'qeRX'
@@ -267,17 +271,12 @@ PdoDebugCallback(
{
if (Pdo == NULL || DebugInterface == NULL)
return;
- if (Pdo->Signature != PDO_SIGNATURE)
- return;
XENBUS_DEBUG(Printf, DebugInterface,
"PDO: Fdo 0x%p DeviceObject 0x%p\n",
Pdo->Fdo,
Pdo->DeviceObject);
XENBUS_DEBUG(Printf, DebugInterface,
- "PDO: ReferenceCount %d\n",
- Pdo->ReferenceCount);
- XENBUS_DEBUG(Printf, DebugInterface,
"PDO: DevicePnpState %s (%s)\n",
__PnpStateName(Pdo->DevicePnpState),
__PnpStateName(Pdo->PrevPnpState));
@@ -516,11 +515,8 @@ PdoCreate(
goto fail1;
Verbose("Target[%d] : Creating (%s)\n", TargetId, EmulatedUnplugged ? "PV"
: "Emulated");
- Pdo->Signature = PDO_SIGNATURE;
Pdo->Fdo = Fdo;
Pdo->DeviceObject = NULL; // filled in later
- KeInitializeEvent(&Pdo->RemoveEvent, SynchronizationEvent, FALSE);
- Pdo->ReferenceCount = 1;
Pdo->Paused = 1; // Paused until D3->D0 transition
Pdo->DevicePnpState = Present;
Pdo->DevicePowerState = PowerDeviceD3;
@@ -545,7 +541,8 @@ PdoCreate(
if (!NT_SUCCESS(Status))
goto fail3;
- if (!FdoLinkPdo(Fdo, Pdo))
+ InitializeListHead(&Pdo->ListEntry);
+ if (!FdoLinkPdo(Fdo, &Pdo->ListEntry))
goto fail4;
Verbose("Target[%d] : Created (%s)\n", TargetId, EmulatedUnplugged ? "PV"
: "Emulated");
@@ -575,57 +572,24 @@ fail1:
VOID
PdoDestroy(
- __in PXENVBD_PDO Pdo
+ __in PXENVBD_PDO Pdo,
+ __in BOOLEAN Unlink
)
{
const ULONG TargetId = PdoGetTargetId(Pdo);
- PVOID Objects[4];
- PKWAIT_BLOCK WaitBlock;
Trace("Target[%d] @ (%d) =====>\n", TargetId, KeGetCurrentIrql());
Verbose("Target[%d] : Destroying\n", TargetId);
- ASSERT3U(Pdo->Signature, ==, PDO_SIGNATURE);
- if (!FdoUnlinkPdo(PdoGetFdo(Pdo), Pdo)) {
- Error("Target[%d] : PDO 0x%p not linked to FDO 0x%p\n", TargetId, Pdo,
PdoGetFdo(Pdo));
+ if (Unlink) {
+ if (!FdoUnlinkPdo(PdoGetFdo(Pdo), &Pdo->ListEntry)) {
+ Error("Target[%d] : PDO 0x%p not linked to FDO 0x%p\n", TargetId,
Pdo, PdoGetFdo(Pdo));
+ }
}
PdoD0ToD3(Pdo);
PdoDereference(Pdo); // drop initial ref count
- // Wait for ReferenceCount == 0 and RequestListUsed == 0
- Verbose("Target[%d] : ReferenceCount %d, RequestListUsed %d\n", TargetId,
Pdo->ReferenceCount, Pdo->RequestList.Used);
- Objects[0] = &Pdo->RemoveEvent;
- Objects[1] = &Pdo->RequestList.Empty;
- Objects[2] = &Pdo->SegmentList.Empty;
- Objects[3] = &Pdo->IndirectList.Empty;
-
- WaitBlock = (PKWAIT_BLOCK)__PdoAlloc(sizeof(KWAIT_BLOCK) *
ARRAYSIZE(Objects));
- if (WaitBlock == NULL) {
- ULONG Index;
-
- Error("Unable to allocate resources for KWAIT_BLOCK\n");
-
- for (Index = 0; Index < ARRAYSIZE(Objects); Index++)
- KeWaitForSingleObject(Objects[Index],
- Executive,
- KernelMode,
- FALSE,
- NULL);
- } else {
- KeWaitForMultipleObjects(ARRAYSIZE(Objects),
- Objects,
- WaitAll,
- Executive,
- KernelMode,
- FALSE,
- NULL,
- WaitBlock);
-#pragma prefast(suppress:6102)
- __PdoFree(WaitBlock);
- }
-
- ASSERT3S(Pdo->ReferenceCount, ==, 0);
ASSERT3U(PdoGetDevicePnpState(Pdo), ==, Deleted);
__LookasideTerm(&Pdo->IndirectList);
@@ -635,7 +599,6 @@ PdoDestroy(
FrontendDestroy(Pdo->Frontend);
Pdo->Frontend = NULL;
- ASSERT3U(Pdo->Signature, ==, PDO_SIGNATURE);
RtlZeroMemory(Pdo, sizeof(XENVBD_PDO));
__PdoFree(Pdo);
@@ -730,20 +693,9 @@ __PdoReference(
__in PCHAR Caller
)
{
- LONG Result;
-
- ASSERT3P(Pdo, !=, NULL);
- Result = InterlockedIncrement(&Pdo->ReferenceCount);
- ASSERTREFCOUNT(Result, >, 0, Caller);
-
- if (Result == 1) {
- Result = InterlockedDecrement(&Pdo->ReferenceCount);
- Error("Target[%d] : %s: Attempting to take reference of removed PDO
from %d\n", PdoGetTargetId(Pdo), Caller, Result);
- return 0;
- } else {
- ASSERTREFCOUNT(Result, >, 1, Caller);
- return Result;
- }
+ UNREFERENCED_PARAMETER(Pdo);
+ UNREFERENCED_PARAMETER(Caller);
+ return 1;
}
FORCEINLINE LONG
@@ -752,17 +704,9 @@ __PdoDereference(
__in PCHAR Caller
)
{
- LONG Result;
-
- ASSERT3P(Pdo, !=, NULL);
- Result = InterlockedDecrement(&Pdo->ReferenceCount);
- ASSERTREFCOUNT(Result, >=, 0, Caller);
-
- if (Result == 0) {
- Verbose("Final ReferenceCount dropped, Target[%d] able to be
removed\n", PdoGetTargetId(Pdo));
- KeSetEvent(&Pdo->RemoveEvent, IO_NO_INCREMENT, FALSE);
- }
- return Result;
+ UNREFERENCED_PARAMETER(Pdo);
+ UNREFERENCED_PARAMETER(Caller);
+ return 1;
}
//=============================================================================
@@ -2544,12 +2488,19 @@ __PdoRemoveDevice(
PdoSetMissing(Pdo, "Surprise Remove");
PdoSetDevicePnpState(Pdo, Deleted);
StorPortNotification(BusChangeDetected, PdoGetFdo(Pdo), 0);
+
+ PdoDereference(Pdo);
+ PdoDestroy(Pdo, TRUE);
break;
+ case RemovePending:
case Enumerated:
PdoSetMissing(Pdo, "Removed");
PdoSetDevicePnpState(Pdo, Deleted);
StorPortNotification(BusChangeDetected, PdoGetFdo(Pdo), 0);
+
+ PdoDereference(Pdo);
+ PdoDestroy(Pdo, TRUE);
break;
default:
diff --git a/src/xenvbd/pdo.h b/src/xenvbd/pdo.h
index c5e81ab..333aca8 100644
--- a/src/xenvbd/pdo.h
+++ b/src/xenvbd/pdo.h
@@ -42,6 +42,11 @@ typedef struct _XENVBD_PDO XENVBD_PDO, *PXENVBD_PDO;
#include "types.h"
#include <debug_interface.h>
+extern PXENVBD_PDO
+PdoFromListEntry(
+ IN PLIST_ENTRY ListEntry
+ );
+
extern VOID
PdoDebugCallback(
__in PXENVBD_PDO Pdo,
@@ -62,7 +67,8 @@ PdoCreate(
extern VOID
PdoDestroy(
- __in PXENVBD_PDO Pdo
+ __in PXENVBD_PDO Pdo,
+ __in BOOLEAN Unlink
);
__checkReturn
--
1.9.4.msysgit.1
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |