Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F158007034
D26267.id76464.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D26267.id76464.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D26267: bhyve: snapshot impovements for 'blockif' backend
Attached
Detach File
Event Timeline
Log In to Comment