For controllers that have TX interrupt moderation capability,

request TX completion interrupt for every 8-th frames. Previously
dc(4) requested TX completion interrupt if number of queued TX
descriptors is greater than 64. This caused a lot of TX completion
interrupt under high TX load once driver queued more than 64 TX
descriptors. It's quite normal to see more than 64 queued TX
descriptors under high TX load.
This change reduces the number of TX completion interrupts to be
less than 17k under high TX load. Because this change does not
generate TX completion interrupt for each frame, add reclaiming
transmitted buffers in dc_tick not to generate false watchdog
timeouts.
While I'm here add check for queued descriptors in dc_txeof() since
there is no more work to do when there is no pending descriptors.
This commit is contained in:
Pyun YongHyeon 2011-02-18 20:38:05 +00:00
parent cfd69ae791
commit 06d23883e7
2 changed files with 16 additions and 1 deletions

View File

@ -2473,6 +2473,7 @@ dc_list_tx_init(struct dc_softc *sc)
}
cd->dc_tx_prod = cd->dc_tx_cons = cd->dc_tx_cnt = 0;
cd->dc_tx_pkts = 0;
bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap,
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
return (0);
@ -2841,6 +2842,9 @@ dc_txeof(struct dc_softc *sc)
int idx;
u_int32_t ctl, txstat;
if (sc->dc_cdata.dc_tx_cnt == 0)
return;
ifp = sc->dc_ifp;
/*
@ -2952,6 +2956,13 @@ dc_tick(void *xsc)
ifp = sc->dc_ifp;
mii = device_get_softc(sc->dc_miibus);
/*
* Reclaim transmitted frames for controllers that do
* not generate TX completion interrupt for every frame.
*/
if (sc->dc_flags & DC_TX_USE_TX_INTR)
dc_txeof(sc);
if (sc->dc_flags & DC_REDUCED_MII_POLL) {
if (sc->dc_flags & DC_21143_NWAY) {
r = CSR_READ_4(sc, DC_10BTSTAT);
@ -3322,8 +3333,11 @@ dc_encap(struct dc_softc *sc, struct mbuf **m_head)
htole32(DC_TXCTL_FINT);
if (sc->dc_flags & DC_TX_INTR_ALWAYS)
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT);
if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
if (sc->dc_flags & DC_TX_USE_TX_INTR &&
++sc->dc_cdata.dc_tx_pkts >= 8) {
sc->dc_cdata.dc_tx_pkts = 0;
sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT);
}
sc->dc_ldata->dc_tx_list[first].dc_status = htole32(DC_TXSTAT_OWN);
bus_dmamap_sync(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx],

View File

@ -495,6 +495,7 @@ struct dc_chain_data {
bus_dmamap_t dc_tx_map[DC_TX_LIST_CNT];
u_int32_t *dc_sbuf;
u_int8_t dc_pad[DC_MIN_FRAMELEN];
int dc_tx_pkts;
int dc_tx_first;
int dc_tx_prod;
int dc_tx_cons;