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-devel

Re: [Xen-devel] [RFC] PVFB: Add refresh period to XenStore parameters?

To: Markus Armbruster <armbru@xxxxxxxxxx>
Subject: Re: [Xen-devel] [RFC] PVFB: Add refresh period to XenStore parameters?
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Mon, 5 May 2008 17:50:08 +0100
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Mon, 05 May 2008 09:51:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <87ej8hysv6.fsf@xxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, Markus Armbruster <armbru@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
References: <20080303191804.GA11699@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <873ar68spy.fsf@xxxxxxxxxxxxxxxxx> <20080304144952.GA9230@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <873ar67anv.fsf@xxxxxxxxxxxxxxxxx> <20080304161220.GA9852@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <20080501175536.GV4797@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <20080502160638.GG4819@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <877ie917ix.fsf@xxxxxxxxxxxxxxxxx> <20080505091808.GC4497@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> <87ej8hysv6.fsf@xxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
Hello,

Something like this then?



ioemu: transmit idleness information to avoid useless polls

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>

diff -r 32342f2b5742 extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Fri May 02 15:12:43 2008 +0100
+++ b/extras/mini-os/fbfront.c  Mon May 05 17:44:16 2008 +0100
@@ -249,11 +249,41 @@ struct fbfront_dev {
     int stride;
     int mem_length;
     int offset;
+
+    int status;
 };
 
 void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
 {
+    struct fbfront_dev *dev = data;
+    struct xenfb_page *page = dev->page;
+    uint32_t prod, cons;
+    int i;
+
     wake_up(&fbfront_queue);
+    prod = page->in_prod;
+
+    if (prod == page->in_cons)
+        return;
+
+    rmb();      /* ensure we see ring contents up to prod */
+
+    for (i = 0, cons = page->in_cons; cons != prod; i++, cons++) {
+        union xenfb_in_event *event = &XENFB_IN_RING_REF(page, cons);
+        switch (event->type) {
+        case XENFB_TYPE_BACKEND_STATUS:
+            dev->status = event->status.status;
+            printk("got status %d\n", dev->status);
+            break;
+        default:
+            /* ignore */
+            break;
+        }
+    }
+    mb();       /* ensure we got ring contents */
+    page->in_cons = cons;
+
+    notify_remote_via_evtchn(dev->evtchn);
 }
 
 struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int 
width, int height, int depth, int stride, int n)
@@ -292,6 +322,7 @@ struct fbfront_dev *init_fbfront(char *n
     dev->stride = s->line_length = stride;
     dev->mem_length = s->mem_length = n * PAGE_SIZE;
     dev->offset = 0;
+    dev->status = XENFB_BACKEND_STATUS_ACTIVE;
 
     const int max_pd = sizeof(s->pd) / sizeof(s->pd[0]);
     unsigned long mapped = 0;
@@ -405,6 +436,11 @@ static void fbfront_out_event(struct fbf
     wmb(); /* ensure ring contents visible */
     page->out_prod = prod + 1;
     notify_remote_via_evtchn(dev->evtchn);
+}
+
+int fbfront_status(struct fbfront_dev *dev)
+{
+    return dev->status;
 }
 
 void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int 
height)
diff -r 32342f2b5742 extras/mini-os/include/fbfront.h
--- a/extras/mini-os/include/fbfront.h  Fri May 02 15:12:43 2008 +0100
+++ b/extras/mini-os/include/fbfront.h  Mon May 05 17:44:16 2008 +0100
@@ -36,6 +36,7 @@ int fbfront_open(struct fbfront_dev *dev
 int fbfront_open(struct fbfront_dev *dev);
 #endif
 
+int fbfront_status(struct fbfront_dev *dev);
 void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int 
height);
 void fbfront_resize(struct fbfront_dev *dev, int width, int height, int 
stride, int depth, int offset);
 
diff -r 32342f2b5742 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Fri May 02 15:12:43 2008 +0100
+++ b/tools/ioemu/hw/xenfb.c    Mon May 05 17:44:16 2008 +0100
@@ -59,6 +59,7 @@ struct xenfb {
        int offset;             /* offset of the framebuffer */
        int abs_pointer_wanted; /* Whether guest supports absolute pointer */
        int button_state;       /* Last seen pointer button state */
+        int notified_active;   /* Did we request update */
        char protocol[64];      /* frontend protocol */
 };
 
@@ -536,6 +537,40 @@ static void xenfb_on_fb_event(struct xen
        xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
 }
 
