vmxnet3: skip zero-length descriptor in the middle of a packet
Passing up such descriptors to iflib is obviously wasteful. But the main conern is that we may overrun iri_frags array because of them. That's been observed in practice. Also, assert that the number of fragments / descriptors / segments is less than IFLIB_MAX_RX_SEGS. Reviewed by: gallatin, pkelsey MFC after: 3 weeks Sponsored by: Panzura LLC Differential Revision: https://reviews.freebsd.org/D33189
This commit is contained in:
parent
cd6f0b4769
commit
9c612a5d0a
@ -1503,8 +1503,6 @@ vmxnet3_isc_rxd_pkt_get(void *vsc, if_rxd_info_t ri)
|
||||
struct vmxnet3_rxqueue *rxq;
|
||||
struct vmxnet3_comp_ring *rxc;
|
||||
struct vmxnet3_rxcompdesc *rxcd;
|
||||
struct vmxnet3_rxring *rxr;
|
||||
struct vmxnet3_rxdesc *rxd;
|
||||
if_rxd_frag_t frag;
|
||||
int cqidx;
|
||||
uint16_t total_len;
|
||||
@ -1604,16 +1602,19 @@ vmxnet3_isc_rxd_pkt_get(void *vsc, if_rxd_info_t ri)
|
||||
rxcd = &rxc->vxcr_u.rxcd[cqidx];
|
||||
KASSERT(rxcd->gen == rxc->vxcr_gen,
|
||||
("%s: generation mismatch", __func__));
|
||||
flid = (rxcd->qid >= scctx->isc_nrxqsets) ? 1 : 0;
|
||||
rxr = &rxq->vxrxq_cmd_ring[flid];
|
||||
rxd = &rxr->vxrxr_rxd[rxcd->rxd_idx];
|
||||
|
||||
frag = &ri->iri_frags[nfrags];
|
||||
frag->irf_flid = flid;
|
||||
frag->irf_idx = rxcd->rxd_idx;
|
||||
frag->irf_len = rxcd->len;
|
||||
total_len += rxcd->len;
|
||||
nfrags++;
|
||||
KASSERT(nfrags < IFLIB_MAX_RX_SEGS,
|
||||
("%s: too many fragments", __func__));
|
||||
if (__predict_true(rxcd->len != 0)) {
|
||||
frag = &ri->iri_frags[nfrags];
|
||||
flid = (rxcd->qid >= scctx->isc_nrxqsets) ? 1 : 0;
|
||||
frag->irf_flid = flid;
|
||||
frag->irf_idx = rxcd->rxd_idx;
|
||||
frag->irf_len = rxcd->len;
|
||||
total_len += rxcd->len;
|
||||
nfrags++;
|
||||
} else {
|
||||
rxc->vcxr_zero_length_frag++;
|
||||
}
|
||||
if (++cqidx == rxc->vxcr_ndesc) {
|
||||
cqidx = 0;
|
||||
rxc->vxcr_gen ^= 1;
|
||||
@ -1885,6 +1886,7 @@ vmxnet3_rxinit(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rxq)
|
||||
rxc->vxcr_next = 0;
|
||||
rxc->vxcr_gen = VMXNET3_INIT_GEN;
|
||||
rxc->vxcr_zero_length = 0;
|
||||
rxc->vcxr_zero_length_frag = 0;
|
||||
rxc->vxcr_pkt_errors = 0;
|
||||
/*
|
||||
* iflib has zeroed out the descriptor array during the prior attach
|
||||
@ -2365,6 +2367,9 @@ vmxnet3_setup_debug_sysctl(struct vmxnet3_softc *sc,
|
||||
&rxq->vxrxq_comp_ring.vxcr_gen, 0, "");
|
||||
SYSCTL_ADD_U64(ctx, list, OID_AUTO, "comp_zero_length", CTLFLAG_RD,
|
||||
&rxq->vxrxq_comp_ring.vxcr_zero_length, 0, "");
|
||||
SYSCTL_ADD_U64(ctx, list, OID_AUTO, "comp_zero_length_frag",
|
||||
CTLFLAG_RD, &rxq->vxrxq_comp_ring.vcxr_zero_length_frag,
|
||||
0, "");
|
||||
SYSCTL_ADD_U64(ctx, list, OID_AUTO, "comp_pkt_errors", CTLFLAG_RD,
|
||||
&rxq->vxrxq_comp_ring.vxcr_pkt_errors, 0, "");
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ struct vmxnet3_comp_ring {
|
||||
int vxcr_gen;
|
||||
bus_addr_t vxcr_paddr;
|
||||
uint64_t vxcr_zero_length;
|
||||
uint64_t vcxr_zero_length_frag;
|
||||
uint64_t vxcr_pkt_errors;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user