On Wed, Feb 20, 2013 at 11:28:23AM +0100, Stefan Hajnoczi wrote: > Amos Kong <ak...@redhat.com> reported that file descriptors numbered higher > than 1024 could crash QEMU. This is due to the fixed size of the fd_set type > used for select(2) event polling. > > This series converts the main-loop.c and aio-posix.c select(2) calls to > g_poll(3). This eliminates the fd_set type and allows QEMU to scale to high > numbers of file descriptors. > > The g_poll(3) interface is a portable version of the poll(2) system call. The > difference to select(2) is that fine-grained events (G_IO_IN, G_IO_OUT, > G_IO_HUP, G_IO_ERR, G_IO_PRI) can be monitored instead of just > read/write/exception. Also, there is no limit to the file descriptor numbers > that may be used, allowing applications to scale to many file descriptors. > See > the documentation for details: > > http://developer.gnome.org/glib/2.28/glib-The-Main-Event-Loop.html#g-poll > > The QEMU main loop works as follows today: > > 1. Call out to slirp, iohandlers, and glib sources to fill rfds/wfds/xfds with > the file descriptors to select(2). > 2. Perform the select(2) call. > 3. Call out to slirp, iohandlers, and glib sources to handle events polled in > rfds/wfds/xfds. > > The plan of attack is as follows: > > 1. Replace select(2) with g_poll(3). Use glue that converts between > rfds/wfds/xfds and GPollFD so that the unconverted QEMU components still > work. > > 2. Convert slirp, iohandlers, and glib source fill/poll functions to use > GPollFD directly instead of rfds/wfds/xfds. > > 3. Drop the glue since all components now natively use GPollFD. > > 4. Convert aio-posix.c to g_poll(3) by reusing GPollFD. > > I have tested that the series builds and is bisectable on Linux and Windows > hosts. But I have not done extensive testing on other host platforms or with > long-term guests to check for performance regressions.
Wouldn't it make sense to switch to epoll instead? poll does not scale well to a huge number of descriptors. > v4: > * Assign revents instead of bitwise OR to make code clearer [Laszlo] > * Invoke pollfds_poll() only when select(2) succeeds [Laszlo] > * Fix gpollfds_to_select(select_ret || g_poll_ret) call [Laszlo] > > v3: > * Convert slirp/slirp.c to tabs to spaces [Blue Swirl] > > v2: > * Replace custom Poller type with GArray [aliguori] > > Stefan Hajnoczi (10): > main-loop: fix select_ret uninitialized variable warning > main-loop: switch to g_poll() on POSIX hosts > main-loop: switch POSIX glib integration to GPollFD > slirp: slirp/slirp.c coding style cleanup > slirp: switch to GPollFD > iohandler: switch to GPollFD > main-loop: drop rfds/wfds/xfds for good > aio: extract aio_dispatch() from aio_poll() > aio: convert aio_poll() to g_poll(3) > aio: support G_IO_HUP and G_IO_ERR > > aio-posix.c | 130 ++++----- > async.c | 2 + > include/block/aio.h | 3 + > include/qemu/main-loop.h | 4 +- > iohandler.c | 40 ++- > main-loop.c | 158 ++++++----- > slirp/libslirp.h | 6 +- > slirp/main.h | 1 - > slirp/slirp.c | 673 > +++++++++++++++++++++++++---------------------- > slirp/socket.c | 9 - > slirp/socket.h | 2 + > stubs/slirp.c | 6 +- > 12 files changed, 547 insertions(+), 487 deletions(-) > > -- > 1.8.1.2 >