diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-02-20 17:50:23 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-02-20 17:50:23 +0000 |
commit | c96b59c95d97512587970d771ffe17678f50c448 (patch) | |
tree | 3cd2e5e6e3d49cd9353ad93f42932acbcc4ad0c1 | |
parent | bd27f21c0da29956ad1ada347d2696010da5bb6f (diff) |
Make sure we have enough space in the LDC transmit queue to send a DRING_DATA
message and bail out early instead of dropping packets to be transmitted.
-rw-r--r-- | sys/arch/sparc64/dev/vnet.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/sys/arch/sparc64/dev/vnet.c b/sys/arch/sparc64/dev/vnet.c index b0a70dcfe2c..5488274a974 100644 --- a/sys/arch/sparc64/dev/vnet.c +++ b/sys/arch/sparc64/dev/vnet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vnet.c,v 1.12 2009/01/17 22:18:14 kettenis Exp $ */ +/* $OpenBSD: vnet.c,v 1.13 2009/02/20 17:50:22 kettenis Exp $ */ /* * Copyright (c) 2009 Mark Kettenis * @@ -814,7 +814,7 @@ vio_sendmsg(struct vnet_softc *sc, void *msg, size_t len) tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1); err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail); if (err != H_EOK) - printf("hv_ldc_tx_set_qtail: %d\n", err); + printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err); } void @@ -900,12 +900,14 @@ void vnet_start(struct ifnet *ifp) { struct vnet_softc *sc = ifp->if_softc; + struct ldc_conn *lc = &sc->sc_lc; struct ldc_map *map = sc->sc_lm; struct vio_dring_msg dm; struct mbuf *m; paddr_t pa; caddr_t buf; - int desc; + uint64_t tx_head, tx_tail, tx_state; + int err, desc; if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) return; @@ -920,6 +922,20 @@ vnet_start(struct ifnet *ifp) if (sc->sc_vio_state != VIO_ESTABLISHED) return; + /* + * Make sure there is room in the LDC transmit queue to send a + * DRING_DATA message. + */ + err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state); + if (err != H_EOK) + return; + tx_tail += sizeof(struct ldc_pkt); + tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(struct ldc_pkt)) - 1); + if (tx_tail == tx_head) { + ifp->if_flags |= IFF_OACTIVE; + return; + } + desc = sc->sc_tx_prod; while (sc->sc_vd->vd_desc[desc].hdr.dstate == VIO_DESC_FREE) { IFQ_POLL(&ifp->if_snd, m); |