summaryrefslogtreecommitdiffstats
path: root/vhost_user_loopback.h
diff options
context:
space:
mode:
Diffstat (limited to 'vhost_user_loopback.h')
-rw-r--r--vhost_user_loopback.h147
1 files changed, 144 insertions, 3 deletions
diff --git a/vhost_user_loopback.h b/vhost_user_loopback.h
index a56a1d2..45b6206 100644
--- a/vhost_user_loopback.h
+++ b/vhost_user_loopback.h
@@ -34,6 +34,7 @@
#include <linux/vhost.h>
#include <pthread.h>
#include "virtio_loopback.h"
+#include "queue.h"
typedef struct adapter_dev {
struct vhost_dev *vdev;
@@ -42,6 +43,15 @@ typedef struct adapter_dev {
VirtioBus *vbus;
} AdapterDev;
+
+
+
+struct scrub_regions {
+ struct vhost_memory_region *region;
+ int reg_idx;
+ int fd_idx;
+};
+
struct vhost_virtqueue {
int kick;
int call;
@@ -64,8 +74,25 @@ typedef struct VhostDevConfigOps {
int (*vhost_dev_config_notifier)(struct vhost_dev *dev);
} VhostDevConfigOps;
+
+typedef struct MemoryRegion MemoryRegion;
+
+typedef struct MemoryRegionSection {
+ uint64_t size;
+ MemoryRegion *mr;
+ uint64_t offset_within_region;
+ uint64_t offset_within_address_space;
+ bool readonly;
+ bool nonvolatile;
+} MemoryRegionSection;
+
struct vhost_dev {
VirtIODevice *vdev;
+ struct vhost_memory *mem;
+ int n_mem_sections;
+ MemoryRegionSection *mem_sections;
+ int n_tmp_sections;
+ MemoryRegionSection *tmp_sections;
struct vhost_virtqueue *vqs;
unsigned int nvqs;
/* the first virtqueue which would be used by this vhost dev */
@@ -73,7 +100,7 @@ struct vhost_dev {
/* one past the last vq index for the virtio device (not vhost) */
int vq_index_end;
/* if non-zero, minimum required value for max_queues */
- uint64_t num_queues;
+ int num_queues;
uint64_t features;
uint64_t acked_features;
uint64_t backend_features;
@@ -84,19 +111,128 @@ struct vhost_dev {
bool log_enabled;
uint64_t log_size;
void *migration_blocker;
- /* Vhost-user struct */
+ void *opaque;
+ struct vhost_log *log;
+ QLIST_ENTRY(vhost_dev) entry;
uint64_t memory_slots;
const VhostDevConfigOps *config_ops;
};
+
+#define VHOST_USER_MAX_RAM_SLOTS 512
+
+typedef uint64_t ram_addr_t;
+typedef struct RAMBlock RAMBlock;
+
+typedef struct RAMBlock {
+ struct MemoryRegion *mr;
+ uint8_t *host;
+ uint8_t *colo_cache; /* For colo, VM's ram cache */
+ ram_addr_t offset;
+ ram_addr_t used_length;
+ ram_addr_t max_length;
+ void (*resized)(const char*, uint64_t length, void *host);
+ uint32_t flags;
+ /* Protected by iothread lock. */
+ char idstr[256];
+ /* RCU-enabled, writes protected by the ramlist lock */
+ int fd;
+ size_t page_size;
+ /* dirty bitmap used during migration */
+ unsigned long *bmap;
+ /* bitmap of already received pages in postcopy */
+ unsigned long *receivedmap;
+
+ /*
+ * bitmap to track already cleared dirty bitmap. When the bit is
+ * set, it means the corresponding memory chunk needs a log-clear.
+ * Set this up to non-NULL to enable the capability to postpone
+ * and split clearing of dirty bitmap on the remote node (e.g.,
+ * KVM). The bitmap will be set only when doing global sync.
+ *
+ * NOTE: this bitmap is different comparing to the other bitmaps
+ * in that one bit can represent multiple guest pages (which is
+ * decided by the `clear_bmap_shift' variable below). On
+ * destination side, this should always be NULL, and the variable
+ * `clear_bmap_shift' is meaningless.
+ */
+ unsigned long *clear_bmap;
+ uint8_t clear_bmap_shift;
+
+ /*
+ * RAM block length that corresponds to the used_length on the migration
+ * source (after RAM block sizes were synchronized). Especially, after
+ * starting to run the guest, used_length and postcopy_length can differ.
+ * Used to register/unregister uffd handlers and as the size of the received
+ * bitmap. Receiving any page beyond this length will bail out, as it
+ * could not have been valid on the source.
+ */
+ ram_addr_t postcopy_length;
+} RAMBlock;
+
+
+/*
+ * MemoryRegion:
+ *
+ * A struct representing a memory region.
+ */
+typedef struct MemoryRegion {
+ /* private: */
+
+ /* The following fields should fit in a cache line */
+ bool romd_mode;
+ bool ram;
+ bool subpage;
+ bool readonly; /* For RAM regions */
+ bool nonvolatile;
+ bool rom_device;
+ bool flush_coalesced_mmio;
+ uint8_t dirty_log_mask;
+ bool is_iommu;
+ RAMBlock *ram_block;
+
+ void *opaque;
+ MemoryRegion *container;
+ uint64_t size;
+ uint64_t addr;
+ void (*destructor)(MemoryRegion *mr);
+ uint64_t align;
+ bool terminates;
+ bool ram_device;
+ bool enabled;
+ bool warning_printed; /* For reservations */
+ uint8_t vga_logging_count;
+ MemoryRegion *alias;
+ uint64_t alias_offset;
+ int32_t priority;
+ QTAILQ_HEAD(, MemoryRegion) subregions;
+ QTAILQ_ENTRY(MemoryRegion) subregions_link;
+ const char *name;
+ unsigned ioeventfd_nb;
+} MemoryRegion;
+
struct vhost_user {
struct vhost_dev *dev;
+
+ /* Shared between vhost devs of the same virtio device */
+
+ uint64_t postcopy_client_bases[VHOST_USER_MAX_RAM_SLOTS];
/* Length of the region_rb and region_rb_offset arrays */
size_t region_rb_len;
+ /* RAMBlock associated with a given region */
+ RAMBlock **region_rb;
+ /*
+ * The offset from the start of the RAMBlock to the start of the
+ * vhost region.
+ */
+ ram_addr_t *region_rb_offset;
+
/* True once we've entered postcopy_listen */
bool postcopy_listen;
+
/* Our current regions */
int num_shadow_regions;
+ struct vhost_memory_region shadow_regions[VHOST_USER_MAX_RAM_SLOTS];
};
/* Global variables */
@@ -118,7 +254,6 @@ extern struct vhost_user *vudev;
* Set a reasonable maximum number of ram slots, which will be supported by
* any architecture.
*/
-#define VHOST_USER_MAX_RAM_SLOTS 32
#define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
/*
@@ -809,6 +944,12 @@ int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data,
uint32_t offset, uint32_t size, uint32_t flags);
+void vhost_commit_init_vqs(struct vhost_dev *dev);
+void vhost_commit_vqs(struct vhost_dev *dev);
+void find_add_new_reg(struct vhost_dev *dev);
+void print_mem_table(struct vhost_dev *dev);
+
+
/* FIXME: This need to move in a better place */
struct vhost_inflight;
int vhost_user_get_inflight_fd(struct vhost_dev *dev,