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): reorganize functions



details:   https://anonhg.NetBSD.org/src/rev/9800cb549df6
branches:  trunk
changeset: 373970:9800cb549df6
user:      yamaguchi <yamaguchi%NetBSD.org@localhost>
date:      Thu Mar 23 02:57:54 2023 +0000

description:
vioif(4): reorganize functions

iThis change is move of function and rename,
and this is no functional change.

diffstat:

 sys/dev/pci/if_vioif.c |  2706 +++++++++++++++++++++++------------------------
 1 files changed, 1347 insertions(+), 1359 deletions(-)

diffs (truncated from 2955 to 300 lines):

diff -r 4b648a600fcc -r 9800cb549df6 sys/dev/pci/if_vioif.c
--- a/sys/dev/pci/if_vioif.c    Thu Mar 23 02:52:29 2023 +0000
+++ b/sys/dev/pci/if_vioif.c    Thu Mar 23 02:57:54 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_vioif.c,v 1.100 2023/03/23 02:52:29 yamaguchi Exp $ */
+/*     $NetBSD: if_vioif.c,v 1.101 2023/03/23 02:57:54 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.100 2023/03/23 02:52:29 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.101 2023/03/23 02:57:54 yamaguchi Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -330,7 +330,7 @@
        void                    *sc_dmamem;
        void                    *sc_kmem;
 
-       void                    *sc_ctl_softint;
+       void                    *sc_cfg_softint;
 
        struct workqueue        *sc_txrx_workqueue;
        bool                     sc_txrx_workqueue_sysctl;
@@ -360,82 +360,87 @@
 static int     vioif_init(struct ifnet *);
 static void    vioif_stop(struct ifnet *, int);
 static void    vioif_start(struct ifnet *);
-static void    vioif_start_locked(struct ifnet *, struct vioif_netqueue *);
 static int     vioif_transmit(struct ifnet *, struct mbuf *);
-static void    vioif_transmit_locked(struct ifnet *, struct vioif_netqueue *);
 static int     vioif_ioctl(struct ifnet *, u_long, void *);
 static void    vioif_watchdog(struct ifnet *);
+static int     vioif_ifflags(struct vioif_softc *);
 static int     vioif_ifflags_cb(struct ethercom *);
 
 /* 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 int     vioif_netqueue_init(struct vioif_softc *,
+                   struct virtio_softc *, size_t, u_int);
+static void    vioif_netqueue_teardown(struct vioif_softc *,
+                   struct virtio_softc *, size_t);
 static void    vioif_net_intr_enable(struct vioif_softc *,
                    struct virtio_softc *);
 static void    vioif_net_intr_disable(struct vioif_softc *,
                    struct virtio_softc *);
+static void    vioif_net_sched_handle(struct vioif_softc *,
+                   struct vioif_netqueue *);
 
 /* rx */
 static void    vioif_populate_rx_mbufs_locked(struct vioif_softc *,
                    struct vioif_netqueue *);
-static void    vioif_rx_queue_clear(struct vioif_softc *, struct virtio_softc *,
-                   struct vioif_netqueue *);
-static bool    vioif_rx_deq_locked(struct vioif_softc *, struct virtio_softc *,
-                   struct vioif_netqueue *, u_int, size_t *);
 static int     vioif_rx_intr(void *);
 static void    vioif_rx_handle(void *);
+static void    vioif_rx_queue_clear(struct vioif_softc *,
+                   struct virtio_softc *, struct vioif_netqueue *);
 
 /* tx */
+static void    vioif_start_locked(struct ifnet *, struct vioif_netqueue *);
+static void    vioif_transmit_locked(struct ifnet *, struct vioif_netqueue *);
+static void    vioif_deferred_transmit(void *);
 static int     vioif_tx_intr(void *);
 static void    vioif_tx_handle(void *);
 static void    vioif_tx_queue_clear(struct vioif_softc *, struct virtio_softc *,
                    struct vioif_netqueue *);
