From e76d2ad39d255dbd48399fe9b26b0b636d12b536 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 6 Apr 2015 20:52:28 +0800 Subject: [PATCH] clock: Piggyback passive IPIQ processing Passive IPIs will be flushed by the target CPU at clock interrupt. But we _never_ completely conform to the passive IPI description. Before we implemented LAPIC interrupt timer, systimers on non-CPU0 were actually IPIQ processing, which processed the passive IPIs; however, passive IPIQ processing on CPU0 didn't conform to the passive IPIs description. After the introduction of LAPIC interrupt timer, none of the systimers were related to IPIQ processing, thus passive IPIQ processing no longer conformed to the passive IPI description at all. As of this commit we piggyback passive IPIQ processing in doreti after hardclock(), which matches the passive IPI description. * NOTE: - We don't piggypack passive IPIQ processing directly in hardclock() to avoid introducing extra jitters to system time. - We choose not to check passive IPIQ in systimer_intr(), since systimer rate could be pretty high, e.g. rate set by polling(4). With-feedback-from: dillon@ --- sys/kern/kern_clock.c | 7 ++++++- sys/sys/thread2.h | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 552877f01d..040de78cf2 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -396,12 +396,17 @@ set_timeofday(struct timespec *ts) * manipulate objects owned by the current cpu. */ static void -hardclock(systimer_t info, int in_ipi __unused, struct intrframe *frame) +hardclock(systimer_t info, int in_ipi, struct intrframe *frame) { sysclock_t cputicks; struct proc *p; struct globaldata *gd = mycpu; + if ((gd->gd_reqflags & RQF_IPIQ) == 0 && lwkt_need_ipiq_process(gd)) { + /* Defer to doreti on passive IPIQ processing */ + need_ipiq(); + } + /* * Realtime updates are per-cpu. Note that timer corrections as * returned by microtime() and friends make an additional adjustment diff --git a/sys/sys/thread2.h b/sys/sys/thread2.h index 9c99d0a60d..5403de9bdc 100644 --- a/sys/sys/thread2.h +++ b/sys/sys/thread2.h @@ -350,6 +350,18 @@ lwkt_send_ipiq2_bycpu(int dcpu, ipifunc2_t func, void *arg1, int arg2) return(lwkt_send_ipiq3_bycpu(dcpu, (ipifunc3_t)func, arg1, arg2)); } +static __inline int +lwkt_need_ipiq_process(globaldata_t gd) +{ + lwkt_ipiq_t ipiq; + + if (CPUMASK_TESTNZERO(gd->gd_ipimask)) + return 1; + + ipiq = &gd->gd_cpusyncq; + return (ipiq->ip_rindex != ipiq->ip_windex); +} + #endif /* _KERNEL */ #endif /* _SYS_THREAD2_H_ */ -- 2.11.4.GIT