Add a transmit descriptor usage counter and use it to absolutely,
positively not let ti_encap() fill up the TX ring all the way and wrap around. This fixes a potential transmit lockup where a really fast machine (or particular TX traffic pattern) can overrun the end of the ring. Reported by: John Plevyak <jplevyak@inktomi.com>
This commit is contained in:
parent
97a62e386d
commit
274342303b
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_ti.c,v 1.5 1999/05/09 17:07:00 peter Exp $
|
||||
* $Id: if_ti.c,v 1.6 1999/05/24 14:56:55 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -128,7 +128,7 @@
|
||||
|
||||
#if !defined(lint)
|
||||
static const char rcsid[] =
|
||||
"$Id: if_ti.c,v 1.5 1999/05/09 17:07:00 peter Exp $";
|
||||
"$Id: if_ti.c,v 1.6 1999/05/24 14:56:55 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1065,6 +1065,7 @@ static void ti_free_tx_ring(sc)
|
||||
static int ti_init_tx_ring(sc)
|
||||
struct ti_softc *sc;
|
||||
{
|
||||
sc->ti_txcnt = 0;
|
||||
sc->ti_tx_saved_considx = 0;
|
||||
CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, 0);
|
||||
return(0);
|
||||
@ -1920,6 +1921,7 @@ static void ti_txeof(sc)
|
||||
m_freem(sc->ti_cdata.ti_tx_chain[idx]);
|
||||
sc->ti_cdata.ti_tx_chain[idx] = NULL;
|
||||
}
|
||||
sc->ti_txcnt--;
|
||||
TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT);
|
||||
ifp->if_timer = 0;
|
||||
}
|
||||
@ -1996,7 +1998,7 @@ static int ti_encap(sc, m_head, txidx)
|
||||
{
|
||||
struct ti_tx_desc *f = NULL;
|
||||
struct mbuf *m;
|
||||
u_int32_t frag, cur;
|
||||
u_int32_t frag, cur, cnt = 0;
|
||||
#if NVLAN > 0
|
||||
struct ifvlan *ifv = NULL;
|
||||
|
||||
@ -2045,8 +2047,15 @@ static int ti_encap(sc, m_head, txidx)
|
||||
f->ti_vlan_tag = 0;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Sanity check: avoid coming within 16 descriptors
|
||||
* of the end of the ring.
|
||||
*/
|
||||
if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16)
|
||||
return(ENOBUFS);
|
||||
cur = frag;
|
||||
TI_INC(frag, TI_TX_RING_CNT);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2062,6 +2071,7 @@ static int ti_encap(sc, m_head, txidx)
|
||||
else
|
||||
sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END;
|
||||
sc->ti_cdata.ti_tx_chain[cur] = m_head;
|
||||
sc->ti_txcnt += cnt;
|
||||
|
||||
*txidx = frag;
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_tireg.h,v 1.2 1999/05/03 17:44:52 wpaul Exp $
|
||||
* $Id: if_tireg.h,v 1.3 1999/05/26 23:01:50 gallatin Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1151,6 +1151,7 @@ struct ti_softc {
|
||||
u_int32_t ti_tx_max_coal_bds;
|
||||
u_int32_t ti_tx_buf_ratio;
|
||||
int ti_if_flags;
|
||||
int ti_txcnt;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_ti.c,v 1.5 1999/05/09 17:07:00 peter Exp $
|
||||
* $Id: if_ti.c,v 1.6 1999/05/24 14:56:55 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -128,7 +128,7 @@
|
||||
|
||||
#if !defined(lint)
|
||||
static const char rcsid[] =
|
||||
"$Id: if_ti.c,v 1.5 1999/05/09 17:07:00 peter Exp $";
|
||||
"$Id: if_ti.c,v 1.6 1999/05/24 14:56:55 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1065,6 +1065,7 @@ static void ti_free_tx_ring(sc)
|
||||
static int ti_init_tx_ring(sc)
|
||||
struct ti_softc *sc;
|
||||
{
|
||||
sc->ti_txcnt = 0;
|
||||
sc->ti_tx_saved_considx = 0;
|
||||
CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, 0);
|
||||
return(0);
|
||||
@ -1920,6 +1921,7 @@ static void ti_txeof(sc)
|
||||
m_freem(sc->ti_cdata.ti_tx_chain[idx]);
|
||||
sc->ti_cdata.ti_tx_chain[idx] = NULL;
|
||||
}
|
||||
sc->ti_txcnt--;
|
||||
TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT);
|
||||
ifp->if_timer = 0;
|
||||
}
|
||||
@ -1996,7 +1998,7 @@ static int ti_encap(sc, m_head, txidx)
|
||||
{
|
||||
struct ti_tx_desc *f = NULL;
|
||||
struct mbuf *m;
|
||||
u_int32_t frag, cur;
|
||||
u_int32_t frag, cur, cnt = 0;
|
||||
#if NVLAN > 0
|
||||
struct ifvlan *ifv = NULL;
|
||||
|
||||
@ -2045,8 +2047,15 @@ static int ti_encap(sc, m_head, txidx)
|
||||
f->ti_vlan_tag = 0;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Sanity check: avoid coming within 16 descriptors
|
||||
* of the end of the ring.
|
||||
*/
|
||||
if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16)
|
||||
return(ENOBUFS);
|
||||
cur = frag;
|
||||
TI_INC(frag, TI_TX_RING_CNT);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2062,6 +2071,7 @@ static int ti_encap(sc, m_head, txidx)
|
||||
else
|
||||
sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END;
|
||||
sc->ti_cdata.ti_tx_chain[cur] = m_head;
|
||||
sc->ti_txcnt += cnt;
|
||||
|
||||
*txidx = frag;
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: if_tireg.h,v 1.2 1999/05/03 17:44:52 wpaul Exp $
|
||||
* $Id: if_tireg.h,v 1.3 1999/05/26 23:01:50 gallatin Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1151,6 +1151,7 @@ struct ti_softc {
|
||||
u_int32_t ti_tx_max_coal_bds;
|
||||
u_int32_t ti_tx_buf_ratio;
|
||||
int ti_if_flags;
|
||||
int ti_txcnt;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user