# HG changeset patch # User john.levon@sun.com # Node ID 6cecc40cc954897022eb8fb1b4b4a9b8cd6249d3 # Parent cede50ca17044ac7cee52ccd708043d3b249a0cc Introduce xc_evtchn_*() interface for interacting with /dev/xen/evtchn. No longer open the device as non-blocking: all reads immediately follow a select() on the device indicating it''s ready to read. Signed-off-by: John Levon <john.levon@sun.com> diff -r cede50ca1704 -r 6cecc40cc954 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/console/daemon/io.c Wed Jun 14 01:57:26 2006 -0700 @@ -24,8 +24,8 @@ #include "io.h" #include <xenctrl.h> #include <xs.h> -#include <xen/linux/evtchn.h> #include <xen/io/console.h> +#include <xenctrl.h> #include <malloc.h> #include <stdlib.h> @@ -36,7 +36,6 @@ #include <unistd.h> #include <termios.h> #include <stdarg.h> -#include <sys/ioctl.h> #include <sys/mman.h> #define MAX(a, b) (((a) > (b)) ? (a) : (b)) @@ -64,18 +63,11 @@ struct domain char *conspath; int ring_ref; evtchn_port_t local_port; - int evtchn_fd; + int xce_handle; struct xencons_interface *interface; }; static struct domain *dom_head; - -static void evtchn_notify(struct domain *dom) -{ - struct ioctl_evtchn_notify notify; - notify.port = dom->local_port; - (void)ioctl(dom->evtchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} static void buffer_append(struct domain *dom) { @@ -106,7 +98,7 @@ static void buffer_append(struct domain mb(); intf->out_cons = cons; - evtchn_notify(dom); + xc_evtchn_notify(dom->xce_handle, dom->local_port); if (buffer->max_capacity && buffer->size > buffer->max_capacity) { @@ -234,7 +226,6 @@ static int domain_create_ring(struct dom static int domain_create_ring(struct domain *dom) { int err, remote_port, ring_ref, rc; - struct ioctl_evtchn_bind_interdomain bind; err = xs_gather(xs, dom->conspath, "ring-ref", "%u", &ring_ref, @@ -258,24 +249,24 @@ static int domain_create_ring(struct dom } dom->local_port = -1; - if (dom->evtchn_fd != -1) - close(dom->evtchn_fd); + if (dom->xce_handle != -1) + xc_evtchn_close(dom->xce_handle); /* Opening evtchn independently for each console is a bit * wasteful, but that''s how the code is structured... */ - dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR); - if (dom->evtchn_fd == -1) { + dom->xce_handle = xc_evtchn_open(); + if (dom->xce_handle == -1) { err = errno; goto out; } - bind.remote_domain = dom->domid; - bind.remote_port = remote_port; - rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + rc = xc_evtchn_bind_interdomain(dom->xce_handle, + dom->domid, remote_port); + if (rc == -1) { err = errno; - close(dom->evtchn_fd); - dom->evtchn_fd = -1; + xc_evtchn_close(dom->xce_handle); + dom->xce_handle = -1; goto out; } dom->local_port = rc; @@ -285,8 +276,8 @@ static int domain_create_ring(struct dom if (dom->tty_fd == -1) { err = errno; - close(dom->evtchn_fd); - dom->evtchn_fd = -1; + xc_evtchn_close(dom->xce_handle); + dom->xce_handle = -1; dom->local_port = -1; goto out; } @@ -344,7 +335,7 @@ static struct domain *create_domain(int dom->ring_ref = -1; dom->local_port = -1; dom->interface = NULL; - dom->evtchn_fd = -1; + dom->xce_handle = -1; if (!watch_domain(dom, true)) goto out; @@ -409,9 +400,9 @@ static void shutdown_domain(struct domai if (d->interface != NULL) munmap(d->interface, getpagesize()); d->interface = NULL; - if (d->evtchn_fd != -1) - close(d->evtchn_fd); - d->evtchn_fd = -1; + if (d->xce_handle != -1) + xc_evtchn_close(d->xce_handle); + d->xce_handle = -1; cleanup_domain(d); } @@ -483,7 +474,7 @@ static void handle_tty_read(struct domai } wmb(); intf->in_prod = prod; - evtchn_notify(dom); + xc_evtchn_notify(dom->xce_handle, dom->local_port); } else { close(dom->tty_fd); dom->tty_fd = -1; @@ -516,14 +507,14 @@ static void handle_tty_write(struct doma static void handle_ring_read(struct domain *dom) { - evtchn_port_t v; - - if (!read_sync(dom->evtchn_fd, &v, sizeof(v))) + evtchn_port_t port; + + if ((port = xc_evtchn_pending(dom->xce_handle)) == -1) return; buffer_append(dom); - (void)write_sync(dom->evtchn_fd, &v, sizeof(v)); + (void)xc_evtchn_unmask(dom->xce_handle, port); } static void handle_xs(void) @@ -566,9 +557,9 @@ void handle_io(void) max_fd = MAX(xs_fileno(xs), max_fd); for (d = dom_head; d; d = d->next) { - if (d->evtchn_fd != -1) { - FD_SET(d->evtchn_fd, &readfds); - max_fd = MAX(d->evtchn_fd, max_fd); + if (d->xce_handle != -1) { + FD_SET(d->xce_handle, &readfds); + max_fd = MAX(d->xce_handle, max_fd); } if (d->tty_fd != -1) { @@ -588,8 +579,8 @@ void handle_io(void) for (d = dom_head; d; d = n) { n = d->next; - if (d->evtchn_fd != -1 && - FD_ISSET(d->evtchn_fd, &readfds)) + if (d->xce_handle != -1 && + FD_ISSET(d->xce_handle, &readfds)) handle_ring_read(d); if (d->tty_fd != -1) { diff -r cede50ca1704 -r 6cecc40cc954 tools/console/daemon/utils.c --- a/tools/console/daemon/utils.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/console/daemon/utils.c Wed Jun 14 01:57:26 2006 -0700 @@ -38,32 +38,6 @@ struct xs_handle *xs; int xc; - -bool _read_write_sync(int fd, void *data, size_t size, bool do_read) -{ - size_t offset = 0; - ssize_t len; - - while (offset < size) { - if (do_read) { - len = read(fd, data + offset, size - offset); - } else { - len = write(fd, data + offset, size - offset); - } - - if (len < 1) { - if (len == -1 && (errno == EAGAIN || errno == EINTR)) { - continue; - } else { - return false; - } - } else { - offset += len; - } - } - - return true; -} static void child_exit(int sig) { diff -r cede50ca1704 -r 6cecc40cc954 tools/console/daemon/utils.h --- a/tools/console/daemon/utils.h Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/console/daemon/utils.h Wed Jun 14 01:57:26 2006 -0700 @@ -29,9 +29,6 @@ void daemonize(const char *pidfile); bool xen_setup(void); -#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true) -#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false) -bool _read_write_sync(int fd, void *data, size_t size, bool do_read); extern struct xs_handle *xs; extern int xc; diff -r cede50ca1704 -r 6cecc40cc954 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/ioemu/target-i386-dm/helper2.c Wed Jun 14 01:57:26 2006 -0700 @@ -47,11 +47,9 @@ #include <limits.h> #include <fcntl.h> -#include <sys/ioctl.h> #include <xenctrl.h> #include <xen/hvm/ioreq.h> -#include <xen/linux/evtchn.h> #include "cpu.h" #include "exec-all.h" @@ -123,7 +121,7 @@ target_ulong cpu_get_phys_page_debug(CPU } //the evtchn fd for polling -int evtchn_fd = -1; +int xce_handle = -1; //which vcpu we are serving int send_vcpu = 0; @@ -170,11 +168,10 @@ static ioreq_t* __cpu_get_ioreq(int vcpu //retval--the number of ioreq packet static ioreq_t* cpu_get_ioreq(void) { - int i, rc; + int i; evtchn_port_t port; - rc = read(evtchn_fd, &port, sizeof(port)); - if ( rc == sizeof(port) ) { + if ( (port = xc_evtchn_pending(xce_handle)) != -1 ) { for ( i = 0; i < vcpus; i++ ) if ( shared_page->vcpu_iodata[i].dm_eport == port ) break; @@ -184,8 +181,7 @@ static ioreq_t* cpu_get_ioreq(void) exit(1); } - // unmask the wanted port again - write(evtchn_fd, &port, sizeof(port)); + xc_evtchn_unmask(xce_handle, port); //get the io packet from shared memory send_vcpu = i; @@ -440,8 +436,8 @@ int main_loop(void) /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&wakeup_rfds); - FD_SET(evtchn_fd, &wakeup_rfds); - highest_fds = evtchn_fd; + FD_SET(xce_handle, &wakeup_rfds); + highest_fds = xce_handle; env->send_event = 0; while (1) { @@ -466,20 +462,18 @@ int main_loop(void) } rfds = wakeup_rfds; FD_ZERO(&wakeup_rfds); - FD_SET(evtchn_fd, &wakeup_rfds); + FD_SET(xce_handle, &wakeup_rfds); tun_receive_handler(&rfds); - if ( FD_ISSET(evtchn_fd, &rfds) ) { + if ( FD_ISSET(xce_handle, &rfds) ) { cpu_handle_ioreq(env); } main_loop_wait(0); if (env->send_event) { - struct ioctl_evtchn_notify notify; - env->send_event = 0; - notify.port = shared_page->vcpu_iodata[send_vcpu].dm_eport; - (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); + (void)xc_evtchn_notify(xce_handle, + shared_page->vcpu_iodata[send_vcpu].dm_eport); } } destroy_hvm_domain(); @@ -511,7 +505,6 @@ CPUState * cpu_init() CPUState * cpu_init() { CPUX86State *env; - struct ioctl_evtchn_bind_interdomain bind; int i, rc; cpu_exec_init(); @@ -523,21 +516,19 @@ CPUState * cpu_init() cpu_single_env = env; - if (evtchn_fd != -1)//the evtchn has been opened by another cpu object + if (xce_handle != -1)//the evtchn has been opened by another cpu object return NULL; - //use nonblock reading not polling, may change in future. - evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK); - if (evtchn_fd == -1) { + xce_handle = xc_evtchn_open(); + if (xce_handle == -1) { fprintf(logfile, "open evtchn device error %d\n", errno); return NULL; } /* FIXME: how about if we overflow the page here? */ - bind.remote_domain = domid; for ( i = 0; i < vcpus; i++ ) { - bind.remote_port = shared_page->vcpu_iodata[i].vp_eport; - rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + rc = xc_evtchn_bind_interdomain(xce_handle, domid, + shared_page->vcpu_iodata[i].vp_eport); if ( rc == -1 ) { fprintf(logfile, "bind interdomain ioctl error %d\n", errno); return NULL; diff -r cede50ca1704 -r 6cecc40cc954 tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/libxc/xc_linux.c Wed Jun 14 01:57:26 2006 -0700 @@ -103,6 +103,119 @@ int do_xen_hypercall(int xc_handle, priv (unsigned long)hypercall); } +#define EVTCHN_DEV_NAME "/dev/xen/evtchn" +#define EVTCHN_DEV_MAJOR 10 +#define EVTCHN_DEV_MINOR 201 + +int xc_evtchn_open(void) +{ + struct stat st; + int fd; + + /* Make sure any existing device file links to correct device. */ + if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || + (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) + (void)unlink(EVTCHN_DEV_NAME); + +reopen: + if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 ) + { + if ( (errno == ENOENT) && + ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && + (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, + makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) ) + goto reopen; + + PERROR("Could not open event channel interface"); + return -1; + } + + return fd; +} + +int xc_evtchn_close(int xce_handle) +{ + return close(xce_handle); +} + +int xc_evtchn_notify(int xce_handle, evtchn_port_t port) +{ + struct ioctl_evtchn_notify notify; + + notify.port = port; + + return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid, + evtchn_port_t remote_port) +{ + struct ioctl_evtchn_bind_interdomain bind; + + bind.remote_domain = domid; + bind.remote_port = remote_port; + + return ioctl(xce_handle, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); +} + +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port) +{ + struct ioctl_evtchn_unbind unbind; + + unbind.port = port; + + return ioctl(xce_handle, IOCTL_EVTCHN_UNBIND, &unbind); +} + +evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq) +{ + struct ioctl_evtchn_bind_virq bind; + + bind.virq = virq; + + return ioctl(xce_handle, IOCTL_EVTCHN_BIND_VIRQ, &bind); +} + +static int dorw(int fd, char *data, size_t size, int do_write) +{ + size_t offset = 0; + ssize_t len; + + while ( offset < size ) + { + if (do_write) + len = write(fd, data + offset, size - offset); + else + len = read(fd, data + offset, size - offset); + + if ( len == -1 ) + { + if ( errno == EINTR ) + continue; + return -1; + } + + offset += len; + } + + return 0; +} + +evtchn_port_t xc_evtchn_pending(int xce_handle) +{ + evtchn_port_t port; + + if ( dorw(xce_handle, (char *)&port, sizeof(port), 0) == -1 ) + return -1; + + return port; +} + +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port) +{ + return dorw(xce_handle, (char *)&port, sizeof(port), 1); +} + /* * Local variables: * mode: C diff -r cede50ca1704 -r 6cecc40cc954 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/libxc/xenctrl.h Wed Jun 14 01:57:26 2006 -0700 @@ -604,4 +604,52 @@ int xc_finish_mmu_updates(int xc_handle, int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size); +/* + * Return a handle to the event channel driver, or -1 on failure, in which case + * errno will be set appropriately. + */ +int xc_evtchn_open(void); + +/* + * Close a handle previously allocated with xc_evtchn_open(). + */ +int xc_evtchn_close(int xce_handle); + +/* + * Notify the given event channel. Returns -1 on failure, in which case + * errno will be set appropriately. + */ +int xc_evtchn_notify(int xce_handle, evtchn_port_t port); + +/* + * Returns a new event port bound to the remote port for the given domain ID, + * or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid, + evtchn_port_t remote_port); + +/* + * Unbind the given event channel. Returns -1 on failure, in which case errno + * will be set appropriately. + */ +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port); + +/* + * Bind an event channel to the given VIRQ. Returns the event channel bound to + * the VIRQ, or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq); + +/* + * Return the next event channel to become pending, or -1 on failure, in which + * case errno will be set appropriately. + */ +evtchn_port_t xc_evtchn_pending(int xce_handle); + +/* + * Unmask the given event channel. Returns -1 on failure, in which case errno + * will be set appropriately. + */ +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port); + #endif diff -r cede50ca1704 -r 6cecc40cc954 tools/xenmon/xenbaked.c --- a/tools/xenmon/xenbaked.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenmon/xenbaked.c Wed Jun 14 01:57:26 2006 -0700 @@ -33,9 +33,6 @@ #include <stdlib.h> #include <stdio.h> #include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> @@ -45,7 +42,6 @@ #include <xen/xen.h> #include <string.h> #include <sys/select.h> -#include <xen/linux/evtchn.h> #define PERROR(_m, _a...) \ do { \ @@ -256,51 +252,29 @@ void log_event(int event_id) stat_map[0].event_count++; // other } -#define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 201 - int virq_port; -int eventchn_fd = -1; +int xce_handle = -1; /* Returns the event channel handle. */ /* Stolen from xenstore code */ int eventchn_init(void) { - struct stat st; - struct ioctl_evtchn_bind_virq bind; int rc; // to revert to old way: if (0) return -1; - /* Make sure any existing device file links to correct device. */ - if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || - (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) - (void)unlink(EVTCHN_DEV_NAME); - - reopen: - eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); - if (eventchn_fd == -1) { - if ((errno == ENOENT) && - ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0)) - goto reopen; - return -errno; - } - - if (eventchn_fd < 0) + xce_handle = xc_evtchn_open(); + + if (xce_handle < 0) perror("Failed to open evtchn device"); - bind.virq = VIRQ_TBUF; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); - if (rc == -1) + if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1) perror("Failed to bind to domain exception virq port"); virq_port = rc; - return eventchn_fd; + return xce_handle; } void wait_for_event(void) @@ -310,26 +284,26 @@ void wait_for_event(void) evtchn_port_t port; struct timeval tv; - if (eventchn_fd < 0) { + if (xce_handle < 0) { nanosleep(&opts.poll_sleep, NULL); return; } FD_ZERO(&inset); - FD_SET(eventchn_fd, &inset); + FD_SET(xce_handle, &inset); tv.tv_sec = 1; tv.tv_usec = 0; // tv = millis_to_timespec(&opts.poll_sleep); - ret = select(eventchn_fd+1, &inset, NULL, NULL, &tv); + ret = select(xce_handle+1, &inset, NULL, NULL, &tv); - if ( (ret == 1) && FD_ISSET(eventchn_fd, &inset)) { - if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + if ( (ret == 1) && FD_ISSET(xce_handle, &inset)) { + if ((port = xc_evtchn_pending(xce_handle)) == -1) perror("Failed to read from event fd"); // if (port == virq_port) // printf("got the event I was looking for\r\n"); - - if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + + if (xc_evtchn_unmask(xce_handle, port) == -1) perror("Failed to write to event fd"); } } diff -r cede50ca1704 -r 6cecc40cc954 tools/xenstore/fake_libxc.c --- a/tools/xenstore/fake_libxc.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenstore/fake_libxc.c Wed Jun 14 01:57:26 2006 -0700 @@ -37,7 +37,7 @@ static evtchn_port_t port; static evtchn_port_t port; /* The event channel maps to a signal, shared page to an mmapped file. */ -void evtchn_notify(int local_port) +void xc_evtchn_notify(int xce_handle, int local_port) { assert(local_port == port); if (kill(xs_test_pid, SIGUSR2) != 0) @@ -124,7 +124,7 @@ void fake_ack_event(void) signal(SIGUSR2, send_to_fd); } -int fake_open_eventchn(void) +int xc_evtchn_open(void) { int fds[2]; diff -r cede50ca1704 -r 6cecc40cc954 tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenstore/xenstored_core.c Wed Jun 14 01:57:26 2006 -0700 @@ -54,7 +54,7 @@ #include "hashtable.h" -extern int eventchn_fd; /* in xenstored_domain.c */ +extern int xce_handle; /* in xenstored_domain.c */ static bool verbose = false; LIST_HEAD(connections); @@ -353,7 +353,7 @@ static int initialize_set(fd_set *inset, set_fd(sock, inset, &max); set_fd(ro_sock, inset, &max); - set_fd(eventchn_fd, inset, &max); + set_fd(xce_handle, inset, &max); set_fd(reopen_log_pipe[0], inset, &max); list_for_each_entry(i, &connections, list) { if (i->domain) @@ -1934,7 +1934,7 @@ int main(int argc, char *argv[]) if (FD_ISSET(*ro_sock, &inset)) accept_connection(*ro_sock, false); - if (eventchn_fd > 0 && FD_ISSET(eventchn_fd, &inset)) + if (xce_handle > 0 && FD_ISSET(xce_handle, &inset)) handle_event(); list_for_each_entry(i, &connections, list) { diff -r cede50ca1704 -r 6cecc40cc954 tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenstore/xenstored_domain.c Wed Jun 14 01:57:26 2006 -0700 @@ -18,15 +18,10 @@ */ #include <stdio.h> -#include <linux/ioctl.h> -#include <sys/ioctl.h> #include <sys/mman.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> //#define DEBUG #include "utils.h" @@ -37,12 +32,11 @@ #include "xenstored_test.h" #include <xenctrl.h> -#include <xen/sys/evtchn.h> static int *xc_handle; static evtchn_port_t virq_port; -int eventchn_fd = -1; +int xce_handle = -1; struct domain { @@ -82,19 +76,6 @@ struct domain }; static LIST_HEAD(domains); - -#ifndef TESTING -static void evtchn_notify(int port) -{ - int rc; - - struct ioctl_evtchn_notify notify; - notify.port = port; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} -#else -extern void evtchn_notify(int port); -#endif /* FIXME: Mark connection as broken (close it?) when this happens. */ static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) @@ -146,7 +127,7 @@ static int writechn(struct connection *c mb(); intf->rsp_prod += len; - evtchn_notify(conn->domain->port); + xc_evtchn_notify(xce_handle, conn->domain->port); return len; } @@ -176,7 +157,7 @@ static int readchn(struct connection *co mb(); intf->req_cons += len; - evtchn_notify(conn->domain->port); + xc_evtchn_notify(xce_handle, conn->domain->port); return len; } @@ -184,13 +165,11 @@ static int destroy_domain(void *_domain) static int destroy_domain(void *_domain) { struct domain *domain = _domain; - struct ioctl_evtchn_unbind unbind; list_del(&domain->list); if (domain->port) { - unbind.port = domain->port; - if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1) + if (xc_evtchn_unbind(xce_handle, domain->port) == -1) eprintf("> Unbinding port %i failed!\n", domain->port); } @@ -231,14 +210,14 @@ void handle_event(void) { evtchn_port_t port; - if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + if ((port = xc_evtchn_pending(xce_handle)) == -1) barf_perror("Failed to read from event fd"); if (port == virq_port) domain_cleanup(); #ifndef TESTING - if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + if (xc_evtchn_unmask(xce_handle, port) == -1) barf_perror("Failed to write to event fd"); #endif } @@ -269,7 +248,6 @@ static struct domain *new_domain(void *c int port) { struct domain *domain; - struct ioctl_evtchn_bind_interdomain bind; int rc; @@ -283,9 +261,7 @@ static struct domain *new_domain(void *c talloc_set_destructor(domain, destroy_domain); /* Tell kernel we''re interested in this event. */ - bind.remote_domain = domid; - bind.remote_port = port; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + rc = xc_evtchn_bind_interdomain(xce_handle, domid, port); if (rc == -1) return NULL; domain->port = rc; @@ -490,23 +466,14 @@ static int dom0_init(void) talloc_steal(dom0->conn, dom0); - evtchn_notify(dom0->port); + xc_evtchn_notify(xce_handle, dom0->port); return 0; } - - - -#define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 201 - /* Returns the event channel handle. */ int domain_init(void) { - struct stat st; - struct ioctl_evtchn_bind_virq bind; int rc; xc_handle = talloc(talloc_autofree_context(), int); @@ -519,39 +486,19 @@ int domain_init(void) talloc_set_destructor(xc_handle, close_xc_handle); -#ifdef TESTING - eventchn_fd = fake_open_eventchn(); - (void)&st; -#else - /* Make sure any existing device file links to correct device. */ - if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || - (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) - (void)unlink(EVTCHN_DEV_NAME); - - reopen: - eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); - if (eventchn_fd == -1) { - if ((errno == ENOENT) && - ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0)) - goto reopen; - return -errno; - } -#endif - if (eventchn_fd < 0) + xce_handle = xc_evtchn_open(); + + if (xce_handle < 0) barf_perror("Failed to open evtchn device"); if (dom0_init() != 0) barf_perror("Failed to initialize dom0 state"); - bind.virq = VIRQ_DOM_EXC; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); - if (rc == -1) + if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1) barf_perror("Failed to bind to domain exception virq port"); virq_port = rc; - return eventchn_fd; + return xce_handle; } void domain_entry_inc(struct connection *conn) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 14 Jun 2006, at 18:47, John Levon wrote:> No longer open the device as non-blocking: all reads immediately follow > a select() on the device indicating it''s ready to read.Why change this? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On Wed, Jun 14, 2006 at 08:06:18PM +0100, Keir Fraser wrote:> >No longer open the device as non-blocking: all reads immediately follow > >a select() on the device indicating it''s ready to read. > > Why change this?Because not all users specified O_NONBLOCK, so to keep the exact same code would mean complicating the API a little bit. As there is no extant code that actually takes advantage of O_NONBLOCK, it''s pointless having the extra code (note that xenstore would actually die if it ever got EAGAIN...) regards john _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 14 Jun 2006, at 20:44, John Levon wrote:>>> No longer open the device as non-blocking: all reads immediately >>> follow >>> a select() on the device indicating it''s ready to read. >> >> Why change this? > > Because not all users specified O_NONBLOCK, so to keep the exact same > code would mean complicating the API a little bit. As there is no > extant > code that actually takes advantage of O_NONBLOCK, it''s pointless having > the extra code (note that xenstore would actually die if it ever got > EAGAIN...)Okay, that makes sense. Looking at the patch, one nit I have is that the ''event-channel handle'' (xce_handle) abstraction is broken by the fact that interface users add the handle to fd sets. Either we should just own up to the fact that xce_handle really is just xce_fd, and thus call it that, or else add a xc_evtchn_fd() interface for getting a pollable fd from a xce_handle. Do you have a preference? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On Wed, Jun 14, 2006 at 10:06:25PM +0100, Keir Fraser wrote:> Looking at the patch, one nit I have is that the ''event-channel handle'' > (xce_handle) abstraction is broken by the fact that interface users add > the handle to fd sets. Either we should just own up to the fact that > xce_handle really is just xce_fd, and thus call it that, or else add aI had a feeling you''d say that.> xc_evtchn_fd() interface for getting a pollable fd from a xce_handle.I''d prefer this. I''ll work on fixing this up. regards, john _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
# HG changeset patch # User john.levon@sun.com # Node ID 09743c3e8825a19931c4e863285d638274a7f94b # Parent cede50ca17044ac7cee52ccd708043d3b249a0cc Introduce xc_evtchn_*() interface for interacting with /dev/xen/evtchn. No longer open the device as non-blocking: all reads immediately follow a select() on the device indicating it''s ready to read. Signed-off-by: John Levon <john.levon@sun.com> diff -r cede50ca1704 -r 09743c3e8825 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/console/daemon/io.c Wed Jun 14 07:19:57 2006 -0700 @@ -24,8 +24,8 @@ #include "io.h" #include <xenctrl.h> #include <xs.h> -#include <xen/linux/evtchn.h> #include <xen/io/console.h> +#include <xenctrl.h> #include <malloc.h> #include <stdlib.h> @@ -36,7 +36,6 @@ #include <unistd.h> #include <termios.h> #include <stdarg.h> -#include <sys/ioctl.h> #include <sys/mman.h> #define MAX(a, b) (((a) > (b)) ? (a) : (b)) @@ -64,18 +63,11 @@ struct domain char *conspath; int ring_ref; evtchn_port_t local_port; - int evtchn_fd; + int xce_handle; struct xencons_interface *interface; }; static struct domain *dom_head; - -static void evtchn_notify(struct domain *dom) -{ - struct ioctl_evtchn_notify notify; - notify.port = dom->local_port; - (void)ioctl(dom->evtchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} static void buffer_append(struct domain *dom) { @@ -106,7 +98,7 @@ static void buffer_append(struct domain mb(); intf->out_cons = cons; - evtchn_notify(dom); + xc_evtchn_notify(dom->xce_handle, dom->local_port); if (buffer->max_capacity && buffer->size > buffer->max_capacity) { @@ -234,7 +226,6 @@ static int domain_create_ring(struct dom static int domain_create_ring(struct domain *dom) { int err, remote_port, ring_ref, rc; - struct ioctl_evtchn_bind_interdomain bind; err = xs_gather(xs, dom->conspath, "ring-ref", "%u", &ring_ref, @@ -258,24 +249,24 @@ static int domain_create_ring(struct dom } dom->local_port = -1; - if (dom->evtchn_fd != -1) - close(dom->evtchn_fd); + if (dom->xce_handle != -1) + xc_evtchn_close(dom->xce_handle); /* Opening evtchn independently for each console is a bit * wasteful, but that''s how the code is structured... */ - dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR); - if (dom->evtchn_fd == -1) { + dom->xce_handle = xc_evtchn_open(); + if (dom->xce_handle == -1) { err = errno; goto out; } - bind.remote_domain = dom->domid; - bind.remote_port = remote_port; - rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + rc = xc_evtchn_bind_interdomain(dom->xce_handle, + dom->domid, remote_port); + if (rc == -1) { err = errno; - close(dom->evtchn_fd); - dom->evtchn_fd = -1; + xc_evtchn_close(dom->xce_handle); + dom->xce_handle = -1; goto out; } dom->local_port = rc; @@ -285,8 +276,8 @@ static int domain_create_ring(struct dom if (dom->tty_fd == -1) { err = errno; - close(dom->evtchn_fd); - dom->evtchn_fd = -1; + xc_evtchn_close(dom->xce_handle); + dom->xce_handle = -1; dom->local_port = -1; goto out; } @@ -344,7 +335,7 @@ static struct domain *create_domain(int dom->ring_ref = -1; dom->local_port = -1; dom->interface = NULL; - dom->evtchn_fd = -1; + dom->xce_handle = -1; if (!watch_domain(dom, true)) goto out; @@ -409,9 +400,9 @@ static void shutdown_domain(struct domai if (d->interface != NULL) munmap(d->interface, getpagesize()); d->interface = NULL; - if (d->evtchn_fd != -1) - close(d->evtchn_fd); - d->evtchn_fd = -1; + if (d->xce_handle != -1) + xc_evtchn_close(d->xce_handle); + d->xce_handle = -1; cleanup_domain(d); } @@ -483,7 +474,7 @@ static void handle_tty_read(struct domai } wmb(); intf->in_prod = prod; - evtchn_notify(dom); + xc_evtchn_notify(dom->xce_handle, dom->local_port); } else { close(dom->tty_fd); dom->tty_fd = -1; @@ -516,14 +507,14 @@ static void handle_tty_write(struct doma static void handle_ring_read(struct domain *dom) { - evtchn_port_t v; - - if (!read_sync(dom->evtchn_fd, &v, sizeof(v))) + evtchn_port_t port; + + if ((port = xc_evtchn_pending(dom->xce_handle)) == -1) return; buffer_append(dom); - (void)write_sync(dom->evtchn_fd, &v, sizeof(v)); + (void)xc_evtchn_unmask(dom->xce_handle, port); } static void handle_xs(void) @@ -566,9 +557,10 @@ void handle_io(void) max_fd = MAX(xs_fileno(xs), max_fd); for (d = dom_head; d; d = d->next) { - if (d->evtchn_fd != -1) { - FD_SET(d->evtchn_fd, &readfds); - max_fd = MAX(d->evtchn_fd, max_fd); + if (d->xce_handle != -1) { + int evtchn_fd = xc_evtchn_fd(d->xce_handle); + FD_SET(evtchn_fd, &readfds); + max_fd = MAX(evtchn_fd, max_fd); } if (d->tty_fd != -1) { @@ -588,8 +580,8 @@ void handle_io(void) for (d = dom_head; d; d = n) { n = d->next; - if (d->evtchn_fd != -1 && - FD_ISSET(d->evtchn_fd, &readfds)) + if (d->xce_handle != -1 && + FD_ISSET(xc_evtchn_fd(d->xce_handle), &readfds)) handle_ring_read(d); if (d->tty_fd != -1) { diff -r cede50ca1704 -r 09743c3e8825 tools/console/daemon/utils.c --- a/tools/console/daemon/utils.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/console/daemon/utils.c Wed Jun 14 07:19:57 2006 -0700 @@ -38,32 +38,6 @@ struct xs_handle *xs; int xc; - -bool _read_write_sync(int fd, void *data, size_t size, bool do_read) -{ - size_t offset = 0; - ssize_t len; - - while (offset < size) { - if (do_read) { - len = read(fd, data + offset, size - offset); - } else { - len = write(fd, data + offset, size - offset); - } - - if (len < 1) { - if (len == -1 && (errno == EAGAIN || errno == EINTR)) { - continue; - } else { - return false; - } - } else { - offset += len; - } - } - - return true; -} static void child_exit(int sig) { diff -r cede50ca1704 -r 09743c3e8825 tools/console/daemon/utils.h --- a/tools/console/daemon/utils.h Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/console/daemon/utils.h Wed Jun 14 07:19:57 2006 -0700 @@ -29,9 +29,6 @@ void daemonize(const char *pidfile); bool xen_setup(void); -#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true) -#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false) -bool _read_write_sync(int fd, void *data, size_t size, bool do_read); extern struct xs_handle *xs; extern int xc; diff -r cede50ca1704 -r 09743c3e8825 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/ioemu/target-i386-dm/helper2.c Wed Jun 14 07:19:57 2006 -0700 @@ -47,11 +47,9 @@ #include <limits.h> #include <fcntl.h> -#include <sys/ioctl.h> #include <xenctrl.h> #include <xen/hvm/ioreq.h> -#include <xen/linux/evtchn.h> #include "cpu.h" #include "exec-all.h" @@ -123,7 +121,7 @@ target_ulong cpu_get_phys_page_debug(CPU } //the evtchn fd for polling -int evtchn_fd = -1; +int xce_handle = -1; //which vcpu we are serving int send_vcpu = 0; @@ -170,11 +168,10 @@ static ioreq_t* __cpu_get_ioreq(int vcpu //retval--the number of ioreq packet static ioreq_t* cpu_get_ioreq(void) { - int i, rc; + int i; evtchn_port_t port; - rc = read(evtchn_fd, &port, sizeof(port)); - if ( rc == sizeof(port) ) { + if ( (port = xc_evtchn_pending(xce_handle)) != -1 ) { for ( i = 0; i < vcpus; i++ ) if ( shared_page->vcpu_iodata[i].dm_eport == port ) break; @@ -184,8 +181,7 @@ static ioreq_t* cpu_get_ioreq(void) exit(1); } - // unmask the wanted port again - write(evtchn_fd, &port, sizeof(port)); + xc_evtchn_unmask(xce_handle, port); //get the io packet from shared memory send_vcpu = i; @@ -436,6 +432,7 @@ int main_loop(void) extern int shutdown_requested; CPUState *env = global_env; int retval; + int evtchn_fd = xc_evtchn_fd(xce_handle); extern void main_loop_wait(int); /* Watch stdin (fd 0) to see when it has input. */ @@ -475,11 +472,9 @@ int main_loop(void) main_loop_wait(0); if (env->send_event) { - struct ioctl_evtchn_notify notify; - env->send_event = 0; - notify.port = shared_page->vcpu_iodata[send_vcpu].dm_eport; - (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); + (void)xc_evtchn_notify(xce_handle, + shared_page->vcpu_iodata[send_vcpu].dm_eport); } } destroy_hvm_domain(); @@ -511,7 +506,6 @@ CPUState * cpu_init() CPUState * cpu_init() { CPUX86State *env; - struct ioctl_evtchn_bind_interdomain bind; int i, rc; cpu_exec_init(); @@ -523,21 +517,19 @@ CPUState * cpu_init() cpu_single_env = env; - if (evtchn_fd != -1)//the evtchn has been opened by another cpu object + if (xce_handle != -1)//the evtchn has been opened by another cpu object return NULL; - //use nonblock reading not polling, may change in future. - evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK); - if (evtchn_fd == -1) { + xce_handle = xc_evtchn_open(); + if (xce_handle == -1) { fprintf(logfile, "open evtchn device error %d\n", errno); return NULL; } /* FIXME: how about if we overflow the page here? */ - bind.remote_domain = domid; for ( i = 0; i < vcpus; i++ ) { - bind.remote_port = shared_page->vcpu_iodata[i].vp_eport; - rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + rc = xc_evtchn_bind_interdomain(xce_handle, domid, + shared_page->vcpu_iodata[i].vp_eport); if ( rc == -1 ) { fprintf(logfile, "bind interdomain ioctl error %d\n", errno); return NULL; diff -r cede50ca1704 -r 09743c3e8825 tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/libxc/xc_linux.c Wed Jun 14 07:19:57 2006 -0700 @@ -103,6 +103,124 @@ int do_xen_hypercall(int xc_handle, priv (unsigned long)hypercall); } +#define EVTCHN_DEV_NAME "/dev/xen/evtchn" +#define EVTCHN_DEV_MAJOR 10 +#define EVTCHN_DEV_MINOR 201 + +int xc_evtchn_open(void) +{ + struct stat st; + int fd; + + /* Make sure any existing device file links to correct device. */ + if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || + (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) + (void)unlink(EVTCHN_DEV_NAME); + +reopen: + if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 ) + { + if ( (errno == ENOENT) && + ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && + (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, + makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) ) + goto reopen; + + PERROR("Could not open event channel interface"); + return -1; + } + + return fd; +} + +int xc_evtchn_close(int xce_handle) +{ + return close(xce_handle); +} + +int xc_evtchn_fd(int xce_handle) +{ + return xce_handle; +} + +int xc_evtchn_notify(int xce_handle, evtchn_port_t port) +{ + struct ioctl_evtchn_notify notify; + + notify.port = port; + + return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid, + evtchn_port_t remote_port) +{ + struct ioctl_evtchn_bind_interdomain bind; + + bind.remote_domain = domid; + bind.remote_port = remote_port; + + return ioctl(xce_handle, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); +} + +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port) +{ + struct ioctl_evtchn_unbind unbind; + + unbind.port = port; + + return ioctl(xce_handle, IOCTL_EVTCHN_UNBIND, &unbind); +} + +evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq) +{ + struct ioctl_evtchn_bind_virq bind; + + bind.virq = virq; + + return ioctl(xce_handle, IOCTL_EVTCHN_BIND_VIRQ, &bind); +} + +static int dorw(int fd, char *data, size_t size, int do_write) +{ + size_t offset = 0; + ssize_t len; + + while ( offset < size ) + { + if (do_write) + len = write(fd, data + offset, size - offset); + else + len = read(fd, data + offset, size - offset); + + if ( len == -1 ) + { + if ( errno == EINTR ) + continue; + return -1; + } + + offset += len; + } + + return 0; +} + +evtchn_port_t xc_evtchn_pending(int xce_handle) +{ + evtchn_port_t port; + + if ( dorw(xce_handle, (char *)&port, sizeof(port), 0) == -1 ) + return -1; + + return port; +} + +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port) +{ + return dorw(xce_handle, (char *)&port, sizeof(port), 1); +} + /* * Local variables: * mode: C diff -r cede50ca1704 -r 09743c3e8825 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/libxc/xenctrl.h Wed Jun 14 07:19:57 2006 -0700 @@ -604,4 +604,58 @@ int xc_finish_mmu_updates(int xc_handle, int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size); +/* + * Return a handle to the event channel driver, or -1 on failure, in which case + * errno will be set appropriately. + */ +int xc_evtchn_open(void); + +/* + * Close a handle previously allocated with xc_evtchn_open(). + */ +int xc_evtchn_close(int xce_handle); + +/* + * Return an fd that can be select()ed on for further calls to + * xc_evtchn_pending(). + */ +int xc_evtchn_fd(int xce_handle); + +/* + * Notify the given event channel. Returns -1 on failure, in which case + * errno will be set appropriately. + */ +int xc_evtchn_notify(int xce_handle, evtchn_port_t port); + +/* + * Returns a new event port bound to the remote port for the given domain ID, + * or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid, + evtchn_port_t remote_port); + +/* + * Unbind the given event channel. Returns -1 on failure, in which case errno + * will be set appropriately. + */ +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port); + +/* + * Bind an event channel to the given VIRQ. Returns the event channel bound to + * the VIRQ, or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq); + +/* + * Return the next event channel to become pending, or -1 on failure, in which + * case errno will be set appropriately. + */ +evtchn_port_t xc_evtchn_pending(int xce_handle); + +/* + * Unmask the given event channel. Returns -1 on failure, in which case errno + * will be set appropriately. + */ +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port); + #endif diff -r cede50ca1704 -r 09743c3e8825 tools/xenmon/xenbaked.c --- a/tools/xenmon/xenbaked.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenmon/xenbaked.c Wed Jun 14 07:19:57 2006 -0700 @@ -33,9 +33,6 @@ #include <stdlib.h> #include <stdio.h> #include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> @@ -45,7 +42,6 @@ #include <xen/xen.h> #include <string.h> #include <sys/select.h> -#include <xen/linux/evtchn.h> #define PERROR(_m, _a...) \ do { \ @@ -256,51 +252,29 @@ void log_event(int event_id) stat_map[0].event_count++; // other } -#define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 201 - int virq_port; -int eventchn_fd = -1; +int xce_handle = -1; /* Returns the event channel handle. */ /* Stolen from xenstore code */ int eventchn_init(void) { - struct stat st; - struct ioctl_evtchn_bind_virq bind; int rc; // to revert to old way: if (0) return -1; - /* Make sure any existing device file links to correct device. */ - if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || - (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) - (void)unlink(EVTCHN_DEV_NAME); - - reopen: - eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); - if (eventchn_fd == -1) { - if ((errno == ENOENT) && - ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0)) - goto reopen; - return -errno; - } - - if (eventchn_fd < 0) + xce_handle = xc_evtchn_open(); + + if (xce_handle < 0) perror("Failed to open evtchn device"); - bind.virq = VIRQ_TBUF; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); - if (rc == -1) + if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1) perror("Failed to bind to domain exception virq port"); virq_port = rc; - return eventchn_fd; + return xce_handle; } void wait_for_event(void) @@ -309,27 +283,30 @@ void wait_for_event(void) fd_set inset; evtchn_port_t port; struct timeval tv; + int evtchn_fd; - if (eventchn_fd < 0) { + if (xce_handle < 0) { nanosleep(&opts.poll_sleep, NULL); return; } + evtchn_fd = xc_evtchn_fd(xce_handle); + FD_ZERO(&inset); - FD_SET(eventchn_fd, &inset); + FD_SET(evtchn_fd, &inset); tv.tv_sec = 1; tv.tv_usec = 0; // tv = millis_to_timespec(&opts.poll_sleep); - ret = select(eventchn_fd+1, &inset, NULL, NULL, &tv); + ret = select(evtchn_fd+1, &inset, NULL, NULL, &tv); - if ( (ret == 1) && FD_ISSET(eventchn_fd, &inset)) { - if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + if ( (ret == 1) && FD_ISSET(evtchn_fd, &inset)) { + if ((port = xc_evtchn_pending(xce_handle)) == -1) perror("Failed to read from event fd"); // if (port == virq_port) // printf("got the event I was looking for\r\n"); - - if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + + if (xc_evtchn_unmask(xce_handle, port) == -1) perror("Failed to write to event fd"); } } diff -r cede50ca1704 -r 09743c3e8825 tools/xenstore/fake_libxc.c --- a/tools/xenstore/fake_libxc.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenstore/fake_libxc.c Wed Jun 14 07:19:57 2006 -0700 @@ -37,7 +37,7 @@ static evtchn_port_t port; static evtchn_port_t port; /* The event channel maps to a signal, shared page to an mmapped file. */ -void evtchn_notify(int local_port) +void xc_evtchn_notify(int xce_handle, int local_port) { assert(local_port == port); if (kill(xs_test_pid, SIGUSR2) != 0) @@ -124,7 +124,7 @@ void fake_ack_event(void) signal(SIGUSR2, send_to_fd); } -int fake_open_eventchn(void) +int xc_evtchn_open(void) { int fds[2]; diff -r cede50ca1704 -r 09743c3e8825 tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenstore/xenstored_core.c Wed Jun 14 07:19:57 2006 -0700 @@ -54,7 +54,7 @@ #include "hashtable.h" -extern int eventchn_fd; /* in xenstored_domain.c */ +extern int xce_handle; /* in xenstored_domain.c */ static bool verbose = false; LIST_HEAD(connections); @@ -353,8 +353,11 @@ static int initialize_set(fd_set *inset, set_fd(sock, inset, &max); set_fd(ro_sock, inset, &max); - set_fd(eventchn_fd, inset, &max); set_fd(reopen_log_pipe[0], inset, &max); + + if (xce_handle != -1) + set_fd(xc_evtchn_fd(xce_handle), inset, &max); + list_for_each_entry(i, &connections, list) { if (i->domain) continue; @@ -1769,6 +1772,7 @@ int main(int argc, char *argv[]) bool outputpid = false; bool no_domain_init = false; const char *pidfile = NULL; + int evtchn_fd = -1; while ((opt = getopt_long(argc, argv, "DE:F:HNPS:T:RLVW:", options, NULL)) != -1) { @@ -1907,6 +1911,9 @@ int main(int argc, char *argv[]) signal(SIGUSR1, stop_failtest); #endif + if (xce_handle != -1) + evtchn_fd = xc_evtchn_fd(xce_handle); + /* Get ready to listen to the tools. */ max = initialize_set(&inset, &outset, *sock, *ro_sock); @@ -1934,7 +1941,7 @@ int main(int argc, char *argv[]) if (FD_ISSET(*ro_sock, &inset)) accept_connection(*ro_sock, false); - if (eventchn_fd > 0 && FD_ISSET(eventchn_fd, &inset)) + if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset)) handle_event(); list_for_each_entry(i, &connections, list) { diff -r cede50ca1704 -r 09743c3e8825 tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Mon Jun 12 18:32:47 2006 +0100 +++ b/tools/xenstore/xenstored_domain.c Wed Jun 14 07:19:57 2006 -0700 @@ -18,15 +18,10 @@ */ #include <stdio.h> -#include <linux/ioctl.h> -#include <sys/ioctl.h> #include <sys/mman.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> //#define DEBUG #include "utils.h" @@ -37,12 +32,11 @@ #include "xenstored_test.h" #include <xenctrl.h> -#include <xen/sys/evtchn.h> static int *xc_handle; static evtchn_port_t virq_port; -int eventchn_fd = -1; +int xce_handle = -1; struct domain { @@ -82,19 +76,6 @@ struct domain }; static LIST_HEAD(domains); - -#ifndef TESTING -static void evtchn_notify(int port) -{ - int rc; - - struct ioctl_evtchn_notify notify; - notify.port = port; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} -#else -extern void evtchn_notify(int port); -#endif /* FIXME: Mark connection as broken (close it?) when this happens. */ static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) @@ -146,7 +127,7 @@ static int writechn(struct connection *c mb(); intf->rsp_prod += len; - evtchn_notify(conn->domain->port); + xc_evtchn_notify(xce_handle, conn->domain->port); return len; } @@ -176,7 +157,7 @@ static int readchn(struct connection *co mb(); intf->req_cons += len; - evtchn_notify(conn->domain->port); + xc_evtchn_notify(xce_handle, conn->domain->port); return len; } @@ -184,13 +165,11 @@ static int destroy_domain(void *_domain) static int destroy_domain(void *_domain) { struct domain *domain = _domain; - struct ioctl_evtchn_unbind unbind; list_del(&domain->list); if (domain->port) { - unbind.port = domain->port; - if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1) + if (xc_evtchn_unbind(xce_handle, domain->port) == -1) eprintf("> Unbinding port %i failed!\n", domain->port); } @@ -231,14 +210,14 @@ void handle_event(void) { evtchn_port_t port; - if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + if ((port = xc_evtchn_pending(xce_handle)) == -1) barf_perror("Failed to read from event fd"); if (port == virq_port) domain_cleanup(); #ifndef TESTING - if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port)) + if (xc_evtchn_unmask(xce_handle, port) == -1) barf_perror("Failed to write to event fd"); #endif } @@ -269,7 +248,6 @@ static struct domain *new_domain(void *c int port) { struct domain *domain; - struct ioctl_evtchn_bind_interdomain bind; int rc; @@ -283,9 +261,7 @@ static struct domain *new_domain(void *c talloc_set_destructor(domain, destroy_domain); /* Tell kernel we''re interested in this event. */ - bind.remote_domain = domid; - bind.remote_port = port; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + rc = xc_evtchn_bind_interdomain(xce_handle, domid, port); if (rc == -1) return NULL; domain->port = rc; @@ -490,23 +466,14 @@ static int dom0_init(void) talloc_steal(dom0->conn, dom0); - evtchn_notify(dom0->port); + xc_evtchn_notify(xce_handle, dom0->port); return 0; } - - - -#define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 201 - /* Returns the event channel handle. */ int domain_init(void) { - struct stat st; - struct ioctl_evtchn_bind_virq bind; int rc; xc_handle = talloc(talloc_autofree_context(), int); @@ -519,39 +486,19 @@ int domain_init(void) talloc_set_destructor(xc_handle, close_xc_handle); -#ifdef TESTING - eventchn_fd = fake_open_eventchn(); - (void)&st; -#else - /* Make sure any existing device file links to correct device. */ - if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || - (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) - (void)unlink(EVTCHN_DEV_NAME); - - reopen: - eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); - if (eventchn_fd == -1) { - if ((errno == ENOENT) && - ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0)) - goto reopen; - return -errno; - } -#endif - if (eventchn_fd < 0) + xce_handle = xc_evtchn_open(); + + if (xce_handle < 0) barf_perror("Failed to open evtchn device"); if (dom0_init() != 0) barf_perror("Failed to initialize dom0 state"); - bind.virq = VIRQ_DOM_EXC; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); - if (rc == -1) + if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1) barf_perror("Failed to bind to domain exception virq port"); virq_port = rc; - return eventchn_fd; + return xce_handle; } void domain_entry_inc(struct connection *conn) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel