[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V2] Switch to poll() in cxenstored's IO loop
On Tue, 2013-01-29 at 17:40 +0000, Wei Liu wrote: > Ian, ping? It's in my queue but I've been holding off applying until we get a test pass and push, we've got a weeks worth of stuff in the staging queue at the moment. Ian. > > On Tue, 2013-01-22 at 15:18 +0000, Wei Liu wrote: > > commit 14b82f52d40143019094727b8fa1aa3a111ffab3 > > Author: Wei Liu <wei.liu2@xxxxxxxxxx> > > Date: Mon Jan 21 19:07:37 2013 +0000 > > > > Switch to poll() in cxenstored's IO loop > > > > Poll() can support more file descriptors than select(). We've done this > > for > > xenconsoled, now do this for cxenstored as well. > > > > The code is taken from xenconsoled and modified to adapt to cxenstored. > > > > Updated: > > * reopen pipe if polling on reopen_log_pipe fails. > > * exit if polling on some critical fds fails. > > > > Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> > > > > diff --git a/tools/xenstore/xenstored_core.c > > b/tools/xenstore/xenstored_core.c > > index bd44645..b91704e 100644 > > --- a/tools/xenstore/xenstored_core.c > > +++ b/tools/xenstore/xenstored_core.c > > @@ -19,7 +19,7 @@ > > > > #include <sys/types.h> > > #include <sys/stat.h> > > -#include <sys/select.h> > > +#include <poll.h> > > #ifndef NO_SOCKETS > > #include <sys/socket.h> > > #include <sys/un.h> > > @@ -55,6 +55,12 @@ > > #include "hashtable.h" > > > > extern xc_evtchn *xce_handle; /* in xenstored_domain.c */ > > +static struct pollfd *xce_pollfd; > > +static struct pollfd *fds; > > +static unsigned int current_array_size; > > +static unsigned int nr_fds; > > + > > +#define ROUNDUP(_x, _w) (((unsigned long)(_x)+(1UL<<(_w))-1) & > > ~((1UL<<(_w))-1)) > > > > static bool verbose = false; > > LIST_HEAD(connections); > > @@ -62,6 +68,7 @@ static int tracefd = -1; > > static bool recovery = true; > > static bool remove_local = true; > > static int reopen_log_pipe[2]; > > +static struct pollfd *reopen_log_pipe0_pollfd; > > static char *tracefile = NULL; > > static TDB_CONTEXT *tdb_ctx = NULL; > > > > @@ -199,7 +206,7 @@ void trace_destroy(const void *data, const char *type) > > /** > > * Signal handler for SIGHUP, which requests that the trace log is reopened > > * (in the main loop). A single byte is written to reopen_log_pipe, to > > awaken > > - * the select() in the main loop. > > + * the poll() in the main loop. > > */ > > static void trigger_reopen_log(int signal __attribute__((unused))) > > { > > @@ -279,15 +286,12 @@ static int destroy_conn(void *_conn) > > > > /* Flush outgoing if possible, but don't block. */ > > if (!conn->domain) { > > - fd_set set; > > - struct timeval none; > > - > > - FD_ZERO(&set); > > - FD_SET(conn->fd, &set); > > - none.tv_sec = none.tv_usec = 0; > > + struct pollfd pfd; > > + pfd.fd = conn->fd; > > + pfd.events = POLLOUT; > > > > while (!list_empty(&conn->out_list) > > - && select(conn->fd+1, NULL, &set, NULL, &none) == 1) > > + && poll(&pfd, 1, 0) == 1) > > if (!write_messages(conn)) > > break; > > close(conn->fd); > > @@ -300,52 +304,74 @@ static int destroy_conn(void *_conn) > > } > > > > > > -static void set_fd(int fd, fd_set *set, int *max) > > +static struct pollfd *set_fd(int fd, short events) > > { > > - if (fd < 0) > > - return; > > - FD_SET(fd, set); > > - if (fd > *max) > > - *max = fd; > > -} > > + struct pollfd *ret; > > + if (current_array_size < nr_fds + 1) { > > + struct pollfd *new_fds = NULL; > > + unsigned long newsize; > > + > > + /* Round up to 2^8 boundary, in practice this just > > + * make newsize larger than current_array_size. > > + */ > > + newsize = ROUNDUP(nr_fds + 1, 8); > > > > + new_fds = realloc(fds, sizeof(struct pollfd)*newsize); > > + if (!new_fds) > > + goto fail; > > + fds = new_fds; > > > > -static int initialize_set(fd_set *inset, fd_set *outset, int sock, int > > ro_sock, > > - struct timeval **ptimeout) > > + memset(&fds[0] + current_array_size, 0, > > + sizeof(struct pollfd ) * (newsize-current_array_size)); > > + current_array_size = newsize; > > + } > > + > > + fds[nr_fds].fd = fd; > > + fds[nr_fds].events = events; > > + ret = &fds[nr_fds]; > > + nr_fds++; > > + > > + return ret; > > +fail: > > + syslog(LOG_ERR, "realloc failed, ignoring fd %d\n", fd); > > + return NULL; > > +} > > + > > +static void initialize_fds(int sock, struct pollfd **p_sock_pollfd, > > + int ro_sock, struct pollfd **p_ro_sock_pollfd, > > + int *ptimeout) > > { > > - static struct timeval zero_timeout = { 0 }; > > struct connection *conn; > > - int max = -1; > > > > - *ptimeout = NULL; > > + memset(fds, 0, sizeof(struct pollfd) * current_array_size); > > + nr_fds = 0; > > > > - FD_ZERO(inset); > > - FD_ZERO(outset); > > + *ptimeout = -1; > > > > if (sock != -1) > > - set_fd(sock, inset, &max); > > + *p_sock_pollfd = set_fd(sock, POLLIN|POLLPRI); > > if (ro_sock != -1) > > - set_fd(ro_sock, inset, &max); > > + *p_ro_sock_pollfd = set_fd(ro_sock, POLLIN|POLLPRI); > > if (reopen_log_pipe[0] != -1) > > - set_fd(reopen_log_pipe[0], inset, &max); > > + reopen_log_pipe0_pollfd = > > + set_fd(reopen_log_pipe[0], POLLIN|POLLPRI); > > > > if (xce_handle != NULL) > > - set_fd(xc_evtchn_fd(xce_handle), inset, &max); > > + xce_pollfd = set_fd(xc_evtchn_fd(xce_handle), POLLIN|POLLPRI); > > > > list_for_each_entry(conn, &connections, list) { > > if (conn->domain) { > > if (domain_can_read(conn) || > > (domain_can_write(conn) && > > !list_empty(&conn->out_list))) > > - *ptimeout = &zero_timeout; > > + *ptimeout = 0; > > } else { > > - set_fd(conn->fd, inset, &max); > > + short events = POLLIN|POLLPRI; > > if (!list_empty(&conn->out_list)) > > - FD_SET(conn->fd, outset); > > + events |= POLLOUT; > > + conn->pollfd = set_fd(conn->fd, events); > > } > > } > > - > > - return max; > > } > > > > /* Is child a subnode of parent, or equal? */ > > @@ -1770,14 +1796,13 @@ int priv_domid = 0; > > > > int main(int argc, char *argv[]) > > { > > - int opt, *sock, *ro_sock, max; > > - fd_set inset, outset; > > + int opt, *sock, *ro_sock; > > + struct pollfd *sock_pollfd = NULL, *ro_sock_pollfd = NULL; > > bool dofork = true; > > bool outputpid = false; > > bool no_domain_init = false; > > const char *pidfile = NULL; > > - int evtchn_fd = -1; > > - struct timeval *timeout; > > + int timeout; > > > > while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:T:RLVW:", options, > > NULL)) != -1) { > > @@ -1880,11 +1905,9 @@ int main(int argc, char *argv[]) > > > > signal(SIGHUP, trigger_reopen_log); > > > > - if (xce_handle != NULL) > > - evtchn_fd = xc_evtchn_fd(xce_handle); > > - > > /* Get ready to listen to the tools. */ > > - max = initialize_set(&inset, &outset, *sock, *ro_sock, &timeout); > > + initialize_fds(*sock, &sock_pollfd, *ro_sock, &ro_sock_pollfd, > > + &timeout); > > > > /* Tell the kernel we're up and running. */ > > xenbus_notify_running(); > > @@ -1893,27 +1916,55 @@ int main(int argc, char *argv[]) > > for (;;) { > > struct connection *conn, *next; > > > > - if (select(max+1, &inset, &outset, NULL, timeout) < 0) { > > + if (poll(fds, nr_fds, timeout) < 0) { > > if (errno == EINTR) > > continue; > > - barf_perror("Select failed"); > > + barf_perror("Poll failed"); > > } > > > > - if (reopen_log_pipe[0] != -1 && FD_ISSET(reopen_log_pipe[0], > > &inset)) { > > - char c; > > - if (read(reopen_log_pipe[0], &c, 1) != 1) > > - barf_perror("read failed"); > > - reopen_log(); > > + if (reopen_log_pipe0_pollfd) { > > + if (reopen_log_pipe0_pollfd->revents & > > ~(POLLIN|POLLOUT|POLLPRI)) { > > + close(reopen_log_pipe[0]); > > + close(reopen_log_pipe[1]); > > + init_pipe(reopen_log_pipe); > > + } else if (reopen_log_pipe0_pollfd->revents & POLLIN) { > > + char c; > > + if (read(reopen_log_pipe[0], &c, 1) != 1) > > + barf_perror("read failed"); > > + reopen_log(); > > + } > > + reopen_log_pipe0_pollfd = NULL; > > } > > > > - if (*sock != -1 && FD_ISSET(*sock, &inset)) > > - accept_connection(*sock, true); > > + if (sock_pollfd) { > > + if (sock_pollfd->revents & ~(POLLIN|POLLOUT|POLLPRI)) { > > + barf_perror("sock poll failed"); > > + break; > > + } else if (sock_pollfd->revents & POLLIN) { > > + accept_connection(*sock, true); > > + sock_pollfd = NULL; > > + } > > + } > > > > - if (*ro_sock != -1 && FD_ISSET(*ro_sock, &inset)) > > - accept_connection(*ro_sock, false); > > + if (ro_sock_pollfd) { > > + if (ro_sock_pollfd->revents & > > ~(POLLIN|POLLOUT|POLLPRI)) { > > + barf_perror("ro sock poll failed"); > > + break; > > + } else if (ro_sock_pollfd->revents & POLLIN) { > > + accept_connection(*ro_sock, false); > > + ro_sock_pollfd = NULL; > > + } > > + } > > > > - if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset)) > > - handle_event(); > > + if (xce_pollfd) { > > + if (xce_pollfd->revents & ~(POLLIN|POLLOUT|POLLPRI)) { > > + barf_perror("xce_handle poll failed"); > > + break; > > + } else if (xce_pollfd->revents & POLLIN) { > > + handle_event(); > > + xce_pollfd = NULL; > > + } > > + } > > > > next = list_entry(connections.next, typeof(*conn), list); > > if (&next->list != &connections) > > @@ -1939,21 +1990,27 @@ int main(int argc, char *argv[]) > > if (talloc_free(conn) == 0) > > continue; > > } else { > > - if (FD_ISSET(conn->fd, &inset)) > > + if (conn->pollfd && > > + !(conn->pollfd->revents & > > ~(POLLIN|POLLOUT|POLLPRI)) && > > + (conn->pollfd->revents & POLLIN)) > > handle_input(conn); > > if (talloc_free(conn) == 0) > > continue; > > > > talloc_increase_ref_count(conn); > > - if (FD_ISSET(conn->fd, &outset)) > > + if (conn->pollfd && > > + !(conn->pollfd->revents & > > ~(POLLIN|POLLOUT|POLLPRI)) && > > + (conn->pollfd->revents & POLLOUT)) > > handle_output(conn); > > if (talloc_free(conn) == 0) > > continue; > > + > > + conn->pollfd = NULL; > > } > > } > > > > - max = initialize_set(&inset, &outset, *sock, *ro_sock, > > - &timeout); > > + initialize_fds(*sock, &sock_pollfd, *ro_sock, &ro_sock_pollfd, > > + &timeout); > > } > > } > > > > diff --git a/tools/xenstore/xenstored_core.h > > b/tools/xenstore/xenstored_core.h > > index 492ca0d..f330a87 100644 > > --- a/tools/xenstore/xenstored_core.h > > +++ b/tools/xenstore/xenstored_core.h > > @@ -60,6 +60,8 @@ struct connection > > > > /* The file descriptor we came in on. */ > > int fd; > > + /* The pollfd corresponding to fd. */ > > + struct pollfd *pollfd; > > > > /* Who am I? 0 for socket connections. */ > > unsigned int id; > > > > > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |