Discussion:
[win-pv-devel] [PATCH xenvif 1/2] Add a xenstore watch for the "speed" key...
Paul Durrant
2018-11-02 17:21:15 UTC
Permalink
...and allow the value to specify units.

The 'wire' speed advertised by XENNET to the Windows network stack can be
controlled by the value of a "speed" key in the xenstore frontend area.
Values of this key are currently interpreted as decimal gigabits-per-second.

This patch sets a watch on the key (meaning changes to it now take
immediate effect) and allows units to be specified: 'G/g' for gigabits-per-
second, 'M/m' for megabits-per-second, and 'K/k' for kilobit-per-second.
Thus, for example, '100M' means 100 megabits-per-second. If no unit is
specified then the value is assumed to be in gigabits-per-second, as before.

Signed-off-by: Paul Durrant <***@citrix.com>
---
src/xenvif/mac.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 67 insertions(+), 10 deletions(-)

diff --git a/src/xenvif/mac.c b/src/xenvif/mac.c
index 428200a..06a9a18 100644
--- a/src/xenvif/mac.c
+++ b/src/xenvif/mac.c
@@ -62,7 +62,8 @@ struct _XENVIF_MAC {
XENBUS_DEBUG_INTERFACE DebugInterface;
PXENBUS_DEBUG_CALLBACK DebugCallback;
XENBUS_STORE_INTERFACE StoreInterface;
- PXENBUS_STORE_WATCH Watch;
+ PXENBUS_STORE_WATCH DisconnectWatch;
+ PXENBUS_STORE_WATCH SpeedWatch;
};

#define XENVIF_MAC_TAG 'CAM'
@@ -518,10 +519,19 @@ MacEnable(
FrontendGetPath(Frontend),
"disconnect",
ThreadGetEvent(Thread),
- &Mac->Watch);
+ &Mac->DisconnectWatch);
if (!NT_SUCCESS(status))
goto fail1;

+ status = XENBUS_STORE(WatchAdd,
+ &Mac->StoreInterface,
+ FrontendGetPath(Frontend),
+ "speed",
+ ThreadGetEvent(Thread),
+ &Mac->SpeedWatch);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
ASSERT(!Mac->Enabled);
Mac->Enabled = TRUE;

