diff options
author | Elie Kheirallah <khei@google.com> | 2023-10-23 19:10:37 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-10-23 19:10:37 +0000 |
commit | 4c88633a8cccd22a6cd9754c87b90337dcda7507 (patch) | |
tree | d559ec0e5fdd4a84b23978cd21635a10d39dad38 | |
parent | f7c85d76bd293788949b470db064c34e434998e1 (diff) | |
parent | 89da3783ed0748072d6c3187e2fa2d8a10b0766e (diff) | |
download | wmediumd-4c88633a8cccd22a6cd9754c87b90337dcda7507.tar.gz |
Add vhost-user snapshot support to wmediumd am: 89da3783ed
Original change: https://android-review.googlesource.com/c/platform/external/wmediumd/+/2759933
Change-Id: I72669d0783ca5e4df4d7f3d17d1cc375904bc611
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | wmediumd/inc/usfstl/vhostproto.h | 20 | ||||
-rw-r--r-- | wmediumd/lib/vhost.c | 58 |
2 files changed, 78 insertions, 0 deletions
diff --git a/wmediumd/inc/usfstl/vhostproto.h b/wmediumd/inc/usfstl/vhostproto.h index 4550179..579af54 100644 --- a/wmediumd/inc/usfstl/vhostproto.h +++ b/wmediumd/inc/usfstl/vhostproto.h @@ -8,6 +8,10 @@ #define MAX_REGIONS 8 +// For simplicity, we only support snapshotting a fixed number of queues. Should +// be equal to HWSIM_NUM_VQS. +#define NUM_SNAPSHOT_QUEUES 2 + /* these are from the vhost-user spec */ struct vhost_user_msg_hdr { @@ -29,11 +33,16 @@ struct vhost_user_region { uint64_t mmap_offset; }; +struct vhost_user_snapshot { + int8_t sleeping[NUM_SNAPSHOT_QUEUES]; +}; + struct vhost_user_msg { struct vhost_user_msg_hdr hdr; union { #define VHOST_USER_U64_VRING_IDX_MSK 0x7f #define VHOST_USER_U64_NO_FD 0x80 + int8_t i8; uint64_t u64; struct { uint32_t idx, num; @@ -63,6 +72,13 @@ struct vhost_user_msg { uint64_t size; uint64_t offset; } vring_area; + struct { + int8_t bool_store; + struct vhost_user_snapshot snapshot; + } __attribute__((packed)) snapshot_response; + struct { + struct vhost_user_snapshot snapshot; + } __attribute__((packed)) restore_request; } __attribute__((packed)) payload; }; @@ -82,6 +98,10 @@ struct vhost_user_msg { #define VHOST_USER_GET_CONFIG 24 #define VHOST_USER_VRING_KICK 35 #define VHOST_USER_GET_SHARED_MEMORY_REGIONS 41 +#define VHOST_USER_SLEEP 42 +#define VHOST_USER_WAKE 43 +#define VHOST_USER_SNAPSHOT 44 +#define VHOST_USER_RESTORE 45 #define VHOST_USER_SLAVE_CONFIG_CHANGE_MSG 2 #define VHOST_USER_SLAVE_VRING_CALL 4 diff --git a/wmediumd/lib/vhost.c b/wmediumd/lib/vhost.c index b6a7a70..7e177ac 100644 --- a/wmediumd/lib/vhost.c +++ b/wmediumd/lib/vhost.c @@ -41,6 +41,7 @@ struct usfstl_vhost_user_dev_int { struct { struct usfstl_loop_entry entry; bool enabled; + bool sleeping; bool triggered; struct vring virtq; int call_fd; @@ -673,6 +674,63 @@ static void usfstl_vhost_user_handle_msg(struct usfstl_loop_entry *entry) reply_len = sizeof(uint64_t); msg.payload.u64 = 0; break; + case VHOST_USER_SLEEP: + USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd"); + USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d"); + for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) { + if (dev->virtqs[virtq].enabled) { + dev->virtqs[virtq].enabled = false; + dev->virtqs[virtq].sleeping = true; + usfstl_loop_unregister(&dev->virtqs[virtq].entry); + } + } + break; + case VHOST_USER_WAKE: + USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd"); + USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d"); + // enable previously enabled queues on wake + for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) { + if (dev->virtqs[virtq].sleeping) { + dev->virtqs[virtq].enabled = true; + dev->virtqs[virtq].sleeping = false; + usfstl_loop_register(&dev->virtqs[virtq].entry); + // TODO: is this needed? + usfstl_vhost_user_virtq_kick(dev, virtq); + } + } + break; + case VHOST_USER_SNAPSHOT: { + USFSTL_ASSERT_EQ(len, (ssize_t)0, "%zd"); + USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d"); + for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) { + msg.payload.snapshot_response.snapshot.sleeping[virtq] = dev->virtqs[virtq].sleeping; + } + msg.payload.snapshot_response.bool_store = 1; + reply_len = (int)sizeof(msg.payload.snapshot_response); + break; + } + case VHOST_USER_RESTORE: { + int *fds; + USFSTL_ASSERT(len == (int)sizeof(msg.payload.restore_request)); + USFSTL_ASSERT_EQ(dev->ext.server->max_queues, NUM_SNAPSHOT_QUEUES, "%d"); + + fds = (int*)malloc(dev->ext.server->max_queues * sizeof(int)); + for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) { + fds[virtq] = -1; + } + usfstl_vhost_user_get_msg_fds(&msghdr, fds, 2); + + for (virtq = 0; virtq < dev->ext.server->max_queues; virtq++) { + dev->virtqs[virtq].sleeping = msg.payload.restore_request.snapshot.sleeping[virtq]; + dev->virtqs[virtq].entry.fd = fds[virtq]; + } + + free(fds); + + msg.payload.i8 = 1; // success + reply_len = sizeof(msg.payload.i8); + break; + } default: USFSTL_ASSERT(0, "Unsupported message: %d\n", msg.hdr.request); } |