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.

Reply via email to