From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KnL1A-0005Mg-EC for qemu-devel@nongnu.org; Tue, 07 Oct 2008 18:27:00 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KnL17-0005Jk-Kj for qemu-devel@nongnu.org; Tue, 07 Oct 2008 18:26:59 -0400 Received: from [199.232.76.173] (port=55694 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KnL17-0005JY-Dd for qemu-devel@nongnu.org; Tue, 07 Oct 2008 18:26:57 -0400 Received: from e38.co.us.ibm.com ([32.97.110.159]:40188) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KnL16-0005IK-VP for qemu-devel@nongnu.org; Tue, 07 Oct 2008 18:26:57 -0400 Received: from d03relay02.boulder.ibm.com (d03relay02.boulder.ibm.com [9.17.195.227]) by e38.co.us.ibm.com (8.13.1/8.13.1) with ESMTP id m97MOrXW021477 for ; Tue, 7 Oct 2008 16:24:53 -0600 Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by d03relay02.boulder.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id m97MPNDs224416 for ; Tue, 7 Oct 2008 16:25:23 -0600 Received: from d03av03.boulder.ibm.com (loopback [127.0.0.1]) by d03av03.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m97MPMY8023387 for ; Tue, 7 Oct 2008 16:25:23 -0600 Message-ID: <48EBE1D0.2050002@us.ibm.com> Date: Tue, 07 Oct 2008 17:25:20 -0500 From: Anthony Liguori MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------010909000403010102060400" Subject: [Qemu-devel] [PATCH][RFT] Fix the regression with SPARC emulation Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Blue Swirl , Aurelien Jarno , "qemu-devel@nongnu.org" This is a multi-part message in MIME format. --------------010909000403010102060400 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit The attached patch should be the proper fix for the sparc performance regression. Unfortunately, this means abandoning signalfd() in favor of the signal handler/pipe trick but I don't see another solution to the problem. Please test and let me know if this works for all of your cases (it did for me with -clock unix and -clock dynticks). Regards, Anthony Liguori --------------010909000403010102060400 Content-Type: text/x-patch; name="sigio-fix.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sigio-fix.patch" commit d3e13a91224d167652288ba98de15658a233d60e Author: Anthony Liguori Date: Tue Oct 7 17:21:38 2008 -0500 Replace signalfd with signal handler/pipe. There is no way to interrupt the CPU execution loop when a file descriptor becomes readable. This results in a large performance regression in sparc emulation during bootup. This patch switches us to signal handler/pipe which was originally suggested by Ian Jackson. The signal handler lets us interrupt the CPU emulation loop while the write to a pipe lets us avoid the select/signal race condition. Signed-off-by: Anthony Liguori diff --git a/compatfd.c b/compatfd.c deleted file mode 100644 index cc5ced3..0000000 --- a/compatfd.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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; - } - - 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) - return ret; -#endif - - return qemu_signalfd_compat(mask); -} - -int qemu_eventfd(int *fds) -{ -#if defined(CONFIG_eventfd) - int ret; - - ret = syscall(SYS_eventfd, 0); - if (ret >= 0) { - fds[0] = fds[1] = ret; - return 0; - } -#endif - - return pipe(fds); -} diff --git a/compatfd.h b/compatfd.h deleted file mode 100644 index 55a111a..0000000 --- a/compatfd.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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; - uint8_t pad[124]; -}; - -int qemu_signalfd(const sigset_t *mask); - -int qemu_eventfd(int *fds); - -#endif --------------010909000403010102060400--