-static bool    vioif_tx_deq_locked(struct vioif_softc *, struct virtio_softc *,
-                   struct vioif_netqueue *, u_int);
-static void    vioif_deferred_transmit(void *);
-
-/* workqueue */
-static struct workqueue*
-               vioif_workq_create(const char *, pri_t, int, int);
-static void    vioif_workq_destroy(struct workqueue *);
-static void    vioif_workq_work(struct work *, void *);
-static void    vioif_work_set(struct vioif_work *, void(*)(void *), void *);
-static void    vioif_work_add(struct workqueue *, struct vioif_work *);
-static void    vioif_work_wait(struct workqueue *, struct vioif_work *);
-
-/* other control */
-static int     vioif_get_link_status(struct vioif_softc *);
-static void    vioif_update_link_status(struct vioif_softc *);
+
+/* controls */
+static int     vioif_ctrl_intr(void *);
 static int     vioif_ctrl_rx(struct vioif_softc *, int, bool);
 static int     vioif_set_promisc(struct vioif_softc *, bool);
 static int     vioif_set_allmulti(struct vioif_softc *, bool);
 static int     vioif_set_rx_filter(struct vioif_softc *);
 static int     vioif_rx_filter(struct vioif_softc *);
 static int     vioif_set_mac_addr(struct vioif_softc *);
-static int     vioif_ctrl_intr(void *);
+static int     vioif_ctrl_mq_vq_pairs_set(struct vioif_softc *, int);
+
+/* config interrupt */
 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_cfg_softint(void *);
+static void    vioif_update_link_status(struct vioif_softc *);
+
+/* others */
+static void    vioif_alloc_queues(struct vioif_softc *);
+static void    vioif_free_queues(struct vioif_softc *);
+static int     vioif_alloc_mems(struct vioif_softc *);
+static struct workqueue*
+               vioif_workq_create(const char *, pri_t, int, int);
+static void    vioif_workq_destroy(struct workqueue *);
+static void    vioif_work_set(struct vioif_work *, void(*)(void *), void *);
+static void    vioif_work_add(struct workqueue *, struct vioif_work *);
+static void    vioif_work_wait(struct workqueue *, struct vioif_work *);
 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);
 
+static void
+vioif_intr_barrier(void)
+{
+
+       /* wait for finish all interrupt handler */
+       xc_barrier(0);
+}
+
+static void
+vioif_notify(struct virtio_softc *vsc, struct virtqueue *vq)
+{
+
+       virtio_enqueue_commit(vsc, vq, -1, true);
+}
+
 static int
 vioif_match(device_t parent, cfdata_t match, void *aux)
 {
@@ -447,6 +452,610 @@
        return 0;
 }
 
+static void
+vioif_attach(device_t parent, device_t self, void *aux)
+{
+       struct vioif_softc *sc = device_private(self);
+       struct virtio_softc *vsc = device_private(parent);
+       struct vioif_netqueue *txq0;
+       struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
+       uint64_t features, req_features;
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       u_int softint_flags;
+       int r, i, req_flags;
+       char xnamebuf[MAXCOMLEN];
+       size_t netq_num;
+
+       if (virtio_child(vsc) != NULL) {
+               aprint_normal(": child already attached for %s; "
+                   "something wrong...\n", device_xname(parent));
+               return;
+       }
+
+       sc->sc_dev = self;
+       sc->sc_virtio = vsc;
+       sc->sc_link_state = LINK_STATE_UNKNOWN;
+
+       sc->sc_max_nvq_pairs = 1;
+       sc->sc_req_nvq_pairs = 1;
+       sc->sc_act_nvq_pairs = 1;
+       sc->sc_txrx_workqueue_sysctl = true;
+       sc->sc_tx_intr_process_limit = VIOIF_TX_INTR_PROCESS_LIMIT;
+       sc->sc_tx_process_limit = VIOIF_TX_PROCESS_LIMIT;
+       sc->sc_rx_intr_process_limit = VIOIF_RX_INTR_PROCESS_LIMIT;
+       sc->sc_rx_process_limit = VIOIF_RX_PROCESS_LIMIT;
+
+       mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+
+       snprintf(xnamebuf, sizeof(xnamebuf), "%s_txrx", device_xname(self));
+       sc->sc_txrx_workqueue = vioif_workq_create(xnamebuf, VIOIF_WORKQUEUE_PRI,
+           IPL_NET, WQ_PERCPU | WQ_MPSAFE);
+       if (sc->sc_txrx_workqueue == NULL)
+               goto err;
+
+       req_flags = 0;
+
+#ifdef VIOIF_MPSAFE
+       req_flags |= VIRTIO_F_INTR_MPSAFE;
+#endif
+       req_flags |= VIRTIO_F_INTR_MSIX;
+
+       req_features =
+           VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ |
+           VIRTIO_NET_F_CTRL_RX | VIRTIO_F_NOTIFY_ON_EMPTY;
+       req_features |= VIRTIO_F_RING_EVENT_IDX;
+       req_features |= VIRTIO_NET_F_CTRL_MAC_ADDR;
+#ifdef VIOIF_MULTIQ
+       req_features |= VIRTIO_NET_F_MQ;
+#endif
+       virtio_child_attach_start(vsc, self, IPL_NET, NULL,
+           vioif_config_change, virtio_vq_intrhand, req_flags,
+           req_features, VIRTIO_NET_FLAG_BITS);
+
+       features = virtio_features(vsc);
+       if (features == 0)
+               goto err;
+
+       if (features & VIRTIO_NET_F_MAC) {
+               for (i = 0; i < __arraycount(sc->sc_mac); i++) {
+                       sc->sc_mac[i] = virtio_read_device_config_1(vsc,
+                           VIRTIO_NET_CONFIG_MAC + i);
+               }
+       } else {
+               /* code stolen from sys/net/if_tap.c */
+               struct timeval tv;
+               uint32_t ui;
+               getmicrouptime(&tv);
+               ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff;
+               memcpy(sc->sc_mac+3, (uint8_t *)&ui, 3);
+               for (i = 0; i < __arraycount(sc->sc_mac); i++) {
+                       virtio_write_device_config_1(vsc,
+                           VIRTIO_NET_CONFIG_MAC + i, sc->sc_mac[i]);
+               }
+       }
+
+       /* 'Ethernet' with capital follows other ethernet driver attachment */
+       aprint_normal_dev(self, "Ethernet address %s\n",
+           ether_sprintf(sc->sc_mac));
+
+       if (features & (VIRTIO_NET_F_MRG_RXBUF | VIRTIO_F_VERSION_1)) {
+               sc->sc_hdr_size = sizeof(struct virtio_net_hdr);
+       } else {
+               sc->sc_hdr_size = offsetof(struct virtio_net_hdr, num_buffers);
+       }
+
+       if ((features & VIRTIO_NET_F_CTRL_VQ) &&
+           (features & VIRTIO_NET_F_CTRL_RX)) {
+               sc->sc_has_ctrl = true;
+
+               cv_init(&ctrlq->ctrlq_wait, "ctrl_vq");
+               mutex_init(&ctrlq->ctrlq_wait_lock, MUTEX_DEFAULT, IPL_NET);
+               ctrlq->ctrlq_inuse = FREE;
+       } else {
+               sc->sc_has_ctrl = false;
+       }
+
+       if (sc->sc_has_ctrl && (features & VIRTIO_NET_F_MQ)) {
+               sc->sc_max_nvq_pairs = virtio_read_device_config_2(vsc,
+                   VIRTIO_NET_CONFIG_MAX_VQ_PAIRS);
+
+               if (sc->sc_max_nvq_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX)
+                       goto err;
+
+               /* Limit the number of queue pairs to use */
+               sc->sc_req_nvq_pairs = MIN(sc->sc_max_nvq_pairs, ncpu);
+       }
+
+       vioif_alloc_queues(sc);
+       virtio_child_attach_set_vqs(vsc, sc->sc_vqs, sc->sc_req_nvq_pairs);
+
+#ifdef VIOIF_MPSAFE
+       softint_flags = SOFTINT_NET | SOFTINT_MPSAFE;
+#else
+       softint_flags = SOFTINT_NET;
+#endif
+
+       /*
+        * Initialize network queues
+        */
+       netq_num = sc->sc_max_nvq_pairs * 2;
+       for (i = 0; i < netq_num; i++) {
+               r = vioif_netqueue_init(sc, vsc, i, softint_flags);
+               if (r != 0)
+                       goto err;
+       }
+
+       if (sc->sc_has_ctrl) {
+               int ctrlq_idx = sc->sc_max_nvq_pairs * 2;
+               /*
+                * Allocating a virtqueue for control channel
+                */
+               sc->sc_ctrlq.ctrlq_vq = &sc->sc_vqs[ctrlq_idx];
+               r = virtio_alloc_vq(vsc, ctrlq->ctrlq_vq, ctrlq_idx,



Home | Main Index | Thread Index | Old Index