Subject: [PATCH] Do not use signals in posix-aio The signal-select race forces us to use a file descriptor for posix-aio notification. Currently, we use a pipe and write to it from the signal handler because normal posix-aio does not provide file descriptor notification support. Since we now emulation posix-aio on our own, we can clean things up and just use a file descriptor for notification. N.B. This is almost certainly going to cause regressions until we fix the select loop to run in a separate thread since there will no longer be a signal that breaks us out of the TCG run loop. We need to hold off on applying this patch until that is fixed properly. Signed-off-by: Anthony Liguori diff --git a/block-raw-posix.c b/block-raw-posix.c index 4404eb1..cae4408 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -511,20 +511,11 @@ static int posix_aio_flush(void *opaque) static PosixAioState *posix_aio_state; -static void aio_signal_handler(int signum) -{ - if (posix_aio_state) { - char byte = 0; - - write(posix_aio_state->wfd, &byte, sizeof(byte)); - } - - qemu_service_io(); -} +/* FIXME need to fix the select() loop issue b/c this IO will not + * necessarily break out us out the TCG loop */ static int posix_aio_init(void) { - struct sigaction act; PosixAioState *s; int fds[2]; struct qemu_paioinit ai; @@ -536,11 +527,6 @@ static int posix_aio_init(void) if (s == NULL) return -ENOMEM; - sigfillset(&act.sa_mask); - act.sa_flags = 0; /* do not restart syscalls to interrupt select() */ - act.sa_handler = aio_signal_handler; - sigaction(SIGUSR2, &act, NULL); - s->first_aio = NULL; if (pipe(fds) == -1) { fprintf(stderr, "failed to create pipe\n"); @@ -579,7 +565,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs, if (!acb) return NULL; acb->aiocb.aio_fildes = s->fd; - acb->aiocb.ev_signo = SIGUSR2; + acb->aiocb.ev_fd = posix_aio_state->wfd; acb->aiocb.aio_buf = buf; if (nb_sectors < 0) acb->aiocb.aio_nbytes = -nb_sectors; diff --git a/posix-aio-compat.c b/posix-aio-compat.c index f141cd9..4409899 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -27,6 +27,15 @@ static int cur_threads = 0; static int idle_threads = 0; static TAILQ_HEAD(, qemu_paiocb) request_list; +static void signal_fd(int fd) +{ + ssize_t len; + do { + char value = 1; + len = write(fd, &value, 1); + } while (len == -1 && errno == EINTR); +} + static void *aio_thread(void *unused) { sigset_t set; @@ -92,9 +101,8 @@ static void *aio_thread(void *unused) pthread_mutex_lock(&lock); aiocb->ret = offset; idle_threads++; + signal_fd(aiocb->ev_fd); pthread_mutex_unlock(&lock); - - kill(getpid(), aiocb->ev_signo); } idle_threads--; diff --git a/posix-aio-compat.h b/posix-aio-compat.h index 0bc10f5..ec17bb6 100644 --- a/posix-aio-compat.h +++ b/posix-aio-compat.h @@ -29,7 +29,7 @@ struct qemu_paiocb int aio_fildes; void *aio_buf; size_t aio_nbytes; - int ev_signo; + int ev_fd; off_t aio_offset; /* private */