Page MenuHomeFreeBSD

Fix vtnet TCP lro panic
ClosedPublic

Authored by melifaro on Apr 21 2021, 10:51 PM.

Details

Summary

vtnet tcp LRO init is done conditionally, depending on the vtnet_software_lro() return value.

In some cases it returns false, resulting in empty lro_ctl being present in the rxq.

Thus, on receipt of the first packet, kernel panics when trying to set curvnet from the lro_ctl->ifp.

#15 0xffffffff810cb49b in trap (frame=0xfffffe00639fa7d0) at /usr/home/melifaro/free/head/sys/amd64/amd64/trap.c:398
#16 <signal handler called>
#17 0xffffffff80df1b24 in tcp_lro_flush_all (lc=lc@entry=0xfffff8000382bca8) at /usr/home/melifaro/free/head/sys/netinet/tcp_lro.c:1442
#18 0xffffffff80a4ef7a in vtnet_rxq_eof (rxq=<optimized out>, rxq@entry=0xfffff8000382bc00) at /usr/home/melifaro/free/head/sys/dev/virtio/network/if_vtnet.c:2148
#19 0xffffffff80a4e5d7 in vtnet_rx_vq_process (rxq=0xfffff8000382bc00, tries=<optimized out>) at /usr/home/melifaro/free/head/sys/dev/virtio/network/if_vtnet.c:2207
#20 0xffffffff80c748da in taskqueue_run_locked (queue=queue@entry=0xfffff800037b3600) at /usr/home/melifaro/free/head/sys/kern/subr_taskqueue.c:476
#21 0xffffffff80c75964 in taskqueue_thread_loop (arg=arg@entry=0xfffff8000382bc80) at /usr/home/melifaro/free/head/sys/kern/subr_taskqueue.c:793
#22 0xffffffff80bcc8a0 in fork_exit (callout=0xffffffff80c758d0 <taskqueue_thread_loop>, arg=0xfffff8000382bc80, frame=0xfffffe00639fab00) at /usr/home/melifaro/free/head/sys/kern/kern_fork.c:1078
#23 <signal handler called>
(kgdb) up 17
#17 0xffffffff80df1b24 in tcp_lro_flush_all (lc=lc@entry=0xfffff8000382bca8) at /usr/home/melifaro/free/head/sys/netinet/tcp_lro.c:1442
1442		CURVNET_SET(lc->ifp->if_vnet);
(kgdb) p lc
$1 = (struct lro_ctrl *) 0xfffff8000382bca8
(kgdb) p lc->ifp
$2 = (struct ifnet *) 0x0
(kgdb) p *lc
$3 = {ifp = 0x0, lro_mbuf_data = 0x0, lro_last_queue_time = 0, lro_queued = 0, lro_flushed = 0, lro_bad_csum = 0, lro_cnt = 0, lro_mbuf_count = 0, lro_mbuf_max = 0, lro_ackcnt_lim = 0,
  lro_length_lim = 0, lro_hashsz = 0, lro_hash = 0x0, lro_active = {lh_first = 0x0}, lro_free = {lh_first = 0x0}}

Diff Detail

Repository
rG FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

This revision is now accepted and ready to land.Apr 22 2021, 7:49 AM
This revision was automatically updated to reflect the committed changes.

For the record: I have no context here and this may not be the best fix (e.g. it may be better to just fill at least the ifp pointer during RX ring init), so committing as a bandaid to fix the panic on boot.

This looks correct.

If the rxq->vtnrx_lro is not init, then it must not be used!

--HPS