Page MenuHomeFreeBSD

D60241.diff
No OneTemporary

D60241.diff

diff --git a/usr.sbin/bhyve/pci_e82545.c b/usr.sbin/bhyve/pci_e82545.c
--- a/usr.sbin/bhyve/pci_e82545.c
+++ b/usr.sbin/bhyve/pci_e82545.c
@@ -266,6 +266,7 @@
/* Interrupt control */
int esc_irq_asserted;
+ int esc_paused;
uint32_t esc_ICR; /* x00C0 cause read/clear */
uint32_t esc_ITR; /* x00C4 intr throttling */
uint32_t esc_ICS; /* x00C8 cause set */
@@ -842,6 +843,10 @@
pthread_mutex_lock(&sc->esc_mtx);
DPRINTF("rx_run: head %x, tail %x", sc->esc_RDH, sc->esc_RDT);
+ /* The packets wait in the backend until the resume. */
+ if (sc->esc_paused)
+ goto done1;
+
if (!sc->esc_rx_enabled || sc->esc_rx_loopback) {
DPRINTF("rx disabled (!%d || %d) -- packet(s) dropped",
sc->esc_rx_enabled, sc->esc_rx_loopback);
@@ -953,7 +958,7 @@
done:
pthread_mutex_lock(&sc->esc_mtx);
sc->esc_rx_active = 0;
- if (sc->esc_rx_enabled == 0)
+ if (sc->esc_rx_enabled == 0 || sc->esc_paused)
pthread_cond_signal(&sc->esc_rx_cond);
sc->esc_RDH = head;
@@ -1518,11 +1523,13 @@
pthread_mutex_lock(&sc->esc_mtx);
for (;;) {
- while (!sc->esc_tx_enabled || sc->esc_TDHr == sc->esc_TDT) {
- if (sc->esc_tx_enabled && sc->esc_TDHr != sc->esc_TDT)
+ while (sc->esc_paused || !sc->esc_tx_enabled ||
+ sc->esc_TDHr == sc->esc_TDT) {
+ if (!sc->esc_paused && sc->esc_tx_enabled &&
+ sc->esc_TDHr != sc->esc_TDT)
break;
sc->esc_tx_active = 0;
- if (sc->esc_tx_enabled == 0)
+ if (sc->esc_tx_enabled == 0 || sc->esc_paused)
pthread_cond_signal(&sc->esc_tx_cond);
pthread_cond_wait(&sc->esc_tx_cond, &sc->esc_mtx);
}
@@ -2481,7 +2488,7 @@
/* Has dependency on esc_RDLEN; reoreder of fields from struct. */
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(pi->pi_vmctx, sc->esc_rxdesc,
- sc->esc_TDLEN, true, meta, ret, done);
+ sc->esc_RDLEN, true, meta, ret, done);
/* IO Port register access */
SNAPSHOT_VAR_OR_LEAVE(sc->io_addr, meta, ret, done);
@@ -2533,6 +2540,49 @@
done:
return (ret);
}
+
+/*
+ * Receive and send nothing between a pause and the resume: the memory of the
+ * guest is saved before the state of the device, so a descriptor written in
+ * between would be missing in the snapshot while the ring's head has moved.
+ */
+static int
+e82545_pause(struct pci_devinst *pi)
+{
+ struct e82545_softc *sc;
+
+ sc = pi->pi_arg;
+
+ netbe_rx_disable(sc->esc_be);
+
+ pthread_mutex_lock(&sc->esc_mtx);
+ sc->esc_paused = 1;
+ while (sc->esc_rx_active)
+ pthread_cond_wait(&sc->esc_rx_cond, &sc->esc_mtx);
+ while (sc->esc_tx_active)
+ pthread_cond_wait(&sc->esc_tx_cond, &sc->esc_mtx);
+ pthread_mutex_unlock(&sc->esc_mtx);
+
+ return (0);
+}
+
+static int
+e82545_resume(struct pci_devinst *pi)
+{
+ struct e82545_softc *sc;
+
+ sc = pi->pi_arg;
+
+ /* Wake the transmit thread for the packets the guest has queued. */
+ pthread_mutex_lock(&sc->esc_mtx);
+ sc->esc_paused = 0;
+ pthread_cond_signal(&sc->esc_tx_cond);
+ pthread_mutex_unlock(&sc->esc_mtx);
+
+ netbe_rx_enable(sc->esc_be);
+
+ return (0);
+}
#endif
static const struct pci_devemu pci_de_e82545 = {
@@ -2543,6 +2593,8 @@
.pe_barread = e82545_read,
#ifdef BHYVE_SNAPSHOT
.pe_snapshot = e82545_snapshot,
+ .pe_pause = e82545_pause,
+ .pe_resume = e82545_resume,
#endif
};
PCI_EMUL_SET(pci_de_e82545);

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 3, 12:38 PM (10 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40123729
Default Alt Text
D60241.diff (3 KB)

Event Timeline