From patchwork Fri Jun 17 09:25:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 100776 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 70E24B6F65 for ; Fri, 17 Jun 2011 19:29:10 +1000 (EST) Received: from localhost ([::1]:52268 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QXVMQ-0007ln-D2 for incoming@patchwork.ozlabs.org; Fri, 17 Jun 2011 05:29:06 -0400 Received: from eggs.gnu.org ([140.186.70.92]:52384) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QXVJU-0007lI-U3 for qemu-devel@nongnu.org; Fri, 17 Jun 2011 05:26:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QXVJS-0004fb-IJ for qemu-devel@nongnu.org; Fri, 17 Jun 2011 05:26:04 -0400 Received: from thoth.sbs.de ([192.35.17.2]:27671) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QXVJR-0004f9-WA for qemu-devel@nongnu.org; Fri, 17 Jun 2011 05:26:02 -0400 Received: from mail1.siemens.de (localhost [127.0.0.1]) by thoth.sbs.de (8.13.6/8.13.6) with ESMTP id p5H9PoNn024139; Fri, 17 Jun 2011 11:25:50 +0200 Received: from mchn199C.mchp.siemens.de ([139.25.109.49]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p5H9PnVo028583; Fri, 17 Jun 2011 11:25:49 +0200 Message-ID: <4DFB1D9D.7060108@siemens.com> Date: Fri, 17 Jun 2011 11:25:49 +0200 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: qemu-devel , Anthony Liguori References: <4DF9CD7E.5020509@siemens.com> In-Reply-To: <4DF9CD7E.5020509@siemens.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 192.35.17.2 Cc: Paolo Bonzini , Sasha Levin , kvm , Richard Henderson Subject: [Qemu-devel] [PATCH v2] Register Linux dyntick timer as per-thread signal X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Derived from kvm-tool patch http://thread.gmane.org/gmane.comp.emulators.kvm.devel/74309 Ingo Molnar pointed out that sending the timer signal to the whole process, just blocking it everywhere, is suboptimal with an increasing number of threads. QEMU is also using this pattern so far. Linux provides a (non-portable) way to restrict the signal to a single thread: We can use SIGEV_THREAD_ID unless we are forced to emulate signalfd via an additional thread. That case could theoretically be optimized as well, but it doesn't look worth bothering. Signed-off-by: Jan Kiszka Reviewed-by: Richard Henderson --- Changes in v2: - refactored dynticks_start_timer changes as suggested by Richard Henderson - added reference to original kvm-tool patch compatfd.c | 11 +++++++++++ compatfd.h | 1 + qemu-timer.c | 8 ++++++++ 3 files changed, 20 insertions(+), 0 deletions(-) diff --git a/compatfd.c b/compatfd.c index 41586ce..31654c6 100644 --- a/compatfd.c +++ b/compatfd.c @@ -115,3 +115,14 @@ int qemu_signalfd(const sigset_t *mask) return qemu_signalfd_compat(mask); } + +bool qemu_signalfd_available(void) +{ +#ifdef CONFIG_SIGNALFD + errno = 0; + syscall(SYS_signalfd, -1, NULL, _NSIG / 8); + return errno != ENOSYS; +#else + return false; +#endif +} diff --git a/compatfd.h b/compatfd.h index fc37915..6b04877 100644 --- a/compatfd.h +++ b/compatfd.h @@ -39,5 +39,6 @@ struct qemu_signalfd_siginfo { }; int qemu_signalfd(const sigset_t *mask); +bool qemu_signalfd_available(void); #endif diff --git a/qemu-timer.c b/qemu-timer.c index 72066c7..743cf96 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -803,6 +803,8 @@ static int64_t qemu_next_alarm_deadline(void) #if defined(__linux__) +#include "compatfd.h" + static int dynticks_start_timer(struct qemu_alarm_timer *t) { struct sigevent ev; @@ -822,6 +824,12 @@ static int dynticks_start_timer(struct qemu_alarm_timer *t) memset(&ev, 0, sizeof(ev)); ev.sigev_value.sival_int = 0; ev.sigev_notify = SIGEV_SIGNAL; +#ifdef SIGEV_THREAD_ID + if (qemu_signalfd_available()) { + ev.sigev_notify = SIGEV_THREAD_ID; + ev._sigev_un._tid = qemu_get_thread_id(); + } +#endif /* SIGEV_THREAD_ID */ ev.sigev_signo = SIGALRM; if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {