Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174338263
D60241.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D60241.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D60241: bhyve: e82545: pause the device for a snapshot
Attached
Detach File
Event Timeline
Log In to Comment