Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci vioif(4): added functions to manipulate network ...
details: https://anonhg.NetBSD.org/src/rev/2a11ed69f728
branches: trunk
changeset: 373968:2a11ed69f728
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Thu Mar 23 02:48:29 2023 +0000
description:
vioif(4): added functions to manipulate network queues
diffstat:
sys/dev/pci/if_vioif.c | 330 +++++++++++++++++++++++++++++++-----------------
1 files changed, 210 insertions(+), 120 deletions(-)
diffs (truncated from 545 to 300 lines):
diff -r 0e78da987f00 -r 2a11ed69f728 sys/dev/pci/if_vioif.c
--- a/sys/dev/pci/if_vioif.c Thu Mar 23 02:42:49 2023 +0000
+++ b/sys/dev/pci/if_vioif.c Thu Mar 23 02:48:29 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vioif.c,v 1.98 2023/03/23 02:42:49 yamaguchi Exp $ */
+/* $NetBSD: if_vioif.c,v 1.99 2023/03/23 02:48:29 yamaguchi Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.98 2023/03/23 02:42:49 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.99 2023/03/23 02:48:29 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -259,7 +259,7 @@
char netq_evgroup[32];
struct evcnt netq_mbuf_load_failed;
- struct evcnt netq_enqueue_reserve_failed;
+ struct evcnt netq_enqueue_failed;
void *netq_ctx;
};
@@ -370,6 +370,21 @@
/* tx & rx */
static void vioif_net_sched_handle(struct vioif_softc *,
struct vioif_netqueue *);
+static int vioif_net_load_mbuf(struct virtio_softc *,
+ struct vioif_net_map *, struct mbuf *, int);
+static void vioif_net_unload_mbuf(struct virtio_softc *,
+ struct vioif_net_map *);
+static int vioif_net_enqueue_tx(struct virtio_softc *, struct virtqueue *,
+ int, struct vioif_net_map *);
+static int vioif_net_enqueue_rx(struct virtio_softc *, struct virtqueue *,
+ int, struct vioif_net_map *);
+static struct mbuf *
+ vioif_net_dequeue_commit(struct virtio_softc *,
+ struct virtqueue *, int, struct vioif_net_map *, int);
+static void vioif_net_intr_enable(struct vioif_softc *,
+ struct virtio_softc *);
+static void vioif_net_intr_disable(struct vioif_softc *,
+ struct virtio_softc *);
/* rx */
static void vioif_populate_rx_mbufs_locked(struct vioif_softc *,
@@ -412,12 +427,11 @@
static int vioif_config_change(struct virtio_softc *);
static void vioif_ctl_softint(void *);
static int vioif_ctrl_mq_vq_pairs_set(struct vioif_softc *, int);
-static void vioif_enable_interrupt_vqpairs(struct vioif_softc *);
-static void vioif_disable_interrupt_vqpairs(struct vioif_softc *);
static int vioif_setup_sysctl(struct vioif_softc *);
static void vioif_setup_stats(struct vioif_softc *);
static int vioif_ifflags(struct vioif_softc *);
static void vioif_intr_barrier(void);
+static void vioif_notify(struct virtio_softc *, struct virtqueue *);
CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc),
vioif_match, vioif_attach, NULL, NULL);
@@ -1180,34 +1194,6 @@
return 0;
}
-static void
-vioif_enable_interrupt_vqpairs(struct vioif_softc *sc)
-{
- struct virtio_softc *vsc = sc->sc_virtio;
- struct vioif_netqueue *netq;
- size_t i, netq_act_num;
-
- netq_act_num = sc->sc_act_nvq_pairs * 2;
- for (i = 0; i < netq_act_num; i++) {
- netq = &sc->sc_netqs[i];
- virtio_start_vq_intr(vsc, netq->netq_vq);
- }
-}
-
-static void
-vioif_disable_interrupt_vqpairs(struct vioif_softc *sc)
-{
- struct virtio_softc *vsc = sc->sc_virtio;
- struct vioif_netqueue *netq;
- size_t i, netq_act_num;
-
- netq_act_num = sc->sc_act_nvq_pairs * 2;
- for (i = 0; i < netq_act_num; i++) {
- netq = &sc->sc_netqs[i];
- virtio_stop_vq_intr(vsc, netq->netq_vq);
- }
-}
-
/*
* Interface functions for ifnet
*/
@@ -1252,7 +1238,7 @@
SET(ifp->if_flags, IFF_RUNNING);
CLR(ifp->if_flags, IFF_OACTIVE);
- vioif_enable_interrupt_vqpairs(sc);
+ vioif_net_intr_enable(sc, vsc);
vioif_update_link_status(sc);
r = vioif_rx_filter(sc);
@@ -1267,12 +1253,12 @@
struct virtio_softc *vsc = sc->sc_virtio;
struct vioif_netqueue *netq;
struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
- size_t i, netq_act_num;
-
- netq_act_num = sc->sc_act_nvq_pairs * 2;
+ size_t i, act_qnum;
+
+ act_qnum = sc->sc_act_nvq_pairs * 2;
CLR(ifp->if_flags, IFF_RUNNING);
- for (i = 0; i < netq_act_num; i++) {
+ for (i = 0; i < act_qnum; i++) {
netq = &sc->sc_netqs[i];
mutex_enter(&netq->netq_lock);
@@ -1281,7 +1267,7 @@
}
/* disable interrupts */
- vioif_disable_interrupt_vqpairs(sc);
+ vioif_net_intr_disable(sc, vsc);
if (sc->sc_has_ctrl)
virtio_stop_vq_intr(vsc, ctrlq->ctrlq_vq);
@@ -1295,7 +1281,7 @@
vioif_intr_barrier();
- for (i = 0; i < netq_act_num; i++) {
+ for (i = 0; i < act_qnum; i++) {
netq = &sc->sc_netqs[i];
vioif_work_wait(sc->sc_txrx_workqueue, &netq->netq_work);
}
@@ -1309,7 +1295,7 @@
}
/* all packet processing is stopped */
- for (i = 0; i < netq_act_num; i++) {
+ for (i = 0; i < act_qnum; i++) {
netq = &sc->sc_netqs[i];
mutex_enter(&netq->netq_lock);
@@ -1327,7 +1313,6 @@
struct virtqueue *vq = netq->netq_vq;
struct vioif_tx_context *txc;
struct vioif_net_map *map;
- struct virtio_net_hdr *hdr;
struct mbuf *m;
int queued = 0;
@@ -1367,25 +1352,23 @@
map = &netq->netq_maps[slot];
KASSERT(map->vnm_mbuf == NULL);
- r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
- map->vnm_mbuf_map, m, BUS_DMA_WRITE | BUS_DMA_NOWAIT);
+ r = vioif_net_load_mbuf(vsc, map, m, BUS_DMA_WRITE);
if (r != 0) {
/* maybe just too fragmented */
struct mbuf *newm;
newm = m_defrag(m, M_NOWAIT);
- if (newm == NULL) {
+ if (newm != NULL) {
+ m = newm;
+ r = vioif_net_load_mbuf(vsc, map, m,
+ BUS_DMA_WRITE);
+ } else {
txc->txc_defrag_failed.ev_count++;
- goto skip;
+ r = -1;
}
- m = newm;
- r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
- map->vnm_mbuf_map, m,
- BUS_DMA_WRITE | BUS_DMA_NOWAIT);
if (r != 0) {
netq->netq_mbuf_load_failed.ev_count++;
-skip:
m_freem(m);
if_statinc(ifp, if_oerrors);
virtio_enqueue_abort(vsc, vq, slot);
@@ -1393,36 +1376,25 @@
}
}
- /* This should actually never fail */
- r = virtio_enqueue_reserve(vsc, vq, slot,
- map->vnm_mbuf_map->dm_nsegs + 1);
+ memset(map->vnm_hdr, 0, sc->sc_hdr_size);
+
+ r = vioif_net_enqueue_tx(vsc, vq, slot, map);
if (r != 0) {
- netq->netq_enqueue_reserve_failed.ev_count++;
- bus_dmamap_unload(virtio_dmat(vsc),
- map->vnm_mbuf_map);
- /* slot already freed by virtio_enqueue_reserve */
+ netq->netq_enqueue_failed.ev_count++;
+ vioif_net_unload_mbuf(vsc, map);
m_freem(m);
+ /* slot already freed by vioif_net_enqueue_tx */
+
if_statinc(ifp, if_oerrors);
continue;
}
- map->vnm_mbuf = m;
- hdr = map->vnm_hdr;
- memset(hdr, 0, sc->sc_hdr_size);
- bus_dmamap_sync(virtio_dmat(vsc), map->vnm_mbuf_map,
- 0, map->vnm_mbuf_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- bus_dmamap_sync(virtio_dmat(vsc), map->vnm_hdr_map,
- 0, map->vnm_hdr_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
- virtio_enqueue(vsc, vq, slot, map->vnm_hdr_map, true);
- virtio_enqueue(vsc, vq, slot, map->vnm_mbuf_map, true);
- virtio_enqueue_commit(vsc, vq, slot, false);
-
queued++;
bpf_mtap(ifp, m, BPF_D_OUT);
}
if (queued > 0) {
- virtio_enqueue_commit(vsc, vq, -1, true);
+ vioif_notify(vsc, vq);
ifp->if_timer = 5;
}
}
@@ -1569,6 +1541,147 @@
}
}
+static int
+vioif_net_load_mbuf(struct virtio_softc *vsc, struct vioif_net_map *map,
+ struct mbuf *m, int dma_flags)
+{
+ int r;
+
+ KASSERT(map->vnm_mbuf == NULL);
+
+ r = bus_dmamap_load_mbuf(virtio_dmat(vsc),
+ map->vnm_mbuf_map, m, dma_flags | BUS_DMA_NOWAIT);
+ if (r == 0) {
+ map->vnm_mbuf = m;
+ }
+
+ return r;
+}
+
+static void
+vioif_net_unload_mbuf(struct virtio_softc *vsc, struct vioif_net_map *map)
+{
+
+ KASSERT(map->vnm_mbuf != NULL);
+ bus_dmamap_unload(virtio_dmat(vsc), map->vnm_mbuf_map);
+ map->vnm_mbuf = NULL;
+}
+
+static int
+vioif_net_enqueue(struct virtio_softc *vsc, struct virtqueue *vq,
+ int slot, struct vioif_net_map *map, int dma_ops, bool is_write)
+{
+ int r;
+
+ KASSERT(map->vnm_mbuf != NULL);
+
+ /* This should actually never fail */
+ r = virtio_enqueue_reserve(vsc, vq, slot,
+ map->vnm_mbuf_map->dm_nsegs + 1);
+ if (r != 0) {
+ /* slot already freed by virtio_enqueue_reserve */
+ return r;
+ }
+
+ bus_dmamap_sync(virtio_dmat(vsc), map->vnm_mbuf_map,
+ 0, map->vnm_mbuf_map->dm_mapsize, dma_ops);
+ bus_dmamap_sync(virtio_dmat(vsc), map->vnm_hdr_map,
+ 0, map->vnm_hdr_map->dm_mapsize, dma_ops);
+
+ virtio_enqueue(vsc, vq, slot, map->vnm_hdr_map, is_write);
+ virtio_enqueue(vsc, vq, slot, map->vnm_mbuf_map, is_write);
+ virtio_enqueue_commit(vsc, vq, slot, false);
+
+ return 0;
+}
+
+static int
+vioif_net_enqueue_tx(struct virtio_softc *vsc, struct virtqueue *vq,
+ int slot, struct vioif_net_map *map)
+{
+
Home |
Main Index |
Thread Index |
Old Index