From patchwork Wed Oct 20 17:43:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 68453 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A815CB70A6 for ; Thu, 21 Oct 2010 04:49:01 +1100 (EST) Received: from localhost ([127.0.0.1]:38804 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P8cmW-0002MI-Ag for incoming@patchwork.ozlabs.org; Wed, 20 Oct 2010 13:48:56 -0400 Received: from [140.186.70.92] (port=37385 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P8ciq-0000Nf-Uz for qemu-devel@nongnu.org; Wed, 20 Oct 2010 13:45:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P8cio-00065v-77 for qemu-devel@nongnu.org; Wed, 20 Oct 2010 13:45:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:61646) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P8cin-00065c-UV for qemu-devel@nongnu.org; Wed, 20 Oct 2010 13:45:06 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9KHj4KE006449 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 20 Oct 2010 13:45:04 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o9KHj4fh018909; Wed, 20 Oct 2010 13:45:04 -0400 Received: from amt.cnet (vpn-9-16.rdu.redhat.com [10.11.9.16]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o9KHj2Jr019221; Wed, 20 Oct 2010 13:45:03 -0400 Received: from amt.cnet (localhost.localdomain [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 034D36561E2; Wed, 20 Oct 2010 15:44:15 -0200 (BRST) Received: (from marcelo@localhost) by amt.cnet (8.14.4/8.14.4/Submit) id o9KHiCIW003553; Wed, 20 Oct 2010 15:44:12 -0200 From: Marcelo Tosatti To: Anthony Liguori Date: Wed, 20 Oct 2010 15:43:40 -0200 Message-Id: <649b630f2c9b78dd581893f457a395c335bca4ca.1287596626.git.mtosatti@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Marcelo Tosatti , qemu-devel@nongnu.org, kvm@vger.kernel.org, Avi Kivity Subject: [Qemu-devel] [PATCH 03/10] signalfd compatibility X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Port qemu-kvm's signalfd compat code. commit 5a7fdd0abd7cd24dac205317a4195446ab8748b5 Author: Anthony Liguori Date: Wed May 7 11:55:47 2008 -0500 Use signalfd() in io-thread This patch reworks the IO thread to use signalfd() instead of sigtimedwait() This will eliminate the need to use SIGIO everywhere. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- Makefile.objs | 1 + compatfd.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ compatfd.h | 43 +++++++++++++++++++++ configure | 18 +++++++++ 4 files changed, 179 insertions(+), 0 deletions(-) create mode 100644 compatfd.c create mode 100644 compatfd.h diff --git a/Makefile.objs b/Makefile.objs index 816194a..d73002d 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -125,6 +125,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y)) common-obj-y += iov.o acl.o common-obj-$(CONFIG_THREAD) += qemu-thread.o +common-obj-$(CONFIG_IOTHREAD) += compatfd.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o diff --git a/compatfd.c b/compatfd.c new file mode 100644 index 0000000..a7cebc4 --- /dev/null +++ b/compatfd.c @@ -0,0 +1,117 @@ +/* + * signalfd/eventfd compatibility + * + * Copyright IBM, Corp. 2008 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "compatfd.h" + +#include +#include + +struct sigfd_compat_info +{ + sigset_t mask; + int fd; +}; + +static void *sigwait_compat(void *opaque) +{ + struct sigfd_compat_info *info = opaque; + int err; + sigset_t all; + + sigfillset(&all); + sigprocmask(SIG_BLOCK, &all, NULL); + + do { + siginfo_t siginfo; + + err = sigwaitinfo(&info->mask, &siginfo); + if (err == -1 && errno == EINTR) { + err = 0; + continue; + } + + if (err > 0) { + char buffer[128]; + size_t offset = 0; + + memcpy(buffer, &err, sizeof(err)); + while (offset < sizeof(buffer)) { + ssize_t len; + + len = write(info->fd, buffer + offset, + sizeof(buffer) - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len <= 0) { + err = -1; + break; + } + + offset += len; + } + } + } while (err >= 0); + + return NULL; +} + +static int qemu_signalfd_compat(const sigset_t *mask) +{ + pthread_attr_t attr; + pthread_t tid; + struct sigfd_compat_info *info; + int fds[2]; + + info = malloc(sizeof(*info)); + if (info == NULL) { + errno = ENOMEM; + return -1; + } + + if (pipe(fds) == -1) { + free(info); + return -1; + } + + qemu_set_cloexec(fds[0]); + qemu_set_cloexec(fds[1]); + + memcpy(&info->mask, mask, sizeof(*mask)); + info->fd = fds[1]; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + pthread_create(&tid, &attr, sigwait_compat, info); + + pthread_attr_destroy(&attr); + + return fds[0]; +} + +int qemu_signalfd(const sigset_t *mask) +{ +#if defined(CONFIG_SIGNALFD) + int ret; + + ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8); + if (ret != -1) { + qemu_set_cloexec(ret); + return ret; + } +#endif + + return qemu_signalfd_compat(mask); +} diff --git a/compatfd.h b/compatfd.h new file mode 100644 index 0000000..fc37915 --- /dev/null +++ b/compatfd.h @@ -0,0 +1,43 @@ +/* + * signalfd/eventfd compatibility + * + * Copyright IBM, Corp. 2008 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_COMPATFD_H +#define QEMU_COMPATFD_H + +#include + +struct qemu_signalfd_siginfo { + uint32_t ssi_signo; /* Signal number */ + int32_t ssi_errno; /* Error number (unused) */ + int32_t ssi_code; /* Signal code */ + uint32_t ssi_pid; /* PID of sender */ + uint32_t ssi_uid; /* Real UID of sender */ + int32_t ssi_fd; /* File descriptor (SIGIO) */ + uint32_t ssi_tid; /* Kernel timer ID (POSIX timers) */ + uint32_t ssi_band; /* Band event (SIGIO) */ + uint32_t ssi_overrun; /* POSIX timer overrun count */ + uint32_t ssi_trapno; /* Trap number that caused signal */ + int32_t ssi_status; /* Exit status or signal (SIGCHLD) */ + int32_t ssi_int; /* Integer sent by sigqueue(2) */ + uint64_t ssi_ptr; /* Pointer sent by sigqueue(2) */ + uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */ + uint64_t ssi_stime; /* System CPU time consumed (SIGCHLD) */ + uint64_t ssi_addr; /* Address that generated signal + (for hardware-generated signals) */ + uint8_t pad[48]; /* Pad size to 128 bytes (allow for + additional fields in the future) */ +}; + +int qemu_signalfd(const sigset_t *mask); + +#endif diff --git a/configure b/configure index a079a49..ae8188e 100755 --- a/configure +++ b/configure @@ -1957,6 +1957,21 @@ if compile_prog "" "" ; then splice=yes fi +########################################## +# signalfd probe +signalfd="no" +cat > $TMPC << EOF +#define _GNU_SOURCE +#include +#include +#include +int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); } +EOF + +if compile_prog "" "" ; then + signalfd=yes +fi + # check if eventfd is supported eventfd=no cat > $TMPC << EOF @@ -2559,6 +2574,9 @@ fi if test "$fdt" = "yes" ; then echo "CONFIG_FDT=y" >> $config_host_mak fi +if test "$signalfd" = "yes" ; then + echo "CONFIG_SIGNALFD=y" >> $config_host_mak +fi if test "$need_offsetof" = "yes" ; then echo "CONFIG_NEED_OFFSETOF=y" >> $config_host_mak fi