summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorStefan Fritsch <sf@cvs.openbsd.org>2024-09-19 06:23:39 +0000
committerStefan Fritsch <sf@cvs.openbsd.org>2024-09-19 06:23:39 +0000
commita2c23e503c42c648ba48b7cffe2e6828f5d6d86b (patch)
treeb7504274566bbf1a71f5b084c27549a51b9c366f /sys
parent2f0d1c29558a69a9ca9d46d5243428fbc86650e8 (diff)
vio: allow longer tx chains
When TCP segmentation offload is supported, we may get larger packets with more dma segments. Allocate more segments in the busdma_map in this case, so that we need to defragment less often. ok jan@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pv/if_vio.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c
index e9c5f82384f..9b6a5452d1b 100644
--- a/sys/dev/pv/if_vio.c
+++ b/sys/dev/pv/if_vio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vio.c,v 1.55 2024/09/17 09:00:14 sf Exp $ */
+/* $OpenBSD: if_vio.c,v 1.56 2024/09/19 06:23:38 sf Exp $ */
/*
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@@ -269,7 +269,6 @@ struct vio_softc {
#define VIO_HAVE_MRG_RXBUF(sc) \
((sc)->sc_hdr_size == sizeof(struct virtio_net_hdr))
-#define VIRTIO_NET_TX_MAXNSEGS 16 /* for larger chains, defrag */
#define VIRTIO_NET_CTRL_MAC_MC_ENTRIES 64 /* for more entries, use ALLMULTI */
#define VIRTIO_NET_CTRL_MAC_UC_ENTRIES 1 /* one entry for own unicast addr */
#define VIRTIO_NET_CTRL_TIMEOUT (5*1000*1000*1000ULL) /* 5 seconds */
@@ -321,7 +320,7 @@ int vio_ctrl_start(struct vio_softc *, uint8_t, uint8_t, int, int *);
int vio_ctrl_submit(struct vio_softc *, int);
void vio_ctrl_finish(struct vio_softc *);
void vio_ctrl_wakeup(struct vio_softc *, enum vio_ctrl_state);
-int vio_alloc_mem(struct vio_softc *);
+int vio_alloc_mem(struct vio_softc *, int);
int vio_alloc_dmamem(struct vio_softc *);
void vio_free_dmamem(struct vio_softc *);
@@ -416,7 +415,7 @@ vio_free_dmamem(struct vio_softc *sc)
* viq_txmbufs[slot]: mbuf pointer array for sent frames
*/
int
-vio_alloc_mem(struct vio_softc *sc)
+vio_alloc_mem(struct vio_softc *sc, int tx_max_segments)
{
struct virtio_softc *vsc = sc->sc_virtio;
struct ifnet *ifp = &sc->sc_ac.ac_if;
@@ -503,7 +502,7 @@ vio_alloc_mem(struct vio_softc *sc)
for (i = 0; i < txqsize; i++) {
r = bus_dmamap_create(vsc->sc_dmat, txsize,
- VIRTIO_NET_TX_MAXNSEGS, txsize, 0,
+ tx_max_segments, txsize, 0,
BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
&vioq->viq_txdmamaps[i]);
if (r != 0)
@@ -586,7 +585,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
{
struct vio_softc *sc = (struct vio_softc *)self;
struct virtio_softc *vsc = (struct virtio_softc *)parent;
- int i;
+ int i, tx_max_segments;
struct ifnet *ifp = &sc->sc_ac.ac_if;
if (vsc->sc_child != NULL) {
@@ -650,6 +649,17 @@ vio_attach(struct device *parent, struct device *self, void *aux)
else
ifp->if_hardmtu = MCLBYTES - sc->sc_hdr_size - ETHER_HDR_LEN;
+ /* defrag for longer mbuf chains */
+ tx_max_segments = 16;
+ if (virtio_has_feature(vsc, VIRTIO_NET_F_HOST_TSO4) ||
+ virtio_has_feature(vsc, VIRTIO_NET_F_HOST_TSO6)) {
+ /*
+ * With TSO, we may get 64K packets and want to be able to
+ * send longer chains without defragmenting
+ */
+ tx_max_segments = 32;
+ }
+
for (i = 0; i < sc->sc_nqueues; i++) {
int vqidx = 2 * i;
struct vio_queue *vioq = &sc->sc_q[i];
@@ -664,7 +674,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
vqidx++;
vioq->viq_txvq = &vsc->sc_vqs[vqidx];
if (virtio_alloc_vq(vsc, vioq->viq_txvq, vqidx,
- VIRTIO_NET_TX_MAXNSEGS + 1, "tx") != 0) {
+ tx_max_segments + 1, "tx") != 0) {
goto err;
}
vioq->viq_txvq->vq_done = vio_tx_intr;
@@ -684,7 +694,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
virtio_start_vq_intr(vsc, sc->sc_ctl_vq);
}
- if (vio_alloc_mem(sc) < 0)
+ if (vio_alloc_mem(sc, tx_max_segments) < 0)
goto err;
strlcpy(ifp->if_xname, self->dv_xname, IFNAMSIZ);