On Tue, Jan 02, 2024 at 09:11:07PM +0300, Vitaliy Makkoveev wrote: > ifq_task_mtx initialized with IPL_NET priority, so this sequence > started this. > > THR1 mtx_enter(&ifq->ifq_task_mtx) > THR2 splnet() /* hv_wait(), just before hv_intr() */ > THR1 mtx_leave(&ifq->ifq_task_mtx) > THR1 `-> Xspllower() > THR1 skip > THR1 `-> hv_intr() > > IMHO the spl*() protection in the network stack doesn???t work as > expected.
I would say it works exactly as I expect. Xresume_hyperv_upcall is registered in amd64/intr.c with IPL_NET. #if NHYPERV > 0 isp = malloc(sizeof (struct intrsource), M_DEVBUF, M_NOWAIT|M_ZERO); if (isp == NULL) panic("can't allocate fixed interrupt source"); isp->is_recurse = Xrecurse_hyperv_upcall; isp->is_resume = Xresume_hyperv_upcall; fake_hyperv_intrhand.ih_level = IPL_NET; isp->is_handlers = &fake_hyperv_intrhand; isp->is_pic = &local_pic; ci->ci_isources[LIR_HYPERV] = isp; #endif mtx_leave(&ifq->ifq_task_mtx) reduces the SPL level below SPL_NET. So this code in spllower() jumps directly into Xrecurse_hyperv_upcall. 2: bsrq %rax,%rax btrq %rax,CPUVAR(IPENDING) movq CPUVAR(ISOURCES)(,%rax,8),%rax movq IS_RECURSE(%rax),%rax jmp retpoline_rax END(Xspllower) Xrecurse_hyperv_upcall jumps to Xresume_hyperv_upcall which calls hv_intr, no hv_wait() involved.