Skip to content

Commit 3103dbf

Browse files
authored
Merge pull request #57 from varnish/coldstart
Implement fast cold start feature
2 parents 8fd0b07 + 4cbd536 commit 3103dbf

File tree

11 files changed

+386
-1
lines changed

11 files changed

+386
-1
lines changed

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set (SOURCES
1818
tinykvm/machine_debug.cpp
1919
tinykvm/machine_elf.cpp
2020
tinykvm/machine_env.cpp
21+
tinykvm/machine_state.cpp
2122
tinykvm/machine_utils.cpp
2223
tinykvm/memory.cpp
2324
tinykvm/memory_bank.cpp

lib/tinykvm/common.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ namespace tinykvm
9696
bool executable_heap = false;
9797
/* Enable file-backed memory mappings for large files */
9898
bool mmap_backed_files = false;
99+
/* Enable fast cold start by file-mapping all physical memory
100+
to the given file. The file is created if it does not exist,
101+
and must be of the correct size if it does exist. */
102+
std::string fast_cold_start_file;
99103
/* When using hugepages, cover the given size with
100104
hugepages, unless 0, in which case the entire
101105
main memory will be covered. */

lib/tinykvm/linux/fds.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ namespace tinykvm
162162
}
163163
break;
164164
}
165+
case SocketType::INVALID:
166+
// Ignore invalid socket types (they cannot be reconstructed)
167+
break;
165168
default:
166169
fprintf(stderr, "TinyKVM: Unknown socket type %d\n", sp.type);
167170
throw std::runtime_error("TinyKVM: Unknown socket type");

lib/tinykvm/linux/fds.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ namespace tinykvm
5151
void set_vfd_start(int vfd_start) noexcept {
5252
m_next_fd = vfd_start;
5353
}
54+
int vfd_start() const noexcept {
55+
return m_next_fd;
56+
}
5457

5558
/// @brief Add a file descriptor to the list of managed FDs.
5659
/// @param fd The real file descriptor.
@@ -282,6 +285,7 @@ namespace tinykvm
282285
std::unordered_set<int> shared_epoll_fds;
283286
};
284287
EpollEntry& get_epoll_entry_for_vfd(int vfd);
288+
const auto& get_epoll_entries() const { return m_epoll_fds; }
285289
auto& get_epoll_entries() { return m_epoll_fds; }
286290
enum SocketType : int {
287291
INVALID,
@@ -298,8 +302,11 @@ namespace tinykvm
298302
SocketType type = INVALID;
299303
};
300304
void add_socket_pair(const SocketPair&);
305+
const auto& get_socket_pairs() const { return m_sockets; }
306+
auto& get_socket_pairs() { return m_sockets; }
301307

302308
std::string sockaddr_to_string(const struct sockaddr_storage& addr) const;
309+
303310
private:
304311
Machine& m_machine;
305312
std::map<int, Entry> m_fds;

lib/tinykvm/linux/threads.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ Thread* MultiThreading::get_thread(int tid) /* or nullptr */
123123
return &it->second;
124124
}
125125

126+
Thread& MultiThreading::create(int tid)
127+
{
128+
auto it = m_threads.try_emplace(tid, *this, tid, 0, 0);
129+
return it.first->second;
130+
}
131+
126132
Thread& MultiThreading::create(
127133
int flags, uint64_t ctid, uint64_t ptid, uint64_t stack, uint64_t tls)
128134
{

lib/tinykvm/linux/threads.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct MultiThreading {
2929
Thread* get_thread(int tid); /* or nullptr */
3030
int gettid() { return get_thread().tid; }
3131

32+
Thread& create(int tid);
3233
Thread& create(int flags, uint64_t ctid, uint64_t ptid,
3334
uint64_t stack, uint64_t tls);
3435
bool suspend_and_yield(int64_t result = 0);

lib/tinykvm/machine.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,29 @@ Machine::Machine(std::string_view binary, const MachineOptions& options)
3838
m_mt {nullptr} /* Explicitly */
3939
{
4040
assert(kvm_fd != -1 && "Call Machine::init() first");
41+
if (options.mmap_backed_files && !options.fast_cold_start_file.empty()) {
42+
throw MachineException("Cannot have fast cold start with mmap-backed files at the same time");
43+
}
4144

4245
this->fd = create_kvm_vm();
4346

4447
install_memory(0, memory.vmem(), false);
4548

49+
this->vcpu.init(0, *this, options);
50+
51+
if (memory.has_loadable_cold_start_state()) {
52+
if (this->load_cold_start_state()) {
53+
printf("Loaded fast cold start state\n");
54+
return;
55+
}
56+
// If the file does not exist, or anything else failed, we continue
57+
// to do a normal cold start.
58+
}
59+
4660
if (!binary.empty()) {
4761
this->elf_loader(binary, options);
4862
}
4963

50-
this->vcpu.init(0, *this, options);
5164
this->setup_long_mode(options);
5265

5366
/* We need to adjust BRK if the kernel end address is

lib/tinykvm/machine.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ struct Machine
295295
/* Migrates the VM to the current thread. Allows creating in
296296
one thread, and using it in another. */
297297
void migrate_to_this_thread();
298+
/* Store non-memory VM state to the already existing cold
299+
start state area in memory. Any failure will throw an
300+
exception. The memory must have been pre-allocated. */
301+
void save_cold_start_state_now() const;
302+
298303
static void init();
299304
static void setup_linux_system_calls(bool unsafe_syscalls = false);
300305
Machine(const std::vector<uint8_t>& binary, const MachineOptions&);
@@ -321,6 +326,7 @@ struct Machine
321326
void remote_update_gigapage_mappings(Machine& other, bool forced = false);
322327
/* Prepare for resume with a pagetable reload */
323328
void prepare_vmresume(address_t fsbase = 0, bool reload_pagetables = true);
329+
bool load_cold_start_state();
324330

325331
vCPU vcpu;
326332
int fd = 0;

0 commit comments

Comments
 (0)