diff options
| author | Michael Zeller <mike@mikezeller.net> | 2020-03-11 16:55:43 -0400 |
|---|---|---|
| committer | Patrick Mooney <pmooney@pfmooney.com> | 2020-05-22 23:32:53 +0000 |
| commit | 84659b24a533984de271059abf9a1092835d15a9 (patch) | |
| tree | a5b46d9b98d0d88ee35aeef492b48c1e84d82035 /usr/src/cmd/bhyve/pci_virtio_net.c | |
| parent | cf3ec608f736765ec9852eed5e611848a25de9a4 (diff) | |
| download | illumos-joyent-84659b24a533984de271059abf9a1092835d15a9.tar.gz | |
12735 bhyve upstream sync 2019 Sept
Reviewed by: Dan McDonald <danmcd@kebe.com>
Reviewed by: John Levon <john.levon@joyent.com>
Reviewed by: Patrick Mooney <pmooney@oxide.computer>
Approved by: Robert Mustacchi <rm@fingolfin.org>
Diffstat (limited to 'usr/src/cmd/bhyve/pci_virtio_net.c')
| -rw-r--r-- | usr/src/cmd/bhyve/pci_virtio_net.c | 132 |
1 files changed, 28 insertions, 104 deletions
diff --git a/usr/src/cmd/bhyve/pci_virtio_net.c b/usr/src/cmd/bhyve/pci_virtio_net.c index aa188a3e59..73f8aa0d6b 100644 --- a/usr/src/cmd/bhyve/pci_virtio_net.c +++ b/usr/src/cmd/bhyve/pci_virtio_net.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include <sys/select.h> #include <sys/uio.h> #include <sys/ioctl.h> -#include <machine/atomic.h> #include <net/ethernet.h> #ifdef __FreeBSD__ #ifndef NETMAP_WITH_LIBS @@ -89,6 +88,7 @@ __FBSDID("$FreeBSD$"); #include "mevent.h" #endif #include "virtio.h" +#include "net_utils.h" #define VTNET_RINGSZ 1024 @@ -176,14 +176,13 @@ struct pci_vtnet_softc { struct nm_desc *vsc_nmd; int vsc_rx_ready; - volatile int resetting; /* set and checked outside lock */ + int resetting; /* protected by tx_mtx */ uint64_t vsc_features; /* negotiated features */ struct virtio_net_config vsc_config; pthread_mutex_t rx_mtx; - int rx_in_progress; int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ @@ -215,62 +214,39 @@ static struct virtio_consts vtnet_vi_consts = { VTNET_S_HOSTCAPS, /* our capabilities */ }; -/* - * If the transmit thread is active then stall until it is done. - */ static void -pci_vtnet_txwait(struct pci_vtnet_softc *sc) +pci_vtnet_reset(void *vsc) { + struct pci_vtnet_softc *sc = vsc; + + DPRINTF(("vtnet: device reset requested !\n")); + + /* Acquire the RX lock to block RX processing. */ + pthread_mutex_lock(&sc->rx_mtx); + /* Set sc->resetting and give a chance to the TX thread to stop. */ pthread_mutex_lock(&sc->tx_mtx); + sc->resetting = 1; while (sc->tx_in_progress) { pthread_mutex_unlock(&sc->tx_mtx); usleep(10000); pthread_mutex_lock(&sc->tx_mtx); } - pthread_mutex_unlock(&sc->tx_mtx); -} - -/* - * If the receive thread is active then stall until it is done. - */ -static void -pci_vtnet_rxwait(struct pci_vtnet_softc *sc) -{ - - pthread_mutex_lock(&sc->rx_mtx); - while (sc->rx_in_progress) { - pthread_mutex_unlock(&sc->rx_mtx); - usleep(10000); - pthread_mutex_lock(&sc->rx_mtx); - } - pthread_mutex_unlock(&sc->rx_mtx); -} - -static void -pci_vtnet_reset(void *vsc) -{ - struct pci_vtnet_softc *sc = vsc; - - DPRINTF(("vtnet: device reset requested !\n")); - - sc->resetting = 1; - - /* - * Wait for the transmit and receive threads to finish their - * processing. - */ - pci_vtnet_txwait(sc); - pci_vtnet_rxwait(sc); sc->vsc_rx_ready = 0; sc->rx_merge = 1; sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); - /* now reset rings, MSI-X vectors, and negotiated capabilities */ + /* + * Now reset rings, MSI-X vectors, and negotiated capabilities. + * Do that with the TX lock held, since we need to reset + * sc->resetting. + */ vi_reset_dev(&sc->vsc_vs); sc->resetting = 0; + pthread_mutex_unlock(&sc->tx_mtx); + pthread_mutex_unlock(&sc->rx_mtx); } /* @@ -370,9 +346,9 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) /* * But, will be called when the rx ring hasn't yet - * been set up or the guest is resetting the device. + * been set up. */ - if (!sc->vsc_rx_ready || sc->resetting) { + if (!sc->vsc_rx_ready) { #ifdef __FreeBSD__ /* * Drop the packet and try later. @@ -580,9 +556,9 @@ pci_vtnet_netmap_rx(struct pci_vtnet_softc *sc) /* * But, will be called when the rx ring hasn't yet - * been set up or the guest is resetting the device. + * been set up. */ - if (!sc->vsc_rx_ready || sc->resetting) { + if (!sc->vsc_rx_ready) { /* * Drop the packet and try later. */ @@ -661,9 +637,7 @@ pci_vtnet_rx_callback(int fd, enum ev_type type, void *param) struct pci_vtnet_softc *sc = param; pthread_mutex_lock(&sc->rx_mtx); - sc->rx_in_progress = 1; sc->pci_vtnet_rx(sc); - sc->rx_in_progress = 0; pthread_mutex_unlock(&sc->rx_mtx); } @@ -685,9 +659,7 @@ pci_vtnet_poll_thread(void *param) continue; } pthread_mutex_lock(&sc->vsc_mtx); - sc->rx_in_progress = 1; pci_vtnet_tap_rx(sc); - sc->rx_in_progress = 0; pthread_mutex_unlock(&sc->vsc_mtx); } @@ -705,7 +677,7 @@ pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) */ if (sc->vsc_rx_ready == 0) { sc->vsc_rx_ready = 1; - vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + vq_kick_disable(vq); } } @@ -751,7 +723,7 @@ pci_vtnet_ping_txq(void *vsc, struct vqueue_info *vq) /* Signal the tx thread for processing */ pthread_mutex_lock(&sc->tx_mtx); - vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + vq_kick_disable(vq); if (sc->tx_in_progress == 0) pthread_cond_signal(&sc->tx_cond); pthread_mutex_unlock(&sc->tx_mtx); @@ -780,8 +752,7 @@ pci_vtnet_tx_thread(void *param) for (;;) { /* note - tx mutex is locked here */ while (sc->resetting || !vq_has_descs(vq)) { - vq->vq_used->vu_flags &= ~VRING_USED_F_NO_NOTIFY; - mb(); + vq_kick_enable(vq); if (!sc->resetting && vq_has_descs(vq)) break; @@ -789,7 +760,7 @@ pci_vtnet_tx_thread(void *param) error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); assert(error == 0); } - vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + vq_kick_disable(vq); sc->tx_in_progress = 1; pthread_mutex_unlock(&sc->tx_mtx); @@ -821,31 +792,6 @@ pci_vtnet_ping_ctlq(void *vsc, struct vqueue_info *vq) } #endif /* __FreeBSD__ */ -#ifdef __FreeBSD__ -static int -pci_vtnet_parsemac(char *mac_str, uint8_t *mac_addr) -{ - struct ether_addr *ea; - char *tmpstr; - char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; - - tmpstr = strsep(&mac_str,"="); - - if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { - ea = ether_aton(mac_str); - - if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || - memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { - fprintf(stderr, "Invalid MAC %s\n", mac_str); - return (EINVAL); - } else - memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); - } - - return (0); -} -#endif /* __FreeBSD__ */ - static void pci_vtnet_tap_setup(struct pci_vtnet_softc *sc, char *devname) { @@ -968,11 +914,6 @@ pci_vtnet_netmap_setup(struct pci_vtnet_softc *sc, char *ifname) static int pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { -#ifdef __FreeBSD__ - MD5_CTX mdctx; - unsigned char digest[16]; - char nstr[80]; -#endif char tname[MAXCOMLEN + 1]; struct pci_vtnet_softc *sc; const char *env_msi; @@ -1027,7 +968,7 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) #ifdef __FreBSD__ if (vtopts != NULL) { - err = pci_vtnet_parsemac(vtopts, sc->vsc_config.mac); + err = net_parsemac(vtopts, sc->vsc_config.mac); if (err != 0) { free(devname); return (err); @@ -1048,24 +989,8 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) } #ifdef __FreeBSD__ - /* - * The default MAC address is the standard NetApp OUI of 00-a0-98, - * followed by an MD5 of the PCI slot/func number and dev name - */ if (!mac_provided) { - snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, - pi->pi_func, vmname); - - MD5Init(&mdctx); - MD5Update(&mdctx, nstr, strlen(nstr)); - MD5Final(digest, &mdctx); - - sc->vsc_config.mac[0] = 0x00; - sc->vsc_config.mac[1] = 0xa0; - sc->vsc_config.mac[2] = 0x98; - sc->vsc_config.mac[3] = digest[0]; - sc->vsc_config.mac[4] = digest[1]; - sc->vsc_config.mac[5] = digest[2]; + net_genmac(pi, sc->vsc_config.mac); } #endif @@ -1095,7 +1020,6 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) sc->rx_merge = 1; sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); - sc->rx_in_progress = 0; pthread_mutex_init(&sc->rx_mtx, NULL); /* |
