[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/2] Virtual frame buffer: user space backend
"Christian Limpach" <christian.limpach@xxxxxxxxx> writes: > On 6/26/06, Markus Armbruster <armbru@xxxxxxxxxx> wrote: >> Straightforward conversion to Xenstore. >> >> Applies to hg repository at http://hg.codemonkey.ws/vncfb > > This also looks ok, two of the frontend issues apply here as well: > - handling of the ring indexes (masking of indexes and use of barriers) > - xenbus transactions can fail and there's no code to retry failed > transactions Both done. Same barrier confusion as for front end. > Additionally, it would be good to use the vnc server code which we're > going to use in the updated ioemu. Sharing code for the framebuffers > for pv and non-pv domains is good and we don't want the dependency on > libvncserver anymore and the qemu vnc code is much compacter. You'll > want to grab the vnc files which come with qemu 0.8.1 > (http://xenbits.xensource.com/chris/ioemu-cvs-qemu-0.8.1.tar.bz2) and > then apply the following two patches: > http://xenbits.xensource.com/chris/xs-tools-ioemu.pq.hg?f=18f45f0721d8;file=vnc-cleanup;style=raw > http://xenbits.xensource.com/chris/xs-tools-ioemu.pq.hg?f=bc42f3c29c74;file=vnc-fixes;style=raw > > Ideally, we'd move qemu's vnc support into a library to make it reusable. > > christian Downloaded it, patches applied with liberal fuzz, configure warned about gcc 4 issues, and gcc 4 promptly choked. I'll dig deeper as soon as I find the time. diff -r f67e0a168879 Makefile --- a/Makefile Tue Jan 24 16:14:00 2006 -0500 +++ b/Makefile Mon Jul 10 20:18:57 2006 +0200 @@ -2,7 +2,7 @@ CFLAGS += -g -Wall ifneq ($(XENDIR),) CFLAGS += -I$(XENDIR)/tools/libxc -I$(XENDIR)/linux-2.6.12-xenU/include -LDFLAGS += -L$(XENDIR)/tools/libxc +LDFLAGS += -L$(XENDIR)/tools/libxc -L$(XENDIR)/tools/xenstore endif all: vncfb sdlfb @@ -13,7 +13,7 @@ sdlfb: sdlfb.o xenfb.o sdlfb: sdlfb.o xenfb.o sdlfb.o: CFLAGS += $(shell sdl-config --cflags) -sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl +sdlfb: LDLIBS += $(shell sdl-config --libs) -lxenctrl -lxenstore clean: $(RM) *.o *~ vncfb @@ -22,4 +22,4 @@ keymapping.o: CFLAGS += $(shell pkg-conf vncfb: vncfb.o xenfb.o keymapping.o vncfb.o: CFLAGS += $(shell libvncserver-config --cflags) -vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl +vncfb: LDLIBS += $(shell libvncserver-config --libs) -lxenctrl -lxenstore diff -r f67e0a168879 vncfb.c --- a/vncfb.c Tue Jan 24 16:14:00 2006 -0500 +++ b/vncfb.c Mon Jul 10 20:18:57 2006 +0200 @@ -39,7 +39,12 @@ static void on_ptr_event(int buttonMask, last_y = y; } +#if 0 #define BUG() do { printf("%d\n", __LINE__); return 1; } while(0) +#else +extern void abort(); +#define BUG() abort(); +#endif static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h) { diff -r f67e0a168879 xenfb.c --- a/xenfb.c Tue Jan 24 16:14:00 2006 -0500 +++ b/xenfb.c Mon Jul 10 20:18:57 2006 +0200 @@ -16,6 +16,7 @@ #include <stdio.h> #include <string.h> #include <time.h> +#include <xs.h> #include "xenfb.h" @@ -100,53 +101,80 @@ void xenfb_delete(struct xenfb *xenfb_pu static int xenfb_fb_event(struct xenfb_private *xenfb, union xenfb_in_event *event) { - uint32_t cons, prod; + uint32_t prod; struct xenfb_page *info = xenfb->fb_info; - - cons = XENFB_MASK_RING(info->in_cons, info->in); - prod = XENFB_MASK_RING(info->in_prod, info->in); - - if (XENFB_MASK_RING(prod + 1, info->in) != cons) { - struct ioctl_evtchn_notify notify; - - memcpy(&info->in[prod], event, sizeof(*event)); - info->in_prod = XENFB_MASK_RING(prod + 1, info->in); - notify.port = xenfb->fbdev_port; - return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, ¬ify); - } - - errno = EAGAIN; - return -1; + struct ioctl_evtchn_notify notify; + + prod = info->in_prod; + if (prod - info->in_cons == XENFB_RING_SIZE(info->in)) { + errno = EAGAIN; + return -1; + } + + XENFB_RING_REF(info->in, prod) = *event; + info->in_prod = prod + 1; + notify.port = xenfb->fbdev_port; + return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, ¬ify); } static int xenfb_kbd_event(struct xenfb_private *xenfb, union xenkbd_in_event *event) { - uint32_t cons, prod; + uint32_t prod; struct xenkbd_info *info = xenfb->kbd_info; - - cons = XENKBD_MASK_RING(info->in_cons, info->in); - prod = XENKBD_MASK_RING(info->in_prod, info->in); - - if (XENKBD_MASK_RING(prod + 1, info->in) != cons) { - struct ioctl_evtchn_notify notify; - - memcpy(&info->in[prod], event, sizeof(*event)); - info->in_prod = XENKBD_MASK_RING(prod + 1, info->in); - notify.port = xenfb->kbd_port; - return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, ¬ify); - } - - errno = EAGAIN; - return -1; + struct ioctl_evtchn_notify notify; + + prod = info->in_prod; + if (prod - info->in_cons == XENKBD_RING_SIZE(info->in)) { + errno = EAGAIN; + return -1; + } + + XENKBD_RING_REF(info->in, prod) = *event; + info->in_prod = prod + 1; + notify.port = xenfb->kbd_port; + return ioctl(xenfb->fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +static char *xenfb_path_in_dom(struct xs_handle *h, + unsigned domid, const char *path, + char *buffer, size_t size) +{ + char *domp = xs_get_domain_path(h, domid); + int n = snprintf(buffer, size, "%s/%s", domp, path); + free(domp); + if (n >= size) + return NULL; + return buffer; +} + +static int xenfb_xs_scanf1(struct xs_handle *xsh, unsigned domid, + const char *path, const char *fmt, + void *dest) +{ + char buffer[1024]; + char *p; + int ret; + + p = xenfb_path_in_dom(xsh, domid, path, buffer, sizeof(buffer)); + p = xs_read(xsh, XBT_NULL, p, NULL); + if (!p) + return -ENOENT; + ret = sscanf(p, fmt, dest); + free(p); + if (ret != 1) + return -EDOM; + return 0; } bool xenfb_set_domid(struct xenfb *xenfb_pub, int domid) { struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub; char buffer[1024]; - FILE *f; + struct xs_handle *xsh; + unsigned dummy; + int ret; + char *p, **vec; struct ioctl_evtchn_bind_interdomain bind; - time_t timeout; if (xenfb->domid != -1) { xenfb_unset_domid(xenfb); @@ -154,47 +182,53 @@ bool xenfb_set_domid(struct xenfb *xenfb return true; } - printf("%d\n", __LINE__); - - snprintf(buffer, sizeof(buffer), "/var/run/xenfb/%d.mfn", domid); - timeout = time(0); - do { - f = fopen(buffer, "r"); - if (!f) { - struct timeval tv = { 0, 500 }; - select(0, NULL, NULL, NULL, &tv); - } - } while (f == NULL && (timeout + 10) > time(0)); - - if (!f || fscanf(f, "%lu", &xenfb->fbdev_mfn) != 1) + xsh = xs_daemon_open_readonly(); + if (!xsh) + goto error; + + p = xenfb_path_in_dom(xsh, domid, "vfb", buffer, sizeof(buffer)); + if (!xs_watch(xsh, p, "")) goto error; - fclose(f); f = NULL; - - printf("%d\n", __LINE__); - - snprintf(buffer, sizeof(buffer), "/var/run/xenfb/%d.evtchn", domid); - f = fopen(buffer, "r"); - if (!f || fscanf(f, "%d", &xenfb->fbdev_evtchn) != 1) + p = xenfb_path_in_dom(xsh, domid, "vkbd", buffer, sizeof(buffer)); + if (!xs_watch(xsh, p, "")) goto error; - fclose(f); f = NULL; - - printf("%d\n", __LINE__); - - snprintf(buffer, sizeof(buffer), "/var/run/xenkbd/%d.mfn", domid); - f = fopen(buffer, "r"); - if (!f || fscanf(f, "%lu", &xenfb->kbd_mfn) != 1) - goto error; - fclose(f); f = NULL; - - printf("%d\n", __LINE__); - - snprintf(buffer, sizeof(buffer), "/var/run/xenkbd/%d.evtchn", domid); - f = fopen(buffer, "r"); - if (!f || fscanf(f, "%d", &xenfb->kbd_evtchn) != 1) - goto error; - fclose(f); f = NULL; - - printf("%d\n", __LINE__); + + for (;;) { + ret = xenfb_xs_scanf1(xsh, domid, "vfb/page-ref", "%lu", + &xenfb->fbdev_mfn); + if (ret == -ENOENT || ret == -EAGAIN) + goto wait; + if (ret < 0) + goto error; + ret = xenfb_xs_scanf1(xsh, domid, "vfb/event-channel", "%u", + &xenfb->fbdev_evtchn); + if (ret == -ENOENT || ret == -EAGAIN) + goto wait; + if (ret < 0) + goto error; + ret = xenfb_xs_scanf1(xsh, domid, "vkbd/page-ref", "%lu", + &xenfb->kbd_mfn); + if (ret == -ENOENT || ret == -EAGAIN) + goto wait; + if (ret < 0) + goto error; + ret = xenfb_xs_scanf1(xsh, domid, "vkbd/event-channel", "%u", + &xenfb->kbd_evtchn); + if (ret == -ENOENT || ret == -EAGAIN) + goto wait; + if (ret < 0) + goto error; + break; + + wait: + printf("Waiting...\n"); + vec = xs_read_watch(xsh, &dummy); + if (!vec) + goto error; + free(vec); + } + xs_daemon_close(xsh); + xsh = NULL; printf("%d, %d, %d\n", xenfb->fd, xenfb->fbdev_evtchn, domid); @@ -312,9 +346,9 @@ bool xenfb_set_domid(struct xenfb *xenfb } error: printf("%d\n", __LINE__); - if (f) { - int serrno = errno; - fclose(f); + if (xsh) { + int serrno = errno; + xs_daemon_close(xsh); errno = serrno; } @@ -332,11 +366,10 @@ static void xenfb_on_fb_event(struct xen uint32_t prod, cons; struct xenfb_page *info = xenfb->fb_info; - prod = XENFB_MASK_RING(info->out_prod, info->out); - cons = XENFB_MASK_RING(info->out_cons, info->out); - - for (; cons != prod; cons = XENFB_MASK_RING(cons + 1, info->out)) { - union xenfb_out_event *event = &info->out[cons]; + prod = info->out_prod; + rmb(); /* ensure we see ring contents up to prod */ + for (cons = info->out_cons; cons != prod; cons++) { + union xenfb_out_event *event = &XENFB_RING_REF(info->out, cons); switch (event->type) { case XENFB_TYPE_UPDATE: @@ -344,7 +377,7 @@ static void xenfb_on_fb_event(struct xen break; } } - + /* FIXME do I need a wmb() here? */ info->out_cons = cons; } @@ -353,18 +386,17 @@ static void xenfb_on_kbd_event(struct xe uint32_t prod, cons; struct xenkbd_info *info = xenfb->kbd_info; - prod = XENKBD_MASK_RING(info->out_prod, info->out); - cons = XENKBD_MASK_RING(info->out_cons, info->out); - - for (; cons != prod; cons = XENKBD_MASK_RING(cons + 1, info->out)) { - union xenkbd_out_event *event = &info->out[cons]; + prod = info->out_prod; + rmb(); /* ensure we see ring contents up to prod */ + for (cons = info->out_cons; cons != prod; cons++) { + union xenkbd_out_event *event = &XENKBD_RING_REF(info->out, cons); switch (event->type) { default: break; } } - + /* FIXME do I need a wmb() here? */ info->out_cons = cons; } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |