summaryrefslogtreecommitdiff
path: root/usr/src/cmd/bhyve/pci_virtio_net.c
diff options
context:
space:
mode:
authorMichael Zeller <mike@mikezeller.net>2020-03-11 16:55:43 -0400
committerPatrick Mooney <pmooney@pfmooney.com>2020-05-22 23:32:53 +0000
commit84659b24a533984de271059abf9a1092835d15a9 (patch)
treea5b46d9b98d0d88ee35aeef492b48c1e84d82035 /usr/src/cmd/bhyve/pci_virtio_net.c
parentcf3ec608f736765ec9852eed5e611848a25de9a4 (diff)
downloadillumos-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.c132
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);
/*