Page MenuHomeFreeBSD

Fix vtnet TCP lro panic
ClosedPublic

Authored by melifaro on Apr 21 2021, 10:51 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mar 7 2024, 11:45 PM
Unknown Object (File)
Feb 5 2024, 2:28 PM
Unknown Object (File)
Dec 22 2023, 11:49 PM
Unknown Object (File)
Dec 14 2023, 1:56 PM
Unknown Object (File)
Dec 12 2023, 7:50 AM
Unknown Object (File)
Dec 9 2023, 7:36 AM
Unknown Object (File)
Nov 25 2023, 11:40 AM
Unknown Object (File)
Nov 25 2023, 11:40 AM
Subscribers

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
Lint Not Applicable
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