+static int xenfb_queue_full(struct xenfb *xenfb)
+{
+        struct xenfb_page *page = xenfb->fb.page;
+        uint32_t cons, prod;
+
+        prod = page->in_prod;
+        cons = page->in_cons;
+        return prod - cons == XENFB_IN_RING_LEN;
+}
+
+static void xenfb_send_event(struct xenfb *xenfb, union xenfb_in_event *event)
+{
+        uint32_t prod;
+        struct xenfb_page *page = xenfb->fb.page;
+
+        prod = page->in_prod;
+        /* caller ensures !xenfb_queue_full() */
+        xen_mb();                   /* ensure ring space available */
+        XENFB_IN_RING_REF(page, prod) = *event;
+        xen_wmb();                  /* ensure ring contents visible */
+        page->in_prod = prod + 1;
+
+       xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
+}
+
+static void xenfb_send_status(struct xenfb *xenfb, int active)
+{
+        union xenfb_in_event event;
+        event.type = XENFB_TYPE_BACKEND_STATUS;
+        event.status.status = active ? XENFB_BACKEND_STATUS_ACTIVE
+                                     : XENFB_BACKEND_STATUS_IDLE ;
+        xenfb_send_event(xenfb, &event);
+}
+
 static void xenfb_on_kbd_event(struct xenfb *xenfb)
 {
        struct xenkbd_page *page = xenfb->kbd.page;
@@ -707,6 +742,7 @@ static int xenfb_read_frontend_fb_config
                             xenfb->protocol) < 0)
                 xenfb->protocol[0] = '\0';
         xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1");
+        xenfb->notified_active = 1;
 
         /* TODO check for permitted ranges */
         fb_page = xenfb->fb.page;
@@ -1185,10 +1221,21 @@ static void xenfb_guest_copy(struct xenf
     dpy_update(xenfb->ds, x, y, w, h);
 }
 
-/* Periodic update of display, no need for any in our case */
+/* Periodic update of display, just announce idleness to the front end */
 static void xenfb_update(void *opaque)
 {
     struct xenfb *xenfb = opaque;
+    if (xenfb->ds->idle) {
+        if (xenfb->notified_active && !xenfb_queue_full(xenfb)) {
+            xenfb_send_status(xenfb, 0);
+            xenfb->notified_active = 0;
+        }
+    } else {
+        if (!xenfb->notified_active && !xenfb_queue_full(xenfb)) {
+            xenfb_send_status(xenfb, 1);
+            xenfb->notified_active = 1;
+        }
+    }
 }
 
 /* QEMU display state changed, so refresh the framebuffer copy */
@@ -1318,7 +1365,22 @@ static void xenfb_pv_setdata(DisplayStat
 
 static void xenfb_pv_refresh(DisplayState *ds)
 {
+    struct fbfront_dev *fb_dev = ds->opaque;
+
     vga_hw_update();
+
+    if (!fb_dev)
+        return;
+
+    if (fbfront_status(fb_dev)) {
+        /* Back to default interval */
+        ds->gui_timer_interval = 0;
+        ds->idle = 0;
+    } else {
+        /* Sleeping interval */
+        ds->gui_timer_interval = 500;
+        ds->idle = 1;
+    }
 }
 
 static void xenfb_kbd_handler(void *opaque)
@@ -1447,6 +1509,7 @@ int xenfb_pv_display_init(DisplayState *
     ds->dpy_colourdepth = xenfb_pv_colourdepth;
     ds->dpy_setdata = xenfb_pv_setdata;
     ds->dpy_refresh = xenfb_pv_refresh;
+    ds->opaque = NULL;
     return 0;
 }
 
diff -r 32342f2b5742 tools/ioemu/sdl.c
--- a/tools/ioemu/sdl.c Fri May 02 15:12:43 2008 +0100
+++ b/tools/ioemu/sdl.c Mon May 05 17:44:16 2008 +0100
@@ -696,9 +696,11 @@ static void sdl_refresh(DisplayState *ds
                if (ev->active.gain) {
                    /* Back to default interval */
                    ds->gui_timer_interval = 0;
+                   ds->idle = 0;
                } else {
                    /* Sleeping interval */
                    ds->gui_timer_interval = 500;
+                   ds->idle = 1;
                }
            }
             break;
diff -r 32342f2b5742 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Fri May 02 15:12:43 2008 +0100
+++ b/tools/ioemu/vl.c  Mon May 05 17:44:16 2008 +0100
@@ -4467,6 +4467,8 @@ void dumb_display_init(DisplayState *ds)
     ds->dpy_resize = dumb_resize;
     ds->dpy_colourdepth = NULL;
     ds->dpy_refresh = dumb_refresh;
+    ds->gui_timer_interval = 500;
+    ds->idle = 1;
 }
 
 /***********************************************************/
