From de74c92736a83f89b47de30f7603e25d4f6687a5 Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Tue, 19 Dec 2017 00:16:43 +0100 Subject: [PATCH] one step toward a live migration plugin have dirty page tracking in a separate plugin (kernel) and stop have dirty page stuff when VM and Migration are not used. Indeed, this plugin is only needed if vm have to be migrated live. In that case, one should: 1) #include "simgrid/plugins/live_migration.h" 2) call "MSG/sg_vm_live_migration_plugin_init() right after the initialization of the simulation (MSG_init or s4u::Engine) --- examples/msg/cloud-capping/cloud-capping.c | 2 + .../cloud-masterworker/cloud-masterworker.c | 3 + .../msg/cloud-migration/cloud-migration.c | 2 + include/simgrid/plugins/live_migration.h | 24 ++++ include/simgrid/s4u/VirtualMachine.hpp | 3 - src/msg/msg_gos.cpp | 9 +- src/msg/msg_private.hpp | 3 - src/msg/msg_task.cpp | 1 - src/msg/msg_vm.cpp | 133 ++---------------- src/plugins/vm/VirtualMachineImpl.cpp | 25 +--- src/plugins/vm/VirtualMachineImpl.hpp | 43 +++--- src/plugins/vm/s4u_VirtualMachine.cpp | 6 - src/surf/plugins/dirty_page_tracking.cpp | 120 ++++++++++++++++ teshsuite/msg/cloud-simple/cloud-simple.c | 3 + tools/cmake/DefinePackages.cmake | 4 +- 15 files changed, 189 insertions(+), 192 deletions(-) create mode 100644 include/simgrid/plugins/live_migration.h create mode 100644 src/surf/plugins/dirty_page_tracking.cpp diff --git a/examples/msg/cloud-capping/cloud-capping.c b/examples/msg/cloud-capping/cloud-capping.c index 44710342a7..5ef1028476 100644 --- a/examples/msg/cloud-capping/cloud-capping.c +++ b/examples/msg/cloud-capping/cloud-capping.c @@ -4,6 +4,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/msg.h" +#include "simgrid/plugins/live_migration.h" XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example"); @@ -296,6 +297,7 @@ int main(int argc, char *argv[]) { /* Get the arguments */ MSG_init(&argc, argv); + MSG_vm_live_migration_plugin_init(); /* load the platform file */ xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/small_platform.xml\n", argv[0], argv[0]); diff --git a/examples/msg/cloud-masterworker/cloud-masterworker.c b/examples/msg/cloud-masterworker/cloud-masterworker.c index 12044addc3..07c7556a52 100644 --- a/examples/msg/cloud-masterworker/cloud-masterworker.c +++ b/examples/msg/cloud-masterworker/cloud-masterworker.c @@ -4,6 +4,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/msg.h" +#include "simgrid/plugins/live_migration.h" XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example"); @@ -175,6 +176,8 @@ int main(int argc, char *argv[]) const int nb_workers = 2; MSG_init(&argc, argv); + MSG_vm_live_migration_plugin_init(); + xbt_assert(argc >1,"Usage: %s example/platforms/cluster.xml\n", argv[0]); /* Load the platform file */ diff --git a/examples/msg/cloud-migration/cloud-migration.c b/examples/msg/cloud-migration/cloud-migration.c index 5fd214347b..2c13261011 100644 --- a/examples/msg/cloud-migration/cloud-migration.c +++ b/examples/msg/cloud-migration/cloud-migration.c @@ -5,6 +5,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/msg.h" +#include "simgrid/plugins/live_migration.h" XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example"); @@ -123,6 +124,7 @@ int main(int argc, char *argv[]) { /* Get the arguments */ MSG_init(&argc, argv); + MSG_vm_live_migration_plugin_init(); /* load the platform file */ MSG_create_environment(argv[1]); diff --git a/include/simgrid/plugins/live_migration.h b/include/simgrid/plugins/live_migration.h new file mode 100644 index 0000000000..e61bdb7860 --- /dev/null +++ b/include/simgrid/plugins/live_migration.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2017. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_PLUGINS_LIVE_MIGRATION_H_ +#define SIMGRID_PLUGINS_LIVE_MIGRATION_H_ + +#include +#include + +SG_BEGIN_DECL() + +XBT_PUBLIC(void) sg_vm_live_migration_plugin_init(); +XBT_PUBLIC(void) sg_vm_start_dirty_page_tracking(sg_vm_t vm); +XBT_PUBLIC(void) sg_vm_stop_dirty_page_tracking(sg_vm_t vm); +XBT_PUBLIC(double) sg_vm_lookup_computed_flops(sg_vm_t vm); + +#define MSG_vm_live_migration_plugin_init() sg_vm_live_migration_plugin_init() + +SG_END_DECL() + +#endif diff --git a/include/simgrid/s4u/VirtualMachine.hpp b/include/simgrid/s4u/VirtualMachine.hpp index 8dcfe49f42..a655e4905e 100644 --- a/include/simgrid/s4u/VirtualMachine.hpp +++ b/include/simgrid/s4u/VirtualMachine.hpp @@ -63,9 +63,6 @@ public: /* FIXME: protect me */ simgrid::vm::VirtualMachineImpl* pimpl_vm_ = nullptr; - - static simgrid::xbt::signal onCreation; - static simgrid::xbt::signal onDestruction; }; } } // namespace simgrid::s4u diff --git a/src/msg/msg_gos.cpp b/src/msg/msg_gos.cpp index e5dc66070a..ad50af0a1c 100644 --- a/src/msg/msg_gos.cpp +++ b/src/msg/msg_gos.cpp @@ -22,14 +22,7 @@ extern "C" { */ msg_error_t MSG_task_execute(msg_task_t task) { - /* TODO: add this to other locations */ - msg_host_t host = MSG_process_get_host(MSG_process_self()); - MSG_host_add_task(host, task); - - msg_error_t ret = MSG_parallel_task_execute(task); - - MSG_host_del_task(host, task); - return ret; + return MSG_parallel_task_execute(task); } /** \ingroup msg_task_usage diff --git a/src/msg/msg_private.hpp b/src/msg/msg_private.hpp index 9eb7d1ce93..49328acbe2 100644 --- a/src/msg/msg_private.hpp +++ b/src/msg/msg_private.hpp @@ -99,9 +99,6 @@ XBT_PRIVATE smx_actor_t MSG_process_create_from_SIMIX(const char* name, std::fun smx_actor_t parent_process); XBT_PRIVATE void MSG_comm_copy_data_from_SIMIX(smx_activity_t comm, void* buff, size_t buff_size); -XBT_PRIVATE void MSG_host_add_task(msg_host_t host, msg_task_t task); -XBT_PRIVATE void MSG_host_del_task(msg_host_t host, msg_task_t task); - /********** Tracing **********/ /* declaration of instrumentation functions from msg_task_instr.c */ XBT_PRIVATE void TRACE_msg_set_task_category(msg_task_t task, const char* category); diff --git a/src/msg/msg_task.cpp b/src/msg/msg_task.cpp index b71d7fa843..ae1f59c4e0 100644 --- a/src/msg/msg_task.cpp +++ b/src/msg/msg_task.cpp @@ -219,7 +219,6 @@ msg_error_t MSG_task_cancel(msg_task_t task) simdata_task_t simdata = task->simdata; if (simdata->compute) { simcall_execution_cancel(simdata->compute); - MSG_host_del_task(MSG_process_get_host(MSG_process_self()), task); } else if (simdata->comm) { simcall_comm_cancel(simdata->comm); } diff --git a/src/msg/msg_vm.cpp b/src/msg/msg_vm.cpp index 34ab03d4a7..e876a2603c 100644 --- a/src/msg/msg_vm.cpp +++ b/src/msg/msg_vm.cpp @@ -11,8 +11,8 @@ #include +#include "simgrid/plugins/live_migration.h" #include "src/instr/instr_private.hpp" -#include "src/msg/msg_private.hpp" #include "src/plugins/vm/VirtualMachineImpl.hpp" #include "src/plugins/vm/VmHostExt.hpp" @@ -22,13 +22,6 @@ extern "C" { -struct s_dirty_page { - double prev_clock = 0.0; - double prev_remaining = 0.0; - msg_task_t task = nullptr; -}; -typedef s_dirty_page* dirty_page_t; - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_vm, msg, "Cloud-oriented parts of the MSG API"); const char* MSG_vm_get_name(msg_vm_t vm) @@ -334,116 +327,6 @@ static int migration_rx_fun(int argc, char *argv[]) return 0; } -static void start_dirty_page_tracking(msg_vm_t vm) -{ - vm->pimpl_vm_->dp_enabled = true; - if (vm->pimpl_vm_->dp_objs.empty()) - return; - - for (auto const& elm : vm->pimpl_vm_->dp_objs) { - dirty_page_t dp = elm.second; - double remaining = MSG_task_get_flops_amount(dp->task); - dp->prev_clock = MSG_get_clock(); - dp->prev_remaining = remaining; - XBT_DEBUG("%s@%s remaining %f", elm.first.c_str(), vm->getCname(), remaining); - } -} - -static void stop_dirty_page_tracking(msg_vm_t vm) -{ - vm->pimpl_vm_->dp_enabled = false; -} - -static double get_computed(const std::string& key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock) -{ - double computed = dp->prev_remaining - remaining; - double duration = clock - dp->prev_clock; - - XBT_DEBUG("%s@%s: computed %f ops (remaining %f -> %f) in %f secs (%f -> %f)", key.c_str(), vm->getCname(), computed, - dp->prev_remaining, remaining, duration, dp->prev_clock, clock); - - return computed; -} - -static double lookup_computed_flop_counts(msg_vm_t vm, int stage_for_fancy_debug, int stage2_round_for_fancy_debug) -{ - double total = 0; - - for (auto const& elm : vm->pimpl_vm_->dp_objs) { - const std::string& key = elm.first; - dirty_page_t dp = elm.second; - double remaining = MSG_task_get_flops_amount(dp->task); - - double clock = MSG_get_clock(); - - total += get_computed(key, vm, dp, remaining, clock); - - dp->prev_remaining = remaining; - dp->prev_clock = clock; - } - - total += vm->pimpl_vm_->dp_updated_by_deleted_tasks; - - XBT_DEBUG("mig-stage%d.%d: computed %f flop_counts (including %f by deleted tasks)", stage_for_fancy_debug, - stage2_round_for_fancy_debug, total, vm->pimpl_vm_->dp_updated_by_deleted_tasks); - - vm->pimpl_vm_->dp_updated_by_deleted_tasks = 0; - - return total; -} - -// TODO Is this code redundant with the information provided by -// msg_process_t MSG_process_create(const char *name, xbt_main_func_t code, void *data, msg_host_t host) -/** @brief take care of the dirty page tracking, in case we're adding a task to a migrating VM */ -void MSG_host_add_task(msg_host_t host, msg_task_t task) -{ - simgrid::s4u::VirtualMachine* vm = dynamic_cast(host); - if (vm == nullptr) - return; - - double remaining = MSG_task_get_flops_amount(task); - std::string key = simgrid::xbt::string_printf("%s-%p", task->name, task); - - dirty_page_t dp = new s_dirty_page; - dp->task = task; - if (vm->pimpl_vm_->dp_enabled) { - dp->prev_clock = MSG_get_clock(); - dp->prev_remaining = remaining; - } - vm->pimpl_vm_->dp_objs.insert({key, dp}); - XBT_DEBUG("add %s on %s (remaining %f, dp_enabled %d)", key.c_str(), host->getCname(), remaining, - vm->pimpl_vm_->dp_enabled); -} - -void MSG_host_del_task(msg_host_t host, msg_task_t task) -{ - simgrid::s4u::VirtualMachine* vm = dynamic_cast(host); - if (vm == nullptr) - return; - - std::string key = simgrid::xbt::string_printf("%s-%p", task->name, task); - dirty_page_t dp = nullptr; - auto dp_obj = vm->pimpl_vm_->dp_objs.find(key); - if (dp_obj != vm->pimpl_vm_->dp_objs.end()) - dp = dp_obj->second; - xbt_assert(dp && dp->task == task); - - /* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep - * the information for the lookup_() function that will called soon. */ - if (vm->pimpl_vm_->dp_enabled) { - double remaining = MSG_task_get_flops_amount(task); - double clock = MSG_get_clock(); - double updated = get_computed(key, vm, dp, remaining, clock); // was host instead of vm - - vm->pimpl_vm_->dp_updated_by_deleted_tasks += updated; - } - - vm->pimpl_vm_->dp_objs.erase(key); - delete dp; - - XBT_DEBUG("del %s on %s", key.c_str(), host->getCname()); -} - static sg_size_t send_migration_data(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, sg_size_t size, const std::string& mbox, int stage, int stage2_round, double mig_speed, double timeout) @@ -537,7 +420,7 @@ static int migration_tx_fun(int argc, char *argv[]) /* Stage1: send all memory pages to the destination. */ XBT_DEBUG("mig-stage1: remaining_size %zu", remaining_size); - start_dirty_page_tracking(ms->vm); + sg_vm_start_dirty_page_tracking(ms->vm); double computed_during_stage1 = 0; double clock_prev_send = MSG_get_clock(); @@ -548,7 +431,7 @@ static int migration_tx_fun(int argc, char *argv[]) XBT_VERB("Stage 1: Gonna send %llu bytes", ramsize); sg_size_t sent = send_migration_data(ms->vm, ms->src_pm, ms->dst_pm, ramsize, ms->mbox, 1, 0, mig_speed, -1); remaining_size -= sent; - computed_during_stage1 = lookup_computed_flop_counts(ms->vm, 1, 0); + computed_during_stage1 = sg_vm_lookup_computed_flops(ms->vm); if (sent < ramsize) { XBT_VERB("mig-stage1: timeout, force moving to stage 3"); @@ -559,7 +442,7 @@ static int migration_tx_fun(int argc, char *argv[]) } catch (xbt_ex& e) { // hostfailure (if you want to know whether this is the SRC or the DST check directly in send_migration_data code) // Stop the dirty page tracking an return (there is no memory space to release) - stop_dirty_page_tracking(ms->vm); + sg_vm_stop_dirty_page_tracking(ms->vm); return 0; } @@ -586,7 +469,7 @@ static int migration_tx_fun(int argc, char *argv[]) /* just after stage1, nothing has been updated. But, we have to send the data updated during stage1 */ updated_size = get_updated_size(computed_during_stage1, dp_rate, dp_cap); } else { - double computed = lookup_computed_flop_counts(ms->vm, 2, stage2_round); + double computed = sg_vm_lookup_computed_flops(ms->vm); updated_size = get_updated_size(computed, dp_rate, dp_cap); } @@ -610,7 +493,7 @@ static int migration_tx_fun(int argc, char *argv[]) // hostfailure (if you want to know whether this is the SRC or the DST check directly in send_migration_data // code) // Stop the dirty page tracking an return (there is no memory space to release) - stop_dirty_page_tracking(ms->vm); + sg_vm_stop_dirty_page_tracking(ms->vm); return 0; } double clock_post_send = MSG_get_clock(); @@ -632,7 +515,7 @@ static int migration_tx_fun(int argc, char *argv[]) updated_size, (clock_post_send - clock_prev_send)); remaining_size -= sent; - double computed = lookup_computed_flop_counts(ms->vm, 2, stage2_round); + double computed = sg_vm_lookup_computed_flops(ms->vm); updated_size = get_updated_size(computed, dp_rate, dp_cap); remaining_size += updated_size; break; @@ -647,7 +530,7 @@ static int migration_tx_fun(int argc, char *argv[]) pimpl->setState(SURF_VM_STATE_RUNNING); // FIXME: this bypass of the checks in suspend() is not nice pimpl->isMigrating = false; // FIXME: this bypass of the checks in suspend() is not nice pimpl->suspend(SIMIX_process_self()); - stop_dirty_page_tracking(ms->vm); + sg_vm_stop_dirty_page_tracking(ms->vm); try { XBT_DEBUG("Stage 3: Gonna send %zu bytes", remaining_size); diff --git a/src/plugins/vm/VirtualMachineImpl.cpp b/src/plugins/vm/VirtualMachineImpl.cpp index 87e2badd9e..8b5f1c8502 100644 --- a/src/plugins/vm/VirtualMachineImpl.cpp +++ b/src/plugins/vm/VirtualMachineImpl.cpp @@ -22,17 +22,17 @@ void surf_vm_model_init_HL13() } } -namespace simgrid { -namespace vm { /************* * Callbacks * *************/ -simgrid::xbt::signal onVmCreation; -simgrid::xbt::signal onVmDestruction; -simgrid::xbt::signal onVmStateChange; +simgrid::xbt::signal simgrid::vm::VirtualMachineImpl::onVmCreation; +simgrid::xbt::signal simgrid::vm::VirtualMachineImpl::onVmDestruction; +simgrid::xbt::signal simgrid::vm::VirtualMachineImpl::onVmStateChange; +namespace simgrid { +namespace vm { /********* * Model * *********/ @@ -125,6 +125,7 @@ VirtualMachineImpl::VirtualMachineImpl(simgrid::s4u::VirtualMachine* piface, sim action_ = host_PM->pimpl_cpu->execution_start(0, coreAmount); XBT_VERB("Create VM(%s)@PM(%s)", piface->getCname(), hostPM_->getCname()); + onVmCreation(this); } /** @brief A physical host does not disappear in the current SimGrid code, but a VM may disappear during a simulation */ @@ -136,20 +137,6 @@ VirtualMachineImpl::~VirtualMachineImpl() if (iter != allVms_.end()) allVms_.erase(iter); - /* dirty page tracking */ - unsigned int size = dp_objs.size(); - static bool already_warned = false; - if (size > 0 && not already_warned) { - auto front = dp_objs.begin(); - XBT_WARN("Dirty page tracking: %u pending task(s) on a destroyed VM (first one is %s).\n" - "If you don't understand why your task was not properly removed, please report that bug.\n" - "This is a known bug if you turned the host off during the VM execution.\n" - "Please remind us of that problem at some point: our code base is not ready to fix this harmless issue in " - "2016, sorry.", - size, (xbt_log_no_loc ? "(name hidden)" : front->first.c_str())); - already_warned = true; - } - /* Free the cpu_action of the VM. */ XBT_ATTRIB_UNUSED int ret = action_->unref(); xbt_assert(ret == 1, "Bug: some resource still remains"); diff --git a/src/plugins/vm/VirtualMachineImpl.hpp b/src/plugins/vm/VirtualMachineImpl.hpp index 0dda5ea889..553fffa8e8 100644 --- a/src/plugins/vm/VirtualMachineImpl.hpp +++ b/src/plugins/vm/VirtualMachineImpl.hpp @@ -21,25 +21,6 @@ typedef struct s_dirty_page* dirty_page_t; namespace simgrid { namespace vm { -/************* - * Callbacks * - *************/ - -/** @ingroup SURF_callbacks - * @brief Callbacks fired after VM creation. Signature: `void(VirtualMachine*)` - */ -extern XBT_PRIVATE simgrid::xbt::signal onVmCreation; - -/** @ingroup SURF_callbacks - * @brief Callbacks fired after VM destruction. Signature: `void(VirtualMachine*)` - */ -extern XBT_PRIVATE simgrid::xbt::signal onVmDestruction; - -/** @ingroup SURF_callbacks - * @brief Callbacks after VM State changes. Signature: `void(VirtualMachine*)` - */ -extern XBT_PRIVATE simgrid::xbt::signal onVmStateChange; - /************ * Resource * ************/ @@ -48,7 +29,7 @@ extern XBT_PRIVATE simgrid::xbt::signal * @brief SURF VM interface class * @details A VM represent a virtual machine */ -XBT_PUBLIC_CLASS VirtualMachineImpl : public surf::HostImpl +XBT_PUBLIC_CLASS VirtualMachineImpl : public surf::HostImpl, public simgrid::xbt::Extendable { friend simgrid::s4u::VirtualMachine; @@ -82,17 +63,29 @@ public: /* The vm object of the lower layer */ surf::Action* action_ = nullptr; - /* Dirty pages stuff */ - std::unordered_map dp_objs; - bool dp_enabled = false; - double dp_updated_by_deleted_tasks = 0; - e_surf_vm_state_t getState(); void setState(e_surf_vm_state_t state); static std::deque allVms_; int coreAmount() { return coreAmount_; } bool isMigrating = false; + /************* + * Callbacks * + *************/ + /** @ingroup SURF_callbacks + * @brief Callbacks fired after VM creation. Signature: `void(VirtualMachine*)` + */ + static simgrid::xbt::signal onVmCreation; + + /** @ingroup SURF_callbacks + * @brief Callbacks fired after VM destruction. Signature: `void(VirtualMachine*)` + */ + static simgrid::xbt::signal onVmDestruction; + + /** @ingroup SURF_callbacks + * @brief Callbacks after VM State changes. Signature: `void(VirtualMachine*)` + */ + static simgrid::xbt::signal onVmStateChange; private: simgrid::s4u::Host* hostPM_; diff --git a/src/plugins/vm/s4u_VirtualMachine.cpp b/src/plugins/vm/s4u_VirtualMachine.cpp index a4f2022443..3ee05b2aae 100644 --- a/src/plugins/vm/s4u_VirtualMachine.cpp +++ b/src/plugins/vm/s4u_VirtualMachine.cpp @@ -176,11 +176,5 @@ void VirtualMachine::setParameters(vm_params_t params) simgrid::simix::kernelImmediate([this, params] { pimpl_vm_->setParams(params); }); } -/************* - * Callbacks * - *************/ -simgrid::xbt::signal VirtualMachine::onCreation; -simgrid::xbt::signal VirtualMachine::onDestruction; - } // namespace simgrid } // namespace s4u diff --git a/src/surf/plugins/dirty_page_tracking.cpp b/src/surf/plugins/dirty_page_tracking.cpp new file mode 100644 index 0000000000..e923f55031 --- /dev/null +++ b/src/surf/plugins/dirty_page_tracking.cpp @@ -0,0 +1,120 @@ +/* Copyright (c) 2017. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/plugins/live_migration.h" +#include "simgrid/s4u.hpp" +#include "src/plugins/vm/VirtualMachineImpl.hpp" +#include + +namespace simgrid { +namespace vm { +class VmDirtyPageTrackingExt { + bool dp_tracking = false; + std::map dp_objs; + double dp_updated_by_deleted_tasks = 0; + +public: + void startTracking(); + void stopTracking() { dp_tracking = false; } + bool isTracking() { return dp_tracking; } + void track(kernel::activity::ExecImplPtr exec, double amount) { dp_objs.insert({exec, amount}); } + void untrack(kernel::activity::ExecImplPtr exec) { dp_objs.erase(exec); } + double getStoredRemains(kernel::activity::ExecImplPtr exec) { return dp_objs.at(exec); } + void updateDirtyPageCount(double delta) { dp_updated_by_deleted_tasks += delta; } + double computedFlopsLookup(); + + static simgrid::xbt::Extension EXTENSION_ID; + virtual ~VmDirtyPageTrackingExt() = default; + VmDirtyPageTrackingExt() = default; +}; + +simgrid::xbt::Extension VmDirtyPageTrackingExt::EXTENSION_ID; + +void VmDirtyPageTrackingExt::startTracking() +{ + dp_tracking = true; + for (auto const& elm : dp_objs) + dp_objs[elm.first] = elm.first->remains(); +} + +double VmDirtyPageTrackingExt::computedFlopsLookup() +{ + double total = 0; + + for (auto const& elm : dp_objs) { + total += elm.second - elm.first->remains(); + dp_objs[elm.first] = elm.first->remains(); + } + total += dp_updated_by_deleted_tasks; + + dp_updated_by_deleted_tasks = 0; + + return total; +} +} +} + +static void onVirtualMachineCreation(simgrid::vm::VirtualMachineImpl* vm) +{ + vm->extension_set(new simgrid::vm::VmDirtyPageTrackingExt()); +} + +static void onExecCreation(simgrid::kernel::activity::ExecImplPtr exec) +{ + simgrid::s4u::VirtualMachine* vm = dynamic_cast(exec->host_); + if (vm == nullptr) + return; + + if (vm->pimpl_vm_->extension()->isTracking()) { + vm->pimpl_vm_->extension()->track(exec, exec->remains()); + } else { + vm->pimpl_vm_->extension()->track(exec, 0.0); + } +} + +static void onExecDestruction(simgrid::kernel::activity::ExecImplPtr exec) +{ + simgrid::s4u::VirtualMachine* vm = dynamic_cast(exec->host_); + if (vm == nullptr) + return; + + /* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep + * the information for the lookup_() function that will called soon. */ + if (vm->pimpl_vm_->extension()->isTracking()) { + double delta = + vm->pimpl_vm_->extension()->getStoredRemains(exec) - exec->remains(); + vm->pimpl_vm_->extension()->updateDirtyPageCount(delta); + } + vm->pimpl_vm_->extension()->untrack(exec); +} + +SG_BEGIN_DECL() + +void sg_vm_live_migration_plugin_init() +{ + if (not simgrid::vm::VmDirtyPageTrackingExt::EXTENSION_ID.valid()) { + simgrid::vm::VmDirtyPageTrackingExt::EXTENSION_ID = + simgrid::vm::VirtualMachineImpl::extension_create(); + simgrid::vm::VirtualMachineImpl::onVmCreation.connect(&onVirtualMachineCreation); + simgrid::kernel::activity::ExecImpl::onCreation.connect(&onExecCreation); + simgrid::kernel::activity::ExecImpl::onDestruction.connect(&onExecDestruction); + } +} + +void sg_vm_start_dirty_page_tracking(sg_vm_t vm) +{ + vm->pimpl_vm_->extension()->startTracking(); +} + +void sg_vm_stop_dirty_page_tracking(sg_vm_t vm) +{ + vm->pimpl_vm_->extension()->stopTracking(); +} + +double sg_vm_lookup_computed_flops(sg_vm_t vm) +{ + return vm->pimpl_vm_->extension()->computedFlopsLookup(); +} +SG_END_DECL() diff --git a/teshsuite/msg/cloud-simple/cloud-simple.c b/teshsuite/msg/cloud-simple/cloud-simple.c index ad7b09513f..bd71be2095 100644 --- a/teshsuite/msg/cloud-simple/cloud-simple.c +++ b/teshsuite/msg/cloud-simple/cloud-simple.c @@ -4,6 +4,8 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/msg.h" +#include "simgrid/plugins/live_migration.h" + XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example"); static int computation_fun(int argc, char* argv[]) @@ -263,6 +265,7 @@ int main(int argc, char* argv[]) { /* Get the arguments */ MSG_init(&argc, argv); + sg_vm_live_migration_plugin_init(); /* load the platform file */ const char* platform = "../../platforms/small_platform.xml"; diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 38517be840..92cf23e6aa 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -340,6 +340,7 @@ set(SURF_SRC src/surf/network_cm02.cpp src/surf/network_constant.cpp src/surf/network_interface.cpp + src/surf/plugins/dirty_page_tracking.cpp src/surf/plugins/host_energy.cpp src/surf/plugins/link_energy.cpp src/surf/plugins/host_load.cpp @@ -667,6 +668,7 @@ set(headers_to_install include/simgrid/chrono.hpp include/simgrid/plugins/energy.h include/simgrid/plugins/file_system.h + include/simgrid/plugins/live_migration.h include/simgrid/plugins/load.h include/simgrid/instr.h include/simgrid/msg.h @@ -695,8 +697,6 @@ set(headers_to_install include/simgrid/s4u/Storage.hpp include/simgrid/s4u/VirtualMachine.hpp include/simgrid/s4u.hpp - include/simgrid/plugins/energy.h - include/simgrid/plugins/load.h include/smpi/mpi.h include/smpi/smpi.h include/smpi/smpi_main.h -- 2.20.1