[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH xenvif 1/2] Add a xenstore watch for the "speed" key...



...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 <paul.durrant@xxxxxxxxxx>
---
 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


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.