From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anthony Liguori Subject: Re: [PATCH v2] Register Linux dyntick timer as per-thread signal Date: Sat, 23 Jul 2011 11:52:21 -0500 Message-ID: <4E2AFC45.1090709@us.ibm.com> References: <4DF9CD7E.5020509@siemens.com> <4DFB1D9D.7060108@siemens.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit Cc: Paolo Bonzini , Richard Henderson , qemu-devel , kvm , Sasha Levin To: Jan Kiszka Return-path: In-Reply-To: <4DFB1D9D.7060108@siemens.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org Sender: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org List-Id: kvm.vger.kernel.org On 06/17/2011 04:25 AM, Jan Kiszka wrote: > 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 Applied. Thanks. Regards, Anthony Liguori > --- > > 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)) {