Message ID | 4DF9CD7E.5020509@siemens.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
* Jan Kiszka <jan.kiszka@siemens.com> wrote: > 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 using this pattern so far. > > But Linux provides a (non-portable) way to restrict the signal to a > single thread: 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. Would be nice to mention it in the changelog that the context and motivation for my remark was a patch sent for tools/kvm/ by Asias He: kvm tools: Block SIGALRM for vcpu thread using sig_block() helper Thanks, Ingo -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 06/16/2011 02:31 AM, Jan Kiszka wrote: > ev.sigev_value.sival_int = 0; > - ev.sigev_notify = SIGEV_SIGNAL; > ev.sigev_signo = SIGALRM; > +#ifdef SIGEV_THREAD_ID > + if (qemu_signalfd_available()) { > + ev.sigev_notify = SIGEV_THREAD_ID; > + ev._sigev_un._tid = qemu_get_thread_id(); > + } else > +#endif /* SIGEV_THREAD_ID */ > + { > + ev.sigev_notify = SIGEV_SIGNAL; > + } > Rather than do the else-inside-ifdef thing, why not leave the original setting of sigev_notify where it was, and let the ifdef overwrite it? r~ -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Jan, On Thu, Jun 16, 2011 at 5:31 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote: > 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 using this pattern so far. I am not familiar with this code, but don't you already need to block SIGALRM properly in all threads for OSes != Linux ? If so, isn't this patch redundant? Alexandre -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 2011-06-16 17:24, Alexandre Raymond wrote: > Hi Jan, > > On Thu, Jun 16, 2011 at 5:31 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote: >> 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 using this pattern so far. > > I am not familiar with this code, but don't you already need to block > SIGALRM properly in all threads for OSes != Linux ? If so, isn't this > patch redundant? Yes, we still need to block for the sake of non-Linux UNIX or pre-signalfd Linux. That blocking becomes in fact redundant in the signalfd case, but that's both harmless and not worth optimizing. The key is that per-thread signals do not care about other threads having them blocked or not, they only deal with the target thread. Jan
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..09e6f17 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; @@ -821,8 +823,16 @@ 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; ev.sigev_signo = SIGALRM; +#ifdef SIGEV_THREAD_ID + if (qemu_signalfd_available()) { + ev.sigev_notify = SIGEV_THREAD_ID; + ev._sigev_un._tid = qemu_get_thread_id(); + } else +#endif /* SIGEV_THREAD_ID */ + { + ev.sigev_notify = SIGEV_SIGNAL; + } if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) { perror("timer_create");
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 using this pattern so far. But Linux provides a (non-portable) way to restrict the signal to a single thread: 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 <jan.kiszka@siemens.com> --- compatfd.c | 11 +++++++++++ compatfd.h | 1 + qemu-timer.c | 12 +++++++++++- 3 files changed, 23 insertions(+), 1 deletions(-)