|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH xenvif 3/5] Use a reader/writer lock in the mac module
Each receiver thread needs to call MacApplyFilters() but the implementation
uses a normal kernel spin lock and hence the threads will all contend the
lock. Switch the mac code to use a reader/writer lock so that
MacApplyFilters() can acquire the lock as a reader and thus avoid causing
the contention.
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
src/xenvif/mac.c | 139 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 110 insertions(+), 29 deletions(-)
diff --git a/src/xenvif/mac.c b/src/xenvif/mac.c
index 3110dde..428200a 100644
--- a/src/xenvif/mac.c
+++ b/src/xenvif/mac.c
@@ -49,7 +49,7 @@ typedef struct _XENVIF_MAC_MULTICAST {
struct _XENVIF_MAC {
PXENVIF_FRONTEND Frontend;
- KSPIN_LOCK Lock;
+ EX_SPIN_LOCK Lock;
BOOLEAN Connected;
BOOLEAN Enabled;
ULONG MaximumFrameSize;
@@ -214,7 +214,6 @@ MacInitialize(
if (*Mac == NULL)
goto fail1;
- KeInitializeSpinLock(&(*Mac)->Lock);
InitializeListHead(&(*Mac)->MulticastList);
FdoGetDebugInterface(PdoGetFdo(FrontendGetPdo(Frontend)),
@@ -233,6 +232,52 @@ fail1:
return status;
}
+static FORCEINLINE VOID
+__drv_requiresIRQL(DISPATCH_LEVEL)
+__MacAcquireLockExclusive(
+ IN PXENVIF_MAC Mac
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+ ExAcquireSpinLockExclusiveAtDpcLevel(&Mac->Lock);
+}
+
+static FORCEINLINE VOID
+__drv_requiresIRQL(DISPATCH_LEVEL)
+__MacReleaseLockExclusive(
+ IN PXENVIF_MAC Mac
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+#pragma prefast(disable:26110)
+ ExReleaseSpinLockExclusiveFromDpcLevel(&Mac->Lock);
+}
+
+static FORCEINLINE VOID
+__drv_requiresIRQL(DISPATCH_LEVEL)
+__MacAcquireLockShared(
+ IN PXENVIF_MAC Mac
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+ ExAcquireSpinLockSharedAtDpcLevel(&Mac->Lock);
+}
+
+static FORCEINLINE VOID
+__drv_requiresIRQL(DISPATCH_LEVEL)
+__MacReleaseLockShared(
+ IN PXENVIF_MAC Mac
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+#pragma prefast(disable:26110)
+ ExReleaseSpinLockSharedFromDpcLevel(&Mac->Lock);
+}
+
static NTSTATUS
MacDumpAddressTable(
IN PXENVIF_MAC Mac
@@ -250,7 +295,8 @@ MacDumpAddressTable(
Frontend = Mac->Frontend;
- KeAcquireSpinLock(&Mac->Lock, &Irql);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockShared(Mac);
status = STATUS_UNSUCCESSFUL;
if (!Mac->Connected)
@@ -284,7 +330,8 @@ MacDumpAddressTable(
ASSERT3U(Index, ==, Count);
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockShared(Mac);
+ KeLowerIrql(Irql);
(VOID) XENBUS_STORE(Remove,
&Mac->StoreInterface,
@@ -328,7 +375,8 @@ fail2:
fail1:
Error("fail1 (%08x)\n", status);
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
return status;
}
@@ -344,6 +392,8 @@ MacConnect(
ULONG64 Mtu;
NTSTATUS status;
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
Frontend = Mac->Frontend;
status = XENBUS_DEBUG(Acquire, &Mac->DebugInterface);
@@ -399,10 +449,12 @@ MacConnect(
if (!NT_SUCCESS(status))
goto fail5;
- KeAcquireSpinLockAtDpcLevel(&Mac->Lock);
+ __MacAcquireLockExclusive(Mac);
+
ASSERT(!Mac->Connected);
Mac->Connected = TRUE;
- KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+
+ __MacReleaseLockExclusive(Mac);
(VOID) MacDumpAddressTable(Mac);
@@ -456,7 +508,8 @@ MacEnable(
Frontend = Mac->Frontend;
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- KeAcquireSpinLockAtDpcLevel(&Mac->Lock);
+
+ __MacAcquireLockExclusive(Mac);
Thread = VifGetMacThread(PdoGetVifContext(FrontendGetPdo(Frontend)));
@@ -472,7 +525,7 @@ MacEnable(
ASSERT(!Mac->Enabled);
Mac->Enabled = TRUE;
- KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+ __MacReleaseLockExclusive(Mac);
Trace("<====\n");
return STATUS_SUCCESS;
@@ -480,7 +533,7 @@ MacEnable(
fail1:
Error("fail1 (%08x)\n");
- KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+ __MacReleaseLockExclusive(Mac);
return status;
}
@@ -497,7 +550,8 @@ MacDisable(
Frontend = Mac->Frontend;
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- KeAcquireSpinLockAtDpcLevel(&Mac->Lock);
+
+ __MacAcquireLockExclusive(Mac);
ASSERT(Mac->Enabled);
Mac->Enabled = FALSE;
@@ -507,7 +561,7 @@ MacDisable(
Mac->Watch);
Mac->Watch = NULL;
- KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+ __MacReleaseLockExclusive(Mac);
Trace("<====\n");
}
@@ -521,10 +575,14 @@ MacDisconnect(
Frontend = Mac->Frontend;
- KeAcquireSpinLockAtDpcLevel(&Mac->Lock);
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+ __MacAcquireLockExclusive(Mac);
+
ASSERT(Mac->Connected);
Mac->Connected = FALSE;
- KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+
+ __MacReleaseLockExclusive(Mac);
XENBUS_DEBUG(Deregister,
&Mac->DebugInterface,
@@ -584,7 +642,7 @@ MacTeardown(
RtlZeroMemory(&Mac->DebugInterface,
sizeof (XENBUS_DEBUG_INTERFACE));
- RtlZeroMemory(&Mac->Lock, sizeof (KSPIN_LOCK));
+ Mac->Lock = 0;
ASSERT(IsZeroMemory(Mac, sizeof (XENVIF_MAC)));
__MacFree(Mac);
@@ -710,10 +768,14 @@ MacAddMulticastAddress(
Multicast->Address = *Address;
- KeAcquireSpinLock(&Mac->Lock, &Irql);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockExclusive(Mac);
+
InsertTailList(&Mac->MulticastList, &Multicast->ListEntry);
Mac->MulticastCount++;
- KeReleaseSpinLock(&Mac->Lock, Irql);
+
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
(VOID) MacDumpAddressTable(Mac);
@@ -748,7 +810,8 @@ MacRemoveMulticastAddress(
Frontend = Mac->Frontend;
- KeAcquireSpinLock(&Mac->Lock, &Irql);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockExclusive(Mac);
for (ListEntry = Mac->MulticastList.Flink;
ListEntry != &Mac->MulticastList;
@@ -773,7 +836,8 @@ found:
RemoveEntryList(&Multicast->ListEntry);
__MacFree(Multicast);
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
(VOID) MacDumpAddressTable(Mac);
@@ -791,7 +855,8 @@ found:
fail1:
Error("fail1 (%08x)\n", status);
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
return status;
}
@@ -807,7 +872,8 @@ MacQueryMulticastAddresses(
KIRQL Irql;
NTSTATUS status;
- KeAcquireSpinLock(&Mac->Lock, &Irql);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockShared(Mac);
status = STATUS_BUFFER_OVERFLOW;
if (Address == NULL || *Count < Mac->MulticastCount)
@@ -827,14 +893,16 @@ MacQueryMulticastAddresses(
}
ASSERT3U(*Count, ==, Mac->MulticastCount);
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockShared(Mac);
+ KeLowerIrql(Irql);
return STATUS_SUCCESS;
fail1:
*Count = Mac->MulticastCount;
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
return status;
}
@@ -862,21 +930,25 @@ MacSetFilterLevel(
if (Type >= ETHERNET_ADDRESS_TYPE_COUNT)
goto fail1;
- KeAcquireSpinLock(&Mac->Lock, &Irql);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockExclusive(Mac);
status = STATUS_INVALID_PARAMETER;
if (Level > XENVIF_MAC_FILTER_ALL || Level < XENVIF_MAC_FILTER_NONE)
goto fail2;
Mac->FilterLevel[Type] = Level;
- KeReleaseSpinLock(&Mac->Lock, Irql);
+
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
return STATUS_SUCCESS;
fail2:
Error("fail2\n");
- KeReleaseSpinLock(&Mac->Lock, Irql);
+ __MacReleaseLockExclusive(Mac);
+ KeLowerIrql(Irql);
fail1:
Error("fail1 (%08x)\n", status);
@@ -891,14 +963,21 @@ MacQueryFilterLevel(
OUT PXENVIF_MAC_FILTER_LEVEL Level
)
{
+ KIRQL Irql;
NTSTATUS status;
status = STATUS_INVALID_PARAMETER;
if (Type >= ETHERNET_ADDRESS_TYPE_COUNT)
goto fail1;
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockShared(Mac);
+
*Level = Mac->FilterLevel[Type];
+ __MacReleaseLockShared(Mac);
+ KeLowerIrql(Irql);
+
return STATUS_SUCCESS;
fail1:
@@ -915,12 +994,13 @@ MacApplyFilters(
{
ETHERNET_ADDRESS_TYPE Type;
BOOLEAN Allow;
+ KIRQL Irql;
Type = GET_ETHERNET_ADDRESS_TYPE(DestinationAddress);
Allow = FALSE;
- ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- KeAcquireSpinLockAtDpcLevel(&Mac->Lock);
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ __MacAcquireLockShared(Mac);
switch (Type) {
case ETHERNET_ADDRESS_UNICAST:
@@ -1014,7 +1094,8 @@ MacApplyFilters(
break;
}
- KeReleaseSpinLockFromDpcLevel(&Mac->Lock);
+ __MacReleaseLockShared(Mac);
+ KeLowerIrql(Irql);
return Allow;
}
--
2.5.3
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |