qemu-kvm: Switch POSIX compat AIO implementation to upstream
PATCH 1/1 qemu-kvm: Switch POSIX compat AIO implementation to upstream
Upstream's version is about to be signal-free and will stop handling SIGUSR2 specially. So it's time to adopt its implementation, ie. switch from signalfd to a pipe.
---
This should help pulling upstream into qemu-kvm when "block: avoid SIGUSR2" is merged. And will help merging further cleanups of this code I'm working on.
posix-aio-compat.c | 73 ++++++++++++++++++++++----------------------------- 1 files changed, 32 insertions(+), 41 deletions(-)
posix-aio-compat.c +32 -41
@@ -27,7 +27,6 @@#include "qemu-common.h" #include "trace.h" #include "block_int.h" -#include "compatfd.h" #include "block/raw-posix-aio.h"
@@ -43,7 +42,6 @@ struct qemu_paiocb {int aio_niov;size_t aio_nbytes;#define aio_ioctl_cmd aio_nbytes/* for QEMU_AIO_IOCTL */ -int ev_signo;off_t aio_offset;QTAILQ_ENTRY (qemu_paiocb) node;
@@ -54,7 +52,7 @@ struct qemu_paiocb { };typedef struct PosixAioState { -int fd; +int rfd, wfd;struct qemu_paiocb *first_aio; }PosixAioState ;
@@ -310,12 +308,10 @@ static ssize_t handle_aiocb_rw(struct qemu_paiocb *aiocb)return nbytes; } +static void posix_aio_notify_event (void ); +static void *aio_thread (void *unused) { -pid_t pid; - - pid =getpid (); -mutex_lock (&lock); pending_threads--;mutex_unlock (&lock);
@@ -382,7 +378,7 @@ static void *aio_thread(void *unused) aiocb->ret = ret;mutex_unlock (&lock); -if (kill (pid, aiocb->ev_signo))die ("kill failed" ); +posix_aio_notify_event (); } cur_threads--;
@@ -524,29 +520,18 @@ static int posix_aio_process_queue(void *opaque)static void posix_aio_read (void *opaque) {PosixAioState *s = opaque; -union { -struct qemu_signalfd_siginfo siginfo; -char buf[128 ]; - } sig; -size_t offset; +ssize_t len; -/* try to read from signalfd, don't freak out if we can't read anything */ - offset =0 ; -while (offset <128 ) { -ssize_t len; +/* read all bytes from signal pipe */ +for (;;) { +char bytes[16 ]; - len =read (s->fd, sig.buf + offset,128 - offset); + len =read (s->rfd, bytes,sizeof (bytes));if (len ==-1 && errno ==EINTR ) -continue ; -if (len ==-1 && errno ==EAGAIN ) { -/* there is no natural reason for this to happen, -* so we'll spin hard until we get everything just -* to be on the safe side. */ -if (offset >0 ) -continue ; - } - - offset += len; +continue ;/* try again */ +if (len ==sizeof (bytes)) +continue ;/* more to read */ +break ; }posix_aio_process_queue (s);
@@ -560,6 +545,16 @@ static int posix_aio_flush(void *opaque)static PosixAioState *posix_aio_state; +static void posix_aio_notify_event (void ) +{ +char byte =0 ; +ssize_t ret; + + ret =write (posix_aio_state->wfd, &byte,sizeof (byte)); +if (ret <0 && errno !=EAGAIN ) +die ("write()" ); +} +static void paio_remove (struct qemu_paiocb *acb) {struct qemu_paiocb **pacb;
@@ -621,7 +616,6 @@ BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,return NULL ; acb->aio_type = type; acb->aio_fildes = fd; - acb->ev_signo =SIGUSR2 ;if (qiov) { acb->aio_iov = qiov->iov;
@@ -649,7 +643,6 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,return NULL ; acb->aio_type =QEMU_AIO_IOCTL ; acb->aio_fildes = fd; - acb->ev_signo =SIGUSR2 ; acb->aio_offset =0 ; acb->aio_ioctl_buf = buf; acb->aio_ioctl_cmd = req;
@@ -663,8 +656,8 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd,int paio_init (void ) { -sigset_t mask;PosixAioState *s; +int fds[2 ];int ret;if (posix_aio_state)
@@ -672,21 +665,19 @@ int paio_init(void) s =g_malloc (sizeof (PosixAioState)); -/* Make sure to block AIO signal */ -sigemptyset (&mask); -sigaddset (&mask,SIGUSR2 ); -sigprocmask (SIG_BLOCK , &mask,NULL ); - s->first_aio =NULL ; - s->fd =qemu_signalfd (&mask); -if (s->fd ==-1 ) { -fprintf (stderr,"failed to create signalfd\n" ); +if (qemu_pipe (fds) ==-1 ) { +fprintf (stderr,"failed to create pipe\n" );return -1 ; } -fcntl (s->fd,F_SETFL ,O_NONBLOCK ); + s->rfd = fds[0 ]; + s->wfd = fds[1 ]; + +fcntl (s->rfd,F_SETFL ,O_NONBLOCK ); +fcntl (s->wfd,F_SETFL ,O_NONBLOCK ); -qemu_aio_set_fd_handler (s->fd, posix_aio_read,NULL , posix_aio_flush, +qemu_aio_set_fd_handler (s->rfd, posix_aio_read,NULL , posix_aio_flush, posix_aio_process_queue, s); ret =pthread_attr_init (&attr);
Signature · 1 line
1.7.3.4
Quoted 5 lines · Jan Kiszka
Upstream's version is about to be signal-free and will stop handling SIGUSR2 specially. So it's time to adopt its implementation, ie. switch from signalfd to a pipe.
Signed-off-by Jan Kiszka <[email protected]>
Quoted 8 lines
---
This should help pulling upstream into qemu-kvm when "block: avoid SIGUSR2" is merged. And will help merging further cleanups of this code I'm working on.
posix-aio-compat.c | 73 ++++++++++++++++++++++----------------------------- 1 files changed, 32 insertions(+), 41 deletions(-)
Perhaps qemu_eventfd() can be used in the future instead of an explicit pipe. Then Linux will do eventfd while other OSes will fall back to pipes.
Stefan
Quoted 12 lines · Stefan Hajnoczi
Quoted 11 lines · Jan Kiszka
Upstream's version is about to be signal-free and will stop handling SIGUSR2 specially. So it's time to adopt its implementation, ie. switch from signalfd to a pipe.
Signed-off-by Jan Kiszka <[email protected]>---
This should help pulling upstream into qemu-kvm when "block: avoid SIGUSR2" is merged. And will help merging further cleanups of this code I'm working on.
Quoted 8 lines
Quoted 2 lines
posix-aio-compat.c | 73 ++++++++++++++++++++++----------------------------- 1 files changed, 32 insertions(+), 41 deletions(-)Reviewed-by Stefan Hajnoczi <[email protected]>Perhaps
qemu_eventfd()can be used in the future instead of an explicit pipe. Then Linux will do eventfd while other OSes will fall back to pipes.
Basically simpler code, or does this also have runtime benefits?
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Quoted 7 lines · Jan Kiszka
Quoted 4 lines
Perhaps
qemu_eventfd()can be used in the future instead of an explicit pipe. Then Linux will do eventfd while other OSes will fall back to pipes.Basically simpler code, or does this also have runtime benefits?
In corner cases, the completion can block on the write() with pipes, but not eventfd.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 11 lines · Avi Kivity
Quoted 7 lines · Jan Kiszka
Quoted 4 lines
Perhaps
qemu_eventfd()can be used in the future instead of an explicit pipe. Then Linux will do eventfd while other OSes will fall back to pipes.Basically simpler code, or does this also have runtime benefits?
In corner cases, the completion can block on the
write()with pipes, but not eventfd.
The pipe is O_NONBLOCK and the only thing the caller cares about is whether there is *some* data in the PIPE so it can happily ignore EAGAIN.
So the pipe implementation never blocks on write() either. It may require multiple reads to drain the queue though whereas eventfd would only require a single read to drain the queue.
Regards,
Anthony Liguori
Quoted 1 line
Quoted 11 lines · Anthony Liguori
Quoted 10 lines · Avi Kivity
Quoted 8 lines · Jan Kiszka
Quoted 2 lines
Perhaps
qemu_eventfd()can be used in the future instead of anexplicit
Quoted 2 lines
pipe. Then Linux will do eventfd while other OSes will fall back to pipes.
Basically simpler code, or does this also have runtime benefits?
Quoted 7 lines
Quoted 2 lines
In corner cases, the completion can block on the
write()with pipes, but not eventfd.The pipe is
O_NONBLOCKand the only thing the caller cares about is whether there is *some* data in the PIPE so it can happily ignore EAGAIN.So the pipe implementation never blocks on
write()either. It may require multiple reads to drain the queue though whereas eventfd would only require a single read to drain the queue.
Oh, so switching to eventfd won't change much. Still nice though IMO.
Signature · 1 line
error compiling committee.c: too many arguments to function
PATCH 1/1 Use qemu_eventfd for POSIX AIO
Move qemu_eventfd unmodified to oslib-posix and use it for signaling POSIX AIO completions. If native eventfd suport is available, this avoids multiple read accesses to drain multiple pending signals. As before we use a pipe if eventfd is not supported.
--- os-posix.c | 32 -------------------------------- oslib-posix.c | 32 +++++++++++++++++++++++++++++++- posix-aio-compat.c | 12 ++++++++---- 3 files changed, 39 insertions(+), 37 deletions(-)
os-posix.c +0 -32
@@ -45,10 +45,6 @@#include <sys/syscall.h> #endif -#ifdef CONFIG_EVENTFD -#include <sys/eventfd.h> -#endif -static struct passwd *user_pwd;static const char *chroot_dir;static int daemonize;
@@ -333,34 +329,6 @@ void os_set_line_buffering(void)setvbuf (stdout,NULL , _IOLBF,0 ); } -/* -* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. -*/ -int qemu_eventfd (int fds[2 ]) -{ -#ifdef CONFIG_EVENTFD -int ret; - - ret =eventfd (0 ,0 ); -if (ret >=0 ) { - fds[0 ] = ret; -qemu_set_cloexec (ret); -if ((fds[1 ] =dup (ret)) ==-1 ) { -close (ret); -return -1 ; - } -qemu_set_cloexec (fds[1 ]); -return 0 ; - } - -if (errno !=ENOSYS ) { -return -1 ; - } -#endif - -return qemu_pipe (fds); -} -int qemu_create_pidfile (const char *filename) {char buffer[128 ];
oslib-posix.c +31 -1
@@ -47,7 +47,9 @@ extern int daemon(int, int);#include "trace.h" #include "qemu_socket.h" - +#ifdef CONFIG_EVENTFD +#include <sys/eventfd.h> +#endif int qemu_daemon (int nochdir,int noclose) {
@@ -139,6 +141,34 @@ int qemu_pipe(int pipefd[2])return ret; } +/* +* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. +*/ +int qemu_eventfd (int fds[2 ]) +{ +#ifdef CONFIG_EVENTFD +int ret; + + ret =eventfd (0 ,0 ); +if (ret >=0 ) { + fds[0 ] = ret; +qemu_set_cloexec (ret); +if ((fds[1 ] =dup (ret)) ==-1 ) { +close (ret); +return -1 ; + } +qemu_set_cloexec (fds[1 ]); +return 0 ; + } + +if (errno !=ENOSYS ) { +return -1 ; + } +#endif + +return qemu_pipe (fds); +} +int qemu_utimensat (int dirfd,const char *path,const struct timespec *times,int flags) {
posix-aio-compat.c +8 -4
@@ -521,7 +521,7 @@ static void posix_aio_read(void *opaque)PosixAioState *s = opaque;ssize_t len; -/* read all bytes from signal pipe */ +/* read all bytes from eventfd or signal pipe */ for (;;) {char bytes[16 ];
@@ -546,10 +546,14 @@ static PosixAioState *posix_aio_state;static void posix_aio_notify_event (void ) { -char byte =0 ; +/* Write 8 bytes to be compatible with eventfd. */ +static const uint64_t val =1 ;ssize_t ret; - ret =write (posix_aio_state->wfd, &byte,sizeof (byte)); +do { + ret =write (posix_aio_state->wfd, &val,sizeof (val)); + }while (ret <0 && errno ==EINTR ); +if (ret <0 && errno !=EAGAIN )die ("write()" ); }
@@ -665,7 +669,7 @@ int paio_init(void) s =g_malloc (sizeof (PosixAioState)); s->first_aio =NULL ; -if (qemu_pipe (fds) ==-1 ) { +if (qemu_eventfd (fds) ==-1 ) {fprintf (stderr,"failed to create pipe\n" );return -1 ; }
Signature · 1 line
1.7.3.4
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 99 lines · Jan Kiszka
Move
qemu_eventfdunmodified to oslib-posix and use it for signaling POSIX AIO completions. If native eventfd suport is available, this avoids multiple read accesses to drain multiple pending signals. As before we use a pipe if eventfd is not supported.Signed-off-by Jan Kiszka<[email protected]>--- os-posix.c | 32 -------------------------------- oslib-posix.c | 32 +++++++++++++++++++++++++++++++- posix-aio-compat.c | 12 ++++++++---- 3 files changed, 39 insertions(+), 37 deletions(-)os-posix.c +0
-32@@ -45,10 +45,6 @@#include <sys/syscall.h> #endif -#ifdef CONFIG_EVENTFD -#include <sys/eventfd.h> -#endif -static struct passwd *user_pwd;static const char *chroot_dir;static int daemonize;@@ -333,34 +329,6 @@ void os_set_line_buffering(void)setvbuf (stdout,NULL , _IOLBF,0 ); } -/* -* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. -*/ -int qemu_eventfd (int fds[2 ]) -{ -#ifdef CONFIG_EVENTFD -int ret; - - ret =eventfd (0 ,0 ); -if (ret>=0 ) { - fds[0 ] = ret; -qemu_set_cloexec (ret); -if ((fds[1 ] =dup (ret)) ==-1 ) { -close (ret); -return -1 ; - } -qemu_set_cloexec (fds[1 ]); -return 0 ; - } - -if (errno !=ENOSYS ) { -return -1 ; - } -#endif - -return qemu_pipe (fds); -} -int qemu_create_pidfile (const char *filename) {char buffer[128 ];oslib-posix.c +21
-1@@ -47,7 +47,9 @@ extern int daemon(int, int);#include "trace.h" #include "qemu_socket.h" - +#ifdef CONFIG_EVENTFD +#include <sys/eventfd.h> +#endif int qemu_daemon (int nochdir,int noclose) {@@ -139,6 +141,34 @@ int qemu_pipe(int pipefd[2])return ret; } +/* +* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. +*/ +int qemu_eventfd (int fds[2 ]) +{ +#ifdef CONFIG_EVENTFD +int ret; + + ret =eventfd (0 ,0 ); +if (ret>=0 ) { + fds[0 ] = ret; +qemu_set_cloexec (ret); +if ((fds[1 ] =dup (ret)) ==-1 ) { +close (ret); +return -1 ; + } +qemu_set_cloexec (fds[1 ]); +return 0 ;
oslib-posix.c int qemu_pipe(int pipefd[2]) · line 171
Quoted 10 lines
oslib-posix.c +10
-0+ } + +if (errno !=ENOSYS ) { +return -1 ; + } +#endif + +return qemu_pipe (fds); +} +
I think it's a bit dangerous to implement eventfd() in terms of pipe().
You don't expect to handle EAGAIN with eventfd() whereas you have to handle it with pipe().
Moreover, the eventfd() counter is not lossy (practically speaking) whereas if you use pipe() as a counter, it will be lossy in practice.
This is why posix aio uses pipe() and not eventfd().
Regards,
Anthony Liguori
Quoted 42 lines
oslib-posix.c +0
-0int qemu_utimensat (int dirfd,const char *path,const struct timespec *times,int flags) {posix-aio-compat.c +8
-4@@ -521,7 +521,7 @@ static void posix_aio_read(void *opaque)PosixAioState *s = opaque;ssize_t len; -/* read all bytes from signal pipe */ +/* read all bytes from eventfd or signal pipe */ for (;;) {char bytes[16 ];@@ -546,10 +546,14 @@ static PosixAioState *posix_aio_state;static void posix_aio_notify_event (void ) { -char byte =0 ; +/* Write 8 bytes to be compatible with eventfd. */ +static const uint64_t val =1 ;ssize_t ret; - ret =write (posix_aio_state->wfd,&byte,sizeof (byte)); +do { + ret =write (posix_aio_state->wfd,&val,sizeof (val)); + }while (ret<0 && errno ==EINTR ); +if (ret<0 && errno !=EAGAIN )die ("write()" ); }@@ -665,7 +669,7 @@ int paio_init(void) s =g_malloc (sizeof (PosixAioState)); s->first_aio =NULL ; -if (qemu_pipe (fds) ==-1 ) { +if (qemu_eventfd (fds) ==-1 ) {fprintf (stderr,"failed to create pipe\n" );return -1 ; }
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 6 lines · Anthony Liguori
You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().
We could define a qemu_event mechanism that satisfies the least common denominator, and is implemented by eventfd when available.
qemu_event_create()qemu_event_signal()qemu_event_wait()qemu_event_poll_add() // registers in main loopqemu_event_poll_del()
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 10 lines · Avi Kivity
Quoted 8 lines · Anthony Liguori
You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().
Quoted 8 lines
We could define a
qemu_eventmechanism that satisfies the least common denominator, and is implemented by eventfd when available.
qemu_event_create()qemu_event_signal()qemu_event_wait()qemu_event_poll_add()// registers in main loopqemu_event_poll_del()
See hw/event_notifier.[ch].
Regards,
Anthony Liguori
Quoted 1 line
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 8 lines · Anthony Liguori
Quoted 5 lines
qemu_event_create()qemu_event_signal()qemu_event_wait()qemu_event_poll_add()// registers in main loopqemu_event_poll_del()See hw/event_notifier.[ch].
Precisely.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
In reply to Anthony LiguoriQuoted 14 lines · Anthony Liguori
Quoted 13 lines · Avi Kivity
Quoted 8 lines · Anthony Liguori
You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().We could define a
qemu_eventmechanism that satisfies the least common denominator, and is implemented by eventfd when available.
Quoted 7 lines
Quoted 5 lines
qemu_event_create()qemu_event_signal()qemu_event_wait()qemu_event_poll_add()// registers in main loopqemu_event_poll_del()See hw/event_notifier.[ch].
That code looks suspicious, btw. It claims things ("we use EFD_SEMAPHORE") it does not do.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 21 lines · Jan Kiszka
Quoted 20 lines · Anthony Liguori
Quoted 18 lines · Avi Kivity
Quoted 8 lines · Anthony Liguori
You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().We could define a
qemu_eventmechanism that satisfies the least common denominator, and is implemented by eventfd when available.
qemu_event_create()qemu_event_signal()qemu_event_wait()qemu_event_poll_add()// registers in main loopqemu_event_poll_del()
Quoted 4 lines
Quoted 1 line
See hw/event_notifier.[ch].
That code looks suspicious, btw. It claims things ("we use
EFD_SEMAPHORE") it does not do.
Indeed.
But the interface appears to be the right one IMHO.
Regards,
Anthony Liguori
Quoted 3 lines
Jan
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
In reply to Anthony LiguoriQuoted 113 lines · Anthony Liguori
Quoted 99 lines · Jan Kiszka
Move
qemu_eventfdunmodified to oslib-posix and use it for signaling POSIX AIO completions. If native eventfd suport is available, this avoids multiple read accesses to drain multiple pending signals. As before we use a pipe if eventfd is not supported.Signed-off-by Jan Kiszka<[email protected]>--- os-posix.c | 32 -------------------------------- oslib-posix.c | 32 +++++++++++++++++++++++++++++++- posix-aio-compat.c | 12 ++++++++---- 3 files changed, 39 insertions(+), 37 deletions(-)os-posix.c +0
-32@@ -45,10 +45,6 @@#include <sys/syscall.h> #endif -#ifdef CONFIG_EVENTFD -#include <sys/eventfd.h> -#endif -static struct passwd *user_pwd;static const char *chroot_dir;static int daemonize;@@ -333,34 +329,6 @@ void os_set_line_buffering(void)setvbuf (stdout,NULL , _IOLBF,0 ); } -/* -* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. -*/ -int qemu_eventfd (int fds[2 ]) -{ -#ifdef CONFIG_EVENTFD -int ret; - - ret =eventfd (0 ,0 ); -if (ret>=0 ) { - fds[0 ] = ret; -qemu_set_cloexec (ret); -if ((fds[1 ] =dup (ret)) ==-1 ) { -close (ret); -return -1 ; - } -qemu_set_cloexec (fds[1 ]); -return 0 ; - } - -if (errno !=ENOSYS ) { -return -1 ; - } -#endif - -return qemu_pipe (fds); -} -int qemu_create_pidfile (const char *filename) {char buffer[128 ];oslib-posix.c +21
-1@@ -47,7 +47,9 @@ extern int daemon(int, int);#include "trace.h" #include "qemu_socket.h" - +#ifdef CONFIG_EVENTFD +#include <sys/eventfd.h> +#endif int qemu_daemon (int nochdir,int noclose) {@@ -139,6 +141,34 @@ int qemu_pipe(int pipefd[2])return ret; } +/* +* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. +*/ +int qemu_eventfd (int fds[2 ]) +{ +#ifdef CONFIG_EVENTFD +int ret; + + ret =eventfd (0 ,0 ); +if (ret>=0 ) { + fds[0 ] = ret; +qemu_set_cloexec (ret); +if ((fds[1 ] =dup (ret)) ==-1 ) { +close (ret); +return -1 ; + } +qemu_set_cloexec (fds[1 ]); +return 0 ;oslib-posix.c int qemu_pipe(int pipefd[2]) · line 171
Quoted 10 lines
oslib-posix.c +10
-0+ } + +if (errno !=ENOSYS ) { +return -1 ; + } +#endif + +return qemu_pipe (fds); +} +I think it's a bit dangerous to implement
eventfd()in terms ofpipe().
Quoted 2 lines
You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().
EAGAIN is returned on eventfd read if no event is pending and the fd is non-blocking - just as we configure it.
Quoted 5 lines
Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().
I don't get this yet. eventfd is lossy by default. It only decreases the counter on read if you specify EFD_SEMAPHORE - which we do not do.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 9 lines · Jan Kiszka
Quoted 5 lines
Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().I don't get this yet. eventfd is lossy by default. It only decreases the counter on read if you specify
EFD_SEMAPHORE- which we do not do.
It's not lossy - a read returns the number of events written since the last read.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 5 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka
Quoted 4 lines
Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
This is why posix aio uses
pipe()and noteventfd().I don't get this yet. eventfd is lossy by default. It only decreases the counter on read if you specify
EFD_SEMAPHORE- which we do not do.It's not lossy - a read returns the number of events written since the last read.
Yeah, but what's the point? We don't evaluate this.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 8 lines · Jan Kiszka
Quoted 7 lines · Avi Kivity
Quoted 6 lines · Jan Kiszka
Quoted 5 lines
Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().
Quoted 10 lines
Quoted 6 lines
Quoted 3 lines
I don't get this yet. eventfd is lossy by default. It only decreases the counter on read if you specify
EFD_SEMAPHORE- which we do not do.It's not lossy - a read returns the number of events written since the last read.
Yeah, but what's the point? We don't evaluate this.
If we write an interface that looks like eventfd but subtly differs, someone will get bitten. If we write a new interface and implement it via eventfd (or a pipe), no one gets bitten.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 16 lines · Avi Kivity
Quoted 15 lines · Jan Kiszka
Quoted 13 lines · Avi Kivity
Quoted 9 lines · Jan Kiszka
Quoted 5 lines
Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().I don't get this yet. eventfd is lossy by default. It only decreases the counter on read if you specify
EFD_SEMAPHORE- which we do not do.It's not lossy - a read returns the number of events written since the last read.
Quoted 7 lines
Quoted 3 lines
Yeah, but what's the point? We don't evaluate this.
If we write an interface that looks like eventfd but subtly differs, someone will get bitten. If we write a new interface and implement it via eventfd (or a pipe), no one gets bitten.
I don't disagree that there is still room for improving the existing interface, generalizing to qemu_event. But that's not in the scope of this patch.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 4 lines · Jan Kiszka
I don't disagree that there is still room for improving the existing interface, generalizing to
qemu_event. But that's not in the scope of this patch.
Why not use event_notify.c?
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka
I don't disagree that there is still room for improving the existing interface, generalizing to
qemu_event. But that's not in the scope of this patch.Why not use
event_notify.c?
It doesn't solve the wrapping issue, it mandates eventfd support.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 11 lines · Jan Kiszka
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka
I don't disagree that there is still room for improving the existing interface, generalizing to
qemu_event. But that's not in the scope of this patch.Why not use
event_notify.c?It doesn't solve the wrapping issue, it mandates eventfd support.
We can add pipe fallbacks too (though if it was meant to use with vhost, that's not what we want).
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
Quoted 8 lines · Avi Kivity
Quoted 7 lines · Jan Kiszka
Quoted 6 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka
I don't disagree that there is still room for improving the existing interface, generalizing to
qemu_event. But that's not in the scope of this patch.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Why not use
event_notify.c?It doesn't solve the wrapping issue, it mandates eventfd support.
We can add pipe fallbacks too (though if it was meant to use with vhost, that's not what we want).
vhost cannot exist on a kernel that doesn't support eventfd so I don't think we need to worry about it.
Regards,
Anthony Liguori
Quoted 1 line
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
In reply to Avi KivityQuoted 8 lines · Avi Kivity
Quoted 7 lines · Jan Kiszka
Quoted 6 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka
I don't disagree that there is still room for improving the existing interface, generalizing to
qemu_event. But that's not in the scope of this patch.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Why not use
event_notify.c?It doesn't solve the wrapping issue, it mandates eventfd support.
We can add pipe fallbacks too (though if it was meant to use with vhost, that's not what we want).
Not a practical issue due to the dependency on much more recent vhost.
So EventNotifier will have to be migrated over a generic solution as well. Again, that's food for additional patches.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
In reply to Jan KiszkaQuoted 121 lines · Jan Kiszka
Quoted 113 lines · Anthony Liguori
Quoted 99 lines · Jan Kiszka
Move
qemu_eventfdunmodified to oslib-posix and use it for signaling POSIX AIO completions. If native eventfd suport is available, this avoids multiple read accesses to drain multiple pending signals. As before we use a pipe if eventfd is not supported.Signed-off-by Jan Kiszka<[email protected]>--- os-posix.c | 32 -------------------------------- oslib-posix.c | 32 +++++++++++++++++++++++++++++++- posix-aio-compat.c | 12 ++++++++---- 3 files changed, 39 insertions(+), 37 deletions(-)os-posix.c +0
-32@@ -45,10 +45,6 @@#include <sys/syscall.h> #endif -#ifdef CONFIG_EVENTFD -#include <sys/eventfd.h> -#endif -static struct passwd *user_pwd;static const char *chroot_dir;static int daemonize;@@ -333,34 +329,6 @@ void os_set_line_buffering(void)setvbuf (stdout,NULL , _IOLBF,0 ); } -/* -* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. -*/ -int qemu_eventfd (int fds[2 ]) -{ -#ifdef CONFIG_EVENTFD -int ret; - - ret =eventfd (0 ,0 ); -if (ret>=0 ) { - fds[0 ] = ret; -qemu_set_cloexec (ret); -if ((fds[1 ] =dup (ret)) ==-1 ) { -close (ret); -return -1 ; - } -qemu_set_cloexec (fds[1 ]); -return 0 ; - } - -if (errno !=ENOSYS ) { -return -1 ; - } -#endif - -return qemu_pipe (fds); -} -int qemu_create_pidfile (const char *filename) {char buffer[128 ];oslib-posix.c +21
-1@@ -47,7 +47,9 @@ extern int daemon(int, int);#include "trace.h" #include "qemu_socket.h" - +#ifdef CONFIG_EVENTFD +#include <sys/eventfd.h> +#endif int qemu_daemon (int nochdir,int noclose) {@@ -139,6 +141,34 @@ int qemu_pipe(int pipefd[2])return ret; } +/* +* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. +*/ +int qemu_eventfd (int fds[2 ]) +{ +#ifdef CONFIG_EVENTFD +int ret; + + ret =eventfd (0 ,0 ); +if (ret>=0 ) { + fds[0 ] = ret; +qemu_set_cloexec (ret); +if ((fds[1 ] =dup (ret)) ==-1 ) { +close (ret); +return -1 ; + } +qemu_set_cloexec (fds[1 ]); +return 0 ;oslib-posix.c int qemu_pipe(int pipefd[2]) · line 171
Quoted 10 lines
oslib-posix.c +10
-0+ } + +if (errno !=ENOSYS ) { +return -1 ; + } +#endif + +return qemu_pipe (fds); +} +I think it's a bit dangerous to implement
eventfd()in terms ofpipe().Quoted 2 lines
You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().EAGAIN is returned on eventfd read if no event is pending and the fd is non-blocking - just as we configure it.
Quoted 1 line
Quoted 7 lines
Quoted 4 lines
Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().I don't get this yet. eventfd is lossy by default. It only decreases the counter on read if you specify
EFD_SEMAPHORE- which we do not do.
uint64_t value;
for (i = 0; i < 1 << 32; i++) {
value = 1;
write(fd, &value, sizeof(value));
}
uint64_t count = 0;
do {
len = read(fd, &value, sizeof(value));
count += value;
} while (len != -1);
With eventfd, count == 2^32. With pipe, count == 8192.
That's each '1' is stored in the pipe buffer whereas with eventfd, an index is just incremented.
Not sure what you mean re: EFD_SEMAPHORE. EFD_SEMAPHORE basically means any non-zero value is returned as 1 and the counter is decremented by 1. Without EFD_SEMAPHORE, the count is returned and the counter is reset to 0.
Regards,
Anthony Liguori
Quoted 3 lines
Jan
Paolo Bonzini
maintainerRe: [Qemu-devel] [PATCH] Use qemu_eventfd for POSIX AIO
In reply to Anthony LiguoriQuoted 10 lines · Anthony Liguori
I think it's a bit dangerous to implement
eventfd()in terms ofpipe().You don't expect to handle EAGAIN with
eventfd()whereas you have to handle it withpipe().Moreover, the
eventfd()counter is not lossy (practically speaking) whereas if you usepipe()as a counter, it will be lossy in practice.This is why posix aio uses
pipe()and noteventfd().
But this is the same idiom we use for the iothread signaling. We're not using the eventfd's counter. Perhaps it would be nice to complete EventNotifier with "notify event" methods and use it, but Jan's patch is safe, I think.
Paolo
Am 20.09.2011 18:49, schrieb Jan Kiszka:
Quoted 10 lines
Upstream's version is about to be signal-free and will stop handling SIGUSR2 specially. So it's time to adopt its implementation, ie. switch from signalfd to a pipe.
Signed-off-by Jan Kiszka <[email protected]>---
This should help pulling upstream into qemu-kvm when "block: avoid SIGUSR2" is merged. And will help merging further cleanups of this code I'm working on.
Avi Kivity
AppliedQuoted 4 lines · Jan Kiszka
Upstream's version is about to be signal-free and will stop handling SIGUSR2 specially. So it's time to adopt its implementation, ie. switch from signalfd to a pipe.
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function