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