Page MenuHomeFreeBSD

D26267.id76464.diff
No OneTemporary

D26267.id76464.diff

Index: usr.sbin/bhyve/block_if.h
===================================================================
--- usr.sbin/bhyve/block_if.h
+++ usr.sbin/bhyve/block_if.h
@@ -80,8 +80,6 @@
#ifdef BHYVE_SNAPSHOT
void blockif_pause(struct blockif_ctxt *bc);
void blockif_resume(struct blockif_ctxt *bc);
-int blockif_snapshot_req(struct blockif_req *br,
- struct vm_snapshot_meta *meta);
int blockif_snapshot(struct blockif_ctxt *bc,
struct vm_snapshot_meta *meta);
#endif
Index: usr.sbin/bhyve/block_if.c
===================================================================
--- usr.sbin/bhyve/block_if.c
+++ usr.sbin/bhyve/block_if.c
@@ -107,11 +107,9 @@
int bc_psectoff;
int bc_closing;
int bc_paused;
- int bc_work_count;
pthread_t bc_btid[BLOCKIF_NUMTHR];
pthread_mutex_t bc_mtx;
pthread_cond_t bc_cond;
- pthread_cond_t bc_paused_cond;
pthread_cond_t bc_work_done_cond;
/* Request elements and free/pending/busy queues */
@@ -132,6 +130,12 @@
static struct blockif_sig_elem *blockif_bse_head;
+static inline bool
+bc_empty(const struct blockif_ctxt *bc)
+{
+ return (TAILQ_EMPTY(&bc->bc_pendq) && TAILQ_EMPTY(&bc->bc_busyq));
+}
+
static int
blockif_enqueue(struct blockif_ctxt *bc, struct blockif_req *breq,
enum blockop op)
@@ -361,30 +365,21 @@
pthread_mutex_lock(&bc->bc_mtx);
for (;;) {
- bc->bc_work_count++;
-
- /* We cannot process work if the interface is paused */
- while (!bc->bc_paused && blockif_dequeue(bc, t, &be)) {
+ while (blockif_dequeue(bc, t, &be)) {
pthread_mutex_unlock(&bc->bc_mtx);
blockif_proc(bc, be, buf);
pthread_mutex_lock(&bc->bc_mtx);
blockif_complete(bc, be);
}
- bc->bc_work_count--;
-
- /* If none of the workers are busy, notify the main thread */
- if (bc->bc_work_count == 0)
+ /* If none to work, notify the main thread */
+ if (bc_empty(bc))
pthread_cond_broadcast(&bc->bc_work_done_cond);
/* Check ctxt status here to see if exit requested */
if (bc->bc_closing)
break;
- /* Make all worker threads wait here if the device is paused */
- while (bc->bc_paused)
- pthread_cond_wait(&bc->bc_paused_cond, &bc->bc_mtx);
-
pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx);
}
pthread_mutex_unlock(&bc->bc_mtx);
@@ -594,8 +589,6 @@
pthread_mutex_init(&bc->bc_mtx, NULL);
pthread_cond_init(&bc->bc_cond, NULL);
bc->bc_paused = 0;
- bc->bc_work_count = 0;
- pthread_cond_init(&bc->bc_paused_cond, NULL);
pthread_cond_init(&bc->bc_work_done_cond, NULL);
TAILQ_INIT(&bc->bc_freeq);
TAILQ_INIT(&bc->bc_pendq);
@@ -628,6 +621,7 @@
err = 0;
pthread_mutex_lock(&bc->bc_mtx);
+ assert(!bc->bc_paused);
if (!TAILQ_EMPTY(&bc->bc_freeq)) {
/*
* Enqueue and inform the block i/o thread
@@ -652,7 +646,6 @@
int
blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (blockif_request(bc, breq, BOP_READ));
}
@@ -660,7 +653,6 @@
int
blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (blockif_request(bc, breq, BOP_WRITE));
}
@@ -668,7 +660,6 @@
int
blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (blockif_request(bc, breq, BOP_FLUSH));
}
@@ -676,7 +667,6 @@
int
blockif_delete(struct blockif_ctxt *bc, struct blockif_req *breq)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (blockif_request(bc, breq, BOP_DELETE));
}
@@ -844,7 +834,6 @@
off_t
blockif_size(struct blockif_ctxt *bc)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (bc->bc_size);
}
@@ -852,7 +841,6 @@
int
blockif_sectsz(struct blockif_ctxt *bc)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (bc->bc_sectsz);
}
@@ -860,7 +848,6 @@
void
blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
*size = bc->bc_psectsz;
*off = bc->bc_psectoff;
@@ -869,7 +856,6 @@
int
blockif_queuesz(struct blockif_ctxt *bc)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (BLOCKIF_MAXREQ - 1);
}
@@ -877,7 +863,6 @@
int
blockif_is_ro(struct blockif_ctxt *bc)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (bc->bc_rdonly);
}
@@ -885,7 +870,6 @@
int
blockif_candelete(struct blockif_ctxt *bc)
{
-
assert(bc->bc_magic == BLOCKIF_SIG);
return (bc->bc_candelete);
}
@@ -901,7 +885,7 @@
bc->bc_paused = 1;
/* The interface is paused. Wait for workers to finish their work */
- while (bc->bc_work_count)
+ while (!bc_empty(bc))
pthread_cond_wait(&bc->bc_work_done_cond, &bc->bc_mtx);
pthread_mutex_unlock(&bc->bc_mtx);
@@ -919,44 +903,11 @@
pthread_mutex_lock(&bc->bc_mtx);
bc->bc_paused = 0;
/* resume the threads waiting for paused */
- pthread_cond_broadcast(&bc->bc_paused_cond);
/* kick the threads after restore */
pthread_cond_broadcast(&bc->bc_cond);
pthread_mutex_unlock(&bc->bc_mtx);
}
-int
-blockif_snapshot_req(struct blockif_req *br, struct vm_snapshot_meta *meta)
-{
- int i;
- struct iovec *iov;
- int ret;
-
- SNAPSHOT_VAR_OR_LEAVE(br->br_iovcnt, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(br->br_offset, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(br->br_resid, meta, ret, done);
-
- /*
- * XXX: The callback and parameter must be filled by the virtualized
- * device that uses the interface, during its init; we're not touching
- * them here.
- */
-
- /* Snapshot the iovecs. */
- for (i = 0; i < br->br_iovcnt; i++) {
- iov = &br->br_iov[i];
-
- SNAPSHOT_VAR_OR_LEAVE(iov->iov_len, meta, ret, done);
-
- /* We assume the iov is a guest-mapped address. */
- SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(iov->iov_base, iov->iov_len,
- false, meta, ret, done);
- }
-
-done:
- return (ret);
-}
-
int
blockif_snapshot(struct blockif_ctxt *bc, struct vm_snapshot_meta *meta)
{
@@ -969,6 +920,7 @@
}
pthread_mutex_lock(&bc->bc_mtx);
+ assert(bc_empty(bc));
SNAPSHOT_VAR_OR_LEAVE(bc->bc_magic, meta, ret, done);
SNAPSHOT_VAR_OR_LEAVE(bc->bc_ischr, meta, ret, done);
Index: usr.sbin/bhyve/pci_ahci.c
===================================================================
--- usr.sbin/bhyve/pci_ahci.c
+++ usr.sbin/bhyve/pci_ahci.c
@@ -2526,104 +2526,6 @@
}
#ifdef BHYVE_SNAPSHOT
-static int
-pci_ahci_snapshot_save_queues(struct ahci_port *port,
- struct vm_snapshot_meta *meta)
-{
- int ret;
- int idx;
- struct ahci_ioreq *ioreq;
-
- STAILQ_FOREACH(ioreq, &port->iofhd, io_flist) {
- idx = ((void *) ioreq - (void *) port->ioreq) / sizeof(*ioreq);
- SNAPSHOT_VAR_OR_LEAVE(idx, meta, ret, done);
- }
-
- idx = -1;
- SNAPSHOT_VAR_OR_LEAVE(idx, meta, ret, done);
-
- TAILQ_FOREACH(ioreq, &port->iobhd, io_blist) {
- idx = ((void *) ioreq - (void *) port->ioreq) / sizeof(*ioreq);
- SNAPSHOT_VAR_OR_LEAVE(idx, meta, ret, done);
-
- /*
- * Snapshot only the busy requests; other requests are
- * not valid.
- */
- ret = blockif_snapshot_req(&ioreq->io_req, meta);
- if (ret != 0) {
- fprintf(stderr, "%s: failed to snapshot req\r\n",
- __func__);
- goto done;
- }
- }
-
- idx = -1;
- SNAPSHOT_VAR_OR_LEAVE(idx, meta, ret, done);
-
-done:
- return (ret);
-}
-
-static int
-pci_ahci_snapshot_restore_queues(struct ahci_port *port,
- struct vm_snapshot_meta *meta)
-{
- int ret;
- int idx;
- struct ahci_ioreq *ioreq;
-
- /* Empty the free queue before restoring. */
- while (!STAILQ_EMPTY(&port->iofhd))
- STAILQ_REMOVE_HEAD(&port->iofhd, io_flist);
-
- /* Restore the free queue. */
- while (1) {
- SNAPSHOT_VAR_OR_LEAVE(idx, meta, ret, done);
- if (idx == -1)
- break;
-
- STAILQ_INSERT_TAIL(&port->iofhd, &port->ioreq[idx], io_flist);
- }
-
- /* Restore the busy queue. */
- while (1) {
- SNAPSHOT_VAR_OR_LEAVE(idx, meta, ret, done);
- if (idx == -1)
- break;
-
- ioreq = &port->ioreq[idx];
- TAILQ_INSERT_TAIL(&port->iobhd, ioreq, io_blist);
-
- /*
- * Restore only the busy requests; other requests are
- * not valid.
- */
- ret = blockif_snapshot_req(&ioreq->io_req, meta);
- if (ret != 0) {
- fprintf(stderr, "%s: failed to restore request\r\n",
- __func__);
- goto done;
- }
-
- /* Re-enqueue the requests in the block interface. */
- if (ioreq->readop)
- ret = blockif_read(port->bctx, &ioreq->io_req);
- else
- ret = blockif_write(port->bctx, &ioreq->io_req);
-
- if (ret != 0) {
- fprintf(stderr,
- "%s: failed to re-enqueue request\r\n",
- __func__);
- goto done;
- }
- }
-
-done:
- return (ret);
-}
-
static int
pci_ahci_snapshot(struct vm_snapshot_meta *meta)
{
@@ -2734,17 +2636,9 @@
SNAPSHOT_VAR_OR_LEAVE(ioreq->readop, meta, ret, done);
}
- /* Perform save / restore specific operations. */
- if (meta->op == VM_SNAPSHOT_SAVE) {
- ret = pci_ahci_snapshot_save_queues(port, meta);
- if (ret != 0)
- goto done;
- } else if (meta->op == VM_SNAPSHOT_RESTORE) {
- ret = pci_ahci_snapshot_restore_queues(port, meta);
- if (ret != 0)
- goto done;
- } else {
- ret = EINVAL;
+ if (!TAILQ_EMPTY(&port->iobhd)) {
+ fprintf(stderr, "%s: device is busy\n", __func__);
+ ret = EBUSY;
goto done;
}
@@ -2799,7 +2693,7 @@
return (0);
}
-#endif
+#endif /* BHYVE_SNAPSHOT */
/*
* Use separate emulation names to distinguish drive and atapi devices
Index: usr.sbin/bhyve/pci_virtio_block.c
===================================================================
--- usr.sbin/bhyve/pci_virtio_block.c
+++ usr.sbin/bhyve/pci_virtio_block.c
@@ -572,6 +572,8 @@
.pe_barread = vi_pci_read,
#ifdef BHYVE_SNAPSHOT
.pe_snapshot = vi_pci_snapshot,
+ .pe_pause = vi_pci_pause,
+ .pe_resume = vi_pci_resume,
#endif
};
PCI_EMUL_SET(pci_de_vblk);

File Metadata

Mime Type
text/plain
Expires
Thu, May 28, 10:28 AM (13 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33583491
Default Alt Text
D26267.id76464.diff (9 KB)

Event Timeline