WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [HVM] Rate limit guest accesses to the qe

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Rate limit guest accesses to the qemu virtual serial port. This stops
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 25 Sep 2006 18:40:16 +0000
Delivery-date: Mon, 25 Sep 2006 11:41:11 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Steven Smith <ssmith@xxxxxxxxxxxxx>
# Node ID 1d3f52eb256e3522edc12daca91039b319dbbbe5
# Parent  b7b653e36d20811831f26bb951ea66dca5854b17
[HVM] Rate limit guest accesses to the qemu virtual serial port.  This stops
grub's boot menu from hammering dom0.

Signed-off-by: Steven Smith <sos22@xxxxxxxxx>
---
 tools/ioemu/hw/serial.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+)

diff -r b7b653e36d20 -r 1d3f52eb256e tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c   Mon Sep 25 16:31:02 2006 +0100
+++ b/tools/ioemu/hw/serial.c   Mon Sep 25 17:27:18 2006 +0100
@@ -22,6 +22,9 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include <sys/time.h>
+#include <time.h>
+#include <assert.h>
 
 //#define DEBUG_SERIAL
 
@@ -138,6 +141,67 @@ static void serial_update_parameters(Ser
     printf("speed=%d parity=%c data=%d stop=%d\n", 
            speed, parity, data_bits, stop_bits);
 #endif
+}
+
+/* Rate limit serial requests so that e.g. grub on a serial console
+   doesn't kill dom0.  Simple token bucket.  If we get some actual
+   data from the user, instantly refil the bucket. */
+
+/* How long it takes to generate a token, in microseconds. */
+#define TOKEN_PERIOD 1000
+/* Maximum and initial size of token bucket */
+#define TOKENS_MAX 100000
+
+static int tokens_avail;
+
+static void serial_get_token(void)
+{
+    static struct timeval last_refil_time;
+    static int started;
+
+    assert(tokens_avail >= 0);
+    if (!tokens_avail) {
+       struct timeval delta, now;
+       int generated;
+
+       if (!started) {
+           gettimeofday(&last_refil_time, NULL);
+           tokens_avail = TOKENS_MAX;
+           started = 1;
+           return;
+       }
+    retry:
+       gettimeofday(&now, NULL);
+       delta.tv_sec = now.tv_sec - last_refil_time.tv_sec;
+       delta.tv_usec = now.tv_usec - last_refil_time.tv_usec;
+       if (delta.tv_usec < 0) {
+           delta.tv_usec += 1000000;
+           delta.tv_sec--;
+       }
+       assert(delta.tv_usec >= 0 && delta.tv_sec >= 0);
+       if (delta.tv_usec < TOKEN_PERIOD) {
+           struct timespec ts;
+           /* Wait until at least one token is available. */
+           ts.tv_sec = TOKEN_PERIOD / 1000000;
+           ts.tv_nsec = (TOKEN_PERIOD % 1000000) * 1000;
+           while (nanosleep(&ts, &ts) < 0 && errno == EINTR)
+               ;
+           goto retry;
+       }
+       generated = (delta.tv_sec * 1000000) / TOKEN_PERIOD;
+       generated +=
+           ((delta.tv_sec * 1000000) % TOKEN_PERIOD + delta.tv_usec) / 
TOKEN_PERIOD;
+       assert(generated > 0);
+
+       last_refil_time.tv_usec += (generated * TOKEN_PERIOD) % 1000000;
+       last_refil_time.tv_sec  += last_refil_time.tv_usec / 1000000;
+       last_refil_time.tv_usec %= 1000000;
+       last_refil_time.tv_sec  += (generated * TOKEN_PERIOD) / 1000000;
+       if (generated > TOKENS_MAX)
+           generated = TOKENS_MAX;
+       tokens_avail = generated;
+    }
+    tokens_avail--;
 }
 
 static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
@@ -245,9 +309,11 @@ static uint32_t serial_ioport_read(void 
         ret = s->mcr;
         break;
     case 5:
+       serial_get_token();
         ret = s->lsr;
         break;
     case 6:
+       serial_get_token();
         if (s->mcr & UART_MCR_LOOP) {
             /* in loopback, the modem output pins are connected to the
                inputs */
@@ -296,12 +362,14 @@ static void serial_receive1(void *opaque
 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
 {
     SerialState *s = opaque;
+    tokens_avail = TOKENS_MAX;
     serial_receive_byte(s, buf[0]);
 }
 
 static void serial_event(void *opaque, int event)
 {
     SerialState *s = opaque;
+    tokens_avail = TOKENS_MAX;
     if (event == CHR_EVENT_BREAK)
         serial_receive_break(s);
 }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM] Rate limit guest accesses to the qemu virtual serial port. This stops, Xen patchbot-unstable <=