diff -r 32342f2b5742 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Fri May 02 15:12:43 2008 +0100
+++ b/tools/ioemu/vl.h  Mon May 05 17:44:16 2008 +0100
@@ -939,6 +939,7 @@ struct DisplayState {
     void *opaque;
     uint32_t *palette;
     uint64_t gui_timer_interval;
+    int idle;
 
     int shared_buf;
     
diff -r 32342f2b5742 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Fri May 02 15:12:43 2008 +0100
+++ b/tools/ioemu/vnc.c Mon May 05 17:44:16 2008 +0100
@@ -778,6 +778,7 @@ static void _vnc_update_client(void *opa
     vs->has_update = 0;
     vnc_flush(vs);
     vs->last_update_time = now;
+    vs->ds->idle = 0;
 
     vs->timer_interval /= 2;
     if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
@@ -790,26 +791,29 @@ static void _vnc_update_client(void *opa
     vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
     if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
        vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
-       if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL &&
-            vs->update_requested) {
-           /* Send a null update.  If the client is no longer
-              interested (e.g. minimised) it'll ignore this, and we
-              can stop scanning the buffer until it sends another
-              update request. */
-           /* It turns out that there's a bug in realvncviewer 4.1.2
-              which means that if you send a proper null update (with
-              no update rectangles), it gets a bit out of sync and
-              never sends any further requests, regardless of whether
-              it needs one or not.  Fix this by sending a single 1x1
-              update rectangle instead. */
-           vnc_write_u8(vs, 0);
-           vnc_write_u8(vs, 0);
-           vnc_write_u16(vs, 1);
-           send_framebuffer_update(vs, 0, 0, 1, 1);
-           vnc_flush(vs);
-           vs->last_update_time = now;
-            vs->update_requested--;
-           return;
+       if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
+            if (!vs->update_requested) {
+                vs->ds->idle = 1;
+            } else {
+                /* Send a null update.  If the client is no longer
+                   interested (e.g. minimised) it'll ignore this, and we
+                   can stop scanning the buffer until it sends another
+                   update request. */
+                /* It turns out that there's a bug in realvncviewer 4.1.2
+                   which means that if you send a proper null update (with
+                   no update rectangles), it gets a bit out of sync and
+                   never sends any further requests, regardless of whether
+                   it needs one or not.  Fix this by sending a single 1x1
+                   update rectangle instead. */
+                vnc_write_u8(vs, 0);
+                vnc_write_u8(vs, 0);
+                vnc_write_u16(vs, 1);
+                send_framebuffer_update(vs, 0, 0, 1, 1);
+                vnc_flush(vs);
+                vs->last_update_time = now;
+                vs->update_requested--;
+                return;
+            }
        }
     }
     qemu_mod_timer(vs->timer, now + vs->timer_interval);
@@ -970,6 +974,7 @@ static int vnc_client_io_error(VncState 
        qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
        closesocket(vs->csock);
        vs->csock = -1;
+        vs->ds->idle = 1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
         free_queue(vs);
@@ -2443,6 +2448,7 @@ static void vnc_listen_read(void *opaque
     vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
     if (vs->csock != -1) {
        VNC_DEBUG("New client on socket %d\n", vs->csock);
+        vs->ds->idle = 0;
         socket_set_nonblock(vs->csock);
        qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
        vnc_write(vs, "RFB 003.008\n", 12);
@@ -2468,6 +2474,7 @@ void vnc_display_init(DisplayState *ds)
        exit(1);
 
     ds->opaque = vs;
+    ds->idle = 1;
     vnc_state = vs;
     vs->display = NULL;
     vs->password = NULL;
diff -r 32342f2b5742 xen/include/public/io/fbif.h
--- a/xen/include/public/io/fbif.h      Fri May 02 15:12:43 2008 +0100
+++ b/xen/include/public/io/fbif.h      Mon May 05 17:44:16 2008 +0100
@@ -80,14 +80,30 @@ union xenfb_out_event
 
 /*
  * Frontends should ignore unknown in events.
- * No in events currently defined.
  */
+
+/*
+ * Backend idleness report
+ * Backend sends it when the output window is somehow non visible
+ * (minimized, no client, etc.)
+ */
+#define XENFB_TYPE_BACKEND_STATUS 1
+
+#define XENFB_BACKEND_STATUS_IDLE 0
+#define XENFB_BACKEND_STATUS_ACTIVE 1
+
+struct xenfb_backend_status
+{
+    uint8_t type;    /* XENFB_TYPE_BACKEND_STATUS */
+    uint8_t status;  /* XENFB_BACKEND_STATUS_* */
+};
 
 #define XENFB_IN_EVENT_SIZE 40
 
 union xenfb_in_event
 {
     uint8_t type;
+    struct xenfb_backend_status status;
     char pad[XENFB_IN_EVENT_SIZE];
 };
 

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

<Prev in Thread] Current Thread [Next in Thread>