Skip to content

Commit

Permalink
vtnet: Fix an LOR in the input path
Browse files Browse the repository at this point in the history
if_vtnet holds a queue lock when processing incoming packets.  It sends
them up the stack without dropping the lock, which is incorrect.  For
example, witness generates warnings when if_vtnet receives ND6 packets:

 may sleep with the following non-sleepable locks held:
exclusive sleep mutex vtnet1-rx0 (vtnet1-rx0) r = 0 (0xfffff80001790000) locked @ /root/freebsd/sys/dev/virtio/network/if_vtnet.c:2202
stack backtrace:
.#0 0xffffffff80bd6785 at witness_debugger+0x65
.#1 0xffffffff80bd78e3 at witness_warn+0x413
.#2 0xffffffff80d8a504 at in6_update_ifa+0xcb4
.#3 0xffffffff80db7030 at in6_ifadd+0x1e0
.#4 0xffffffff80db3734 at nd6_ra_input+0x1024
.#5 0xffffffff80d8430b at icmp6_input+0x5ab
.#6 0xffffffff80d9db68 at ip6_input+0xc78
.#7 0xffffffff80cbb21d at netisr_dispatch_src+0xad
.#8 0xffffffff80c9db0a at ether_demux+0x16a
.#9 0xffffffff80c9f15a at ether_nh_input+0x34a
.#10 0xffffffff80cbb21d at netisr_dispatch_src+0xad
.#11 0xffffffff80c9df69 at ether_input+0xd9
.#12 0xffffffff80986240 at vtnet_rxq_eof+0x790
.#13 0xffffffff809859fc at vtnet_rx_vq_process+0x9c
.#14 0xffffffff80b19dc6 at ithread_loop+0x266
.#15 0xffffffff80b161f2 at fork_exit+0x82
.#16 0xffffffff8105322e at fork_trampoline+0xe

Simply drop the lock before entering the network stack.  We could batch
this by linking a small number of packets using m_nextpkt; ether_input()
handles such batches.

PR:		253888
Reviewed by:	zlei
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D45950
  • Loading branch information
markjdb committed Jul 16, 2024
1 parent 502f522 commit 432c182
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion sys/dev/virtio/network/if_vtnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -2008,6 +2008,8 @@ vtnet_rxq_input(struct vtnet_rxq *rxq, struct mbuf *m,
struct vtnet_softc *sc;
if_t ifp;

VTNET_RXQ_LOCK_ASSERT(rxq);

sc = rxq->vtnrx_sc;
ifp = sc->vtnet_ifp;

Expand Down Expand Up @@ -2049,14 +2051,18 @@ vtnet_rxq_input(struct vtnet_rxq *rxq, struct mbuf *m,
rxq->vtnrx_stats.vrxs_ipackets++;
rxq->vtnrx_stats.vrxs_ibytes += m->m_pkthdr.len;

VTNET_RXQ_UNLOCK(rxq);
#if defined(INET) || defined(INET6)
if (vtnet_software_lro(sc) && if_getcapenable(ifp) & IFCAP_LRO) {
if (vtnet_lro_rx(rxq, m) == 0)
if (vtnet_lro_rx(rxq, m) == 0) {
VTNET_RXQ_LOCK(rxq);
return;
}
}
#endif

if_input(ifp, m);
VTNET_RXQ_LOCK(rxq);
}

static int
Expand Down

0 comments on commit 432c182

Please sign in to comment.