diff options
author | avg <avg@FreeBSD.org> | 2017-06-19 14:45:20 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2017-06-19 14:45:20 +0000 |
commit | 432e857f0d18498c906d69775e49df383fc97973 (patch) | |
tree | 5f76fc492c069bbb75d164c6db7cb55a78a9b156 | |
parent | b040418e8f00d678454b180b1adb68c2ba0a9b95 (diff) | |
download | FreeBSD-src-432e857f0d18498c906d69775e49df383fc97973.zip FreeBSD-src-432e857f0d18498c906d69775e49df383fc97973.tar.gz |
MFC r318867: fix vmxnet3 crash when LRO is enabled
The crash can occur when all of the following conditions are true:
- a packet consists of multiple segments (requires LRO enabled)
- there has been a failure to allocate an mbuf for the packet and
the packet has to be dropped
- a host (vmware) still owned at least one segment of the packet,
so the driver had to wait for another interrupt to proceed to
discarding the remaining segment(s)
Reviewed by: rstone
Approved by: re (gjb)
Sponsored by: Panzura
-rw-r--r-- | sys/dev/vmware/vmxnet3/if_vmx.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/dev/vmware/vmxnet3/if_vmx.c b/sys/dev/vmware/vmxnet3/if_vmx.c index b1bc947..017ccb0 100644 --- a/sys/dev/vmware/vmxnet3/if_vmx.c +++ b/sys/dev/vmware/vmxnet3/if_vmx.c @@ -2194,6 +2194,20 @@ vmxnet3_rxq_eof(struct vmxnet3_rxqueue *rxq) } else { KASSERT(rxd->btype == VMXNET3_BTYPE_BODY, ("%s: non start of frame w/o body buffer", __func__)); + + if (m_head == NULL && m_tail == NULL) { + /* + * This is a continuation of a packet that we + * started to drop, but could not drop entirely + * because this segment was still owned by the + * host. So, drop the remainder now. + */ + vmxnet3_rxq_eof_discard(rxq, rxr, idx); + if (!rxcd->eop) + vmxnet3_rxq_discard_chain(rxq); + goto nextp; + } + KASSERT(m_head != NULL, ("%s: frame not started?", __func__)); |