From 813b1d9f66a8b4c1d44f199ccfd197909ac5c00b Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 28 Jul 2011 16:16:29 -0700 Subject: [PATCH] vkernel - Fix lockup with [v]kernel due to missing ipiq signal * If the target ipiq has nothing but passively queued entries the target cpu will normally just process the ipi's on the next clock interrupt. However, if the originating cpu is forced to live-loop waiting for the target to the drain the target may not be aware that it needs to drain ASAP. * The fix is for the originating cpu to ensure that an ipi interrupt is sent to the target cpu before live looping. * This appears to primarily effect vkernels. Reported-by: ftigeot, tuxillo --- sys/kern/lwkt_ipiq.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/kern/lwkt_ipiq.c b/sys/kern/lwkt_ipiq.c index a4416e0100..34e206b6e1 100644 --- a/sys/kern/lwkt_ipiq.c +++ b/sys/kern/lwkt_ipiq.c @@ -179,6 +179,10 @@ lwkt_send_ipiq3(globaldata_t target, ipifunc3_t func, void *arg1, int arg2) /* * Do not allow the FIFO to become full. Interrupts must be physically * enabled while we liveloop to avoid deadlocking the APIC. + * + * The target ipiq may have gotten filled up due to passive IPIs and thus + * not be aware that its queue is too full, so be sure to issue an + * ipiq interrupt to the target cpu. */ if (ip->ip_windex - ip->ip_rindex > MAXCPUFIFO / 2) { #if defined(__i386__) @@ -193,6 +197,7 @@ lwkt_send_ipiq3(globaldata_t target, ipifunc3_t func, void *arg1, int arg2) } cpu_enable_intr(); ++ipiq_fifofull; + cpu_send_ipiq(target->gd_cpuid); DEBUG_PUSH_INFO("send_ipiq3"); while (ip->ip_windex - ip->ip_rindex > MAXCPUFIFO / 4) { KKASSERT(ip->ip_windex - ip->ip_rindex != MAXCPUFIFO - 1); @@ -286,6 +291,7 @@ lwkt_send_ipiq3_passive(globaldata_t target, ipifunc3_t func, } cpu_enable_intr(); ++ipiq_fifofull; + cpu_send_ipiq(target->gd_cpuid); DEBUG_PUSH_INFO("send_ipiq3_passive"); while (ip->ip_windex - ip->ip_rindex > MAXCPUFIFO / 4) { KKASSERT(ip->ip_windex - ip->ip_rindex != MAXCPUFIFO - 1); -- 2.41.0