@@ -530,6 +540,14 @@ MacEnable(
Trace("<====\n");
return STATUS_SUCCESS;

+fail2:
+ Error("fail2\n");
+
+ (VOID) XENBUS_STORE(WatchRemove,
+ &Mac->StoreInterface,
+ Mac->DisconnectWatch);
+ Mac->DisconnectWatch = NULL;
+
fail1:
Error("fail1 (%08x)\n");

@@ -558,8 +576,13 @@ MacDisable(

(VOID) XENBUS_STORE(WatchRemove,
&Mac->StoreInterface,
- Mac->Watch);
- Mac->Watch = NULL;
+ Mac->SpeedWatch);
+ Mac->SpeedWatch = NULL;
+
+ (VOID) XENBUS_STORE(WatchRemove,
+ &Mac->StoreInterface,
+ Mac->DisconnectWatch);
+ Mac->DisconnectWatch = NULL;

__MacReleaseLockExclusive(Mac);

@@ -648,14 +671,15 @@ MacTeardown(
__MacFree(Mac);
}

-static FORCEINLINE ULONG
+static FORCEINLINE ULONG64
__MacGetSpeed(
IN PXENVIF_MAC Mac
)
{
PXENVIF_FRONTEND Frontend;
PCHAR Buffer;
- ULONG Speed;
+ ULONG64 Speed;
+ PCHAR Unit;
NTSTATUS status;

Frontend = Mac->Frontend;
@@ -668,14 +692,43 @@ __MacGetSpeed(
&Buffer);
if (!NT_SUCCESS(status)) {
Speed = 1;
+ Unit = "G";
} else {
- Speed = (ULONG)strtol(Buffer, NULL, 10);
+ Speed = _strtoui64(Buffer, &Unit, 10);
+ if (*Unit == '\0')
+ Unit = "G";

XENBUS_STORE(Free,
&Mac->StoreInterface,
Buffer);
}

+ if (*(Unit + 1) != '\0') {
+ Warning("INVALID SPEED: %s\n", Buffer);
+ return 0;
+ }
+
+ switch (*Unit) {
+ case 'g':
+ case 'G':
+ Speed *= 1000000000ull;
+ break;
+
+ case 'm':
+ case 'M':
+ Speed *= 1000000ull;
+ break;
+
+ case 'k':
+ case 'K':
+ Speed *= 1000ull;
+ break;
+
+ default:
+ Warning("INVALID SPEED UNIT: %c\n", *Unit);
+ return 0;
+ }
+
return Speed;
}

@@ -718,9 +771,13 @@ MacQueryState(
OUT PNET_IF_MEDIA_DUPLEX_STATE MediaDuplexState OPTIONAL
)
{
- if (MediaConnectState != NULL || MediaDuplexState != NULL) {
- BOOLEAN Disconnect = __MacGetDisconnect(Mac);
+ ULONG64 Speed = __MacGetSpeed(Mac);
+ BOOLEAN Disconnect = __MacGetDisconnect(Mac);
+
+ if (Speed == 0)
+ Disconnect = TRUE;

+ if (MediaConnectState != NULL || MediaDuplexState != NULL) {
if (MediaConnectState != NULL)
*MediaConnectState = (Disconnect) ?
MediaConnectStateDisconnected :
@@ -733,7 +790,7 @@ MacQueryState(
}

if (LinkSpeed != NULL)
- *LinkSpeed = (ULONG64)__MacGetSpeed(Mac) * 1000000000ull;
+ *LinkSpeed = Speed;
}

VOID
--
2.5.3
Paul Durrant
2018-11-02 17:21:16 UTC
Permalink
...and change the default to 100G.

This patch adds code to check for a new 'MacSpeed' XENVIF parameter
(sampled at initialization time), defaulting to a wire speed of 100G if
it is not present (rather than the 1G default prior to this patch).

Signed-off-by: Paul Durrant <***@citrix.com>
---
src/xenvif/mac.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/xenvif/mac.c b/src/xenvif/mac.c
index 06a9a18..0b17a54 100644
--- a/src/xenvif/mac.c
+++ b/src/xenvif/mac.c
@@ -35,6 +35,7 @@
#include <ethernet.h>

#include "pdo.h"
+#include "registry.h"
#include "frontend.h"
#include "mac.h"
#include "thread.h"
@@ -52,6 +53,7 @@ struct _XENVIF_MAC {
EX_SPIN_LOCK Lock;
BOOLEAN Connected;
BOOLEAN Enabled;
+ ULONG Speed;
ULONG MaximumFrameSize;
ETHERNET_ADDRESS PermanentAddress;
ETHERNET_ADDRESS CurrentAddress;
@@ -207,6 +209,8 @@ MacInitialize(
OUT PXENVIF_MAC *Mac
)
{
+ HANDLE ParametersKey;
+ ULONG MacSpeed;
NTSTATUS status;

*Mac = __MacAllocate(sizeof (XENVIF_MAC));
@@ -215,6 +219,18 @@ MacInitialize(
if (*Mac == NULL)
goto fail1;

+ ParametersKey = DriverGetParametersKey();
+
+ (*Mac)->Speed = 100;
+
+ if (ParametersKey != NULL) {
+ status = RegistryQueryDwordValue(ParametersKey,
+ "MacSpeed",
+ &MacSpeed);
+ if (NT_SUCCESS(status))
+ (*Mac)->Speed = MacSpeed;
+ }
+
InitializeListHead(&(*Mac)->MulticastList);

FdoGetDebugInterface(PdoGetFdo(FrontendGetPdo(Frontend)),
@@ -667,6 +683,8 @@ MacTeardown(

Mac->Lock = 0;

+ Mac->Speed = 0;
+
ASSERT(IsZeroMemory(Mac, sizeof (XENVIF_MAC)));
__MacFree(Mac);
}
@@ -691,7 +709,7 @@ __MacGetSpeed(
"speed",
&Buffer);
if (!NT_SUCCESS(status)) {
- Speed = 1;
+ Speed = Mac->Speed;
Unit = "G";
} else {
Speed = _strtoui64(Buffer, &Unit, 10);
--
2.5.3
Loading...