diff options
author | kmacy <kmacy@FreeBSD.org> | 2008-01-15 08:08:09 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2008-01-15 08:08:09 +0000 |
commit | 90f3f8edb2bda24c666a8a36141ac4c371a0f58a (patch) | |
tree | c9b6e1e52defdce1aea0f33fb7f6d611bbe2c8c3 /sys/dev/cxgb/cxgb_sge.c | |
parent | 409fbbd08fad855cfd3efaab185d2f4091e931f9 (diff) | |
download | FreeBSD-src-90f3f8edb2bda24c666a8a36141ac4c371a0f58a.zip FreeBSD-src-90f3f8edb2bda24c666a8a36141ac4c371a0f58a.tar.gz |
- Simplify mb_free_ext_fast
- increase asserts for mbuf accounting
- track outstanding mbufs (maps very closely to leaked)
- actually only create one thread per port if !multiq
Oddly enough this fixes the use after free
- move txq_segs to stack in t3_encap
- add checks that pidx doesn't move pass cidx
- simplify mbuf free logic in collapse mbufs routine
Diffstat (limited to 'sys/dev/cxgb/cxgb_sge.c')
-rw-r--r-- | sys/dev/cxgb/cxgb_sge.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index c854d9d..06ab98d 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -927,7 +927,17 @@ txq_prod(struct sge_txq *txq, unsigned int ndesc, struct txq_state *txqs) txq->unacked &= 7; txqs->pidx = txq->pidx; txq->pidx += ndesc; - +#ifdef INVARIANTS + if (((txqs->pidx > txq->cidx) && + (txq->pidx < txqs->pidx) && + (txq->pidx >= txq->cidx)) || + ((txqs->pidx < txq->cidx) && + (txq->pidx >= txq-> cidx)) || + ((txqs->pidx < txq->cidx) && + (txq->cidx < txqs->pidx))) + panic("txqs->pidx=%d txq->pidx=%d txq->cidx=%d", + txqs->pidx, txq->pidx, txq->cidx); +#endif if (txq->pidx >= txq->size) { txq->pidx -= txq->size; txq->gen ^= 1; @@ -1205,23 +1215,23 @@ t3_encap(struct sge_qset *qs, struct mbuf **m, int count) struct work_request_hdr *wrp; struct tx_sw_desc *txsd; struct sg_ent *sgp, *sgl; - bus_dma_segment_t *segs; uint32_t wr_hi, wr_lo, sgl_flits; + bus_dma_segment_t segs[TX_MAX_SEGS]; struct tx_desc *txd; struct mbuf_vec *mv; struct mbuf_iovec *mi; DPRINTF("t3_encap cpu=%d ", curcpu); + KASSERT(qs->idx == 0, ("invalid qs %d", qs->idx)); mi = NULL; pi = qs->port; sc = pi->adapter; txq = &qs->txq[TXQ_ETH]; - txsd = &txq->sdesc[txq->pidx]; txd = &txq->desc[txq->pidx]; + txsd = &txq->sdesc[txq->pidx]; sgl = txq->txq_sgl; - segs = txq->txq_segs; m0 = *m; DPRINTF("t3_encap port_id=%d qsidx=%d ", pi->port_id, pi->first_qset); @@ -1240,6 +1250,8 @@ t3_encap(struct sge_qset *qs, struct mbuf **m, int count) #endif KASSERT(txsd->mi.mi_base == NULL, ("overwrting valid entry mi_base==%p", txsd->mi.mi_base)); + if (cxgb_debug) + printf("uipc_mvec PIO_LEN=%ld\n", PIO_LEN); if (count > 1) { panic("count > 1 not support in CVS\n"); @@ -1253,7 +1265,7 @@ t3_encap(struct sge_qset *qs, struct mbuf **m, int count) } KASSERT(m0->m_pkthdr.len, ("empty packet nsegs=%d count=%d", nsegs, count)); - if (m0->m_pkthdr.len > PIO_LEN) { + if (!(m0->m_pkthdr.len <= PIO_LEN)) { mi_collapse_mbuf(&txsd->mi, m0); mi = &txsd->mi; } @@ -1393,8 +1405,11 @@ t3_encap(struct sge_qset *qs, struct mbuf **m, int count) write_wr_hdr_sgl(ndesc, txd, &txqs, txq, sgl, flits, sgl_flits, wr_hi, wr_lo); check_ring_tx_db(pi->adapter, txq); - if ((m0->m_type == MT_DATA) && ((m0->m_flags & (M_EXT|M_NOFREE)) == M_EXT)) { + if ((m0->m_type == MT_DATA) && + ((m0->m_flags & (M_EXT|M_NOFREE)) == M_EXT) && + (m0->m_ext.ext_type != EXT_PACKET)) { m0->m_flags &= ~M_EXT ; + mbufs_outstanding--; m_free(m0); } @@ -1797,6 +1812,7 @@ t3_free_tx_desc(struct sge_txq *q, int reclaimable) cidx = q->cidx; txsd = &q->sdesc[cidx]; DPRINTF("reclaiming %d WR\n", reclaimable); + mtx_assert(&q->lock, MA_OWNED); while (reclaimable--) { DPRINTF("cidx=%d d=%p\n", cidx, txsd); if (txsd->mi.mi_base != NULL) { @@ -2208,6 +2224,7 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx, } init_qset_cntxt(q, id); + q->idx = id; if ((ret = alloc_ring(sc, p->fl_size, sizeof(struct rx_desc), sizeof(struct rx_sw_desc), &q->fl[0].phys_addr, @@ -3203,7 +3220,11 @@ t3_add_attach_sysctls(adapter_t *sc) SYSCTL_ADD_INT(ctx, children, OID_AUTO, "ext_freed", CTLFLAG_RD, &cxgb_ext_freed, - 0, "#times a cluster was freed through ext_free"); + 0, "#times a cluster was freed through ext_free"); + SYSCTL_ADD_INT(ctx, children, OID_AUTO, + "mbufs_outstanding", + CTLFLAG_RD, &mbufs_outstanding, + 0, "#mbufs in flight in the driver"); } |