From: Peter Dinda Date: Thu, 9 Aug 2012 18:44:03 +0000 (-0500) Subject: Configuration of global performance parameters X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=a0bff8bd6b7f6dcfc840b41aa428904f251fba7e;p=palacios.git Configuration of global performance parameters Integration of yielding parameters into this framework --- diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 468434f..5e18244 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -42,6 +42,8 @@ #include #include +#include + #ifdef V3_CONFIG_TELEMETRY #include #endif @@ -185,6 +187,8 @@ struct v3_vm_info { struct v3_extensions extensions; + struct v3_perf_options perf_options; + #ifdef V3_CONFIG_SYMBIOTIC /* Symbiotic state */ struct v3_sym_vm_state sym_vm_state; diff --git a/palacios/include/palacios/vmm_perftune.h b/palacios/include/palacios/vmm_perftune.h new file mode 100644 index 0000000..0a60d6c --- /dev/null +++ b/palacios/include/palacios/vmm_perftune.h @@ -0,0 +1,64 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2012, Peter Dinda + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __VM_PERFTUNE_H__ +#define __VM_PERFTUNE_H__ + +#ifdef __V3VEE__ + +#include + + +struct v3_yield_strategy { + enum { + V3_YIELD_STRATEGY_GREEDY=0, // always untimed yields + V3_YIELD_STRATEGY_FRIENDLY, // always timed yields with the following + V3_YIELD_STRATEGY_ADAPTIVE, // switch from untimed to timed after the threshold + } strategy; + + uint64_t threshold_usec; // the point at which we transiton from untimed to timed yield + uint64_t time_usec; // the amount of time for a timed yield call + +#define V3_DEFAULT_YIELD_STRATEGY V3_YIELD_STRATEGY_GREEDY +#define V3_DEFAULT_YIELD_THRESHOLD_USEC 100 +#define V3_DEFAULT_YIELD_TIME_USEC 1000 +}; + + + +// +// The idea is that the performance tuning knobs in the system are in the following +// structure, which is configured when the VM is created, right after extensions, +// using the subtree +// +struct v3_perf_options { + struct v3_yield_strategy yield_strategy; +}; + + +int v3_setup_performance_tuning(struct v3_vm_info *vm, v3_cfg_tree_t *cfg); + +void v3_strategy_driven_yield(struct guest_info *core, uint64_t time_since_last_did_work_usec); + +uint64_t v3_cycle_diff_in_usec(struct guest_info *core, uint64_t earlier_cycles, uint64_t later_cycles); + + +#endif + +#endif diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index 6d14934..4a4b04e 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -38,7 +38,8 @@ obj-y := \ vmm_barrier.o \ vmm_timeout.o \ vmm_exits.o \ - vmm_events.o + vmm_events.o \ + vmm_perftune.o \ obj-$(V3_CONFIG_XED) += vmm_xed.o diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index f02ab25..75d9ea7 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -37,6 +37,7 @@ #include +#include #include "vmm_config_class.h" @@ -474,6 +475,11 @@ static int post_config_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } + if (v3_setup_performance_tuning(vm, cfg) == -1) { + PrintError("Failed to configure performance tuning parameters\n"); + return -1; + } + vm->run_state = VM_STOPPED; diff --git a/palacios/src/palacios/vmm_perftune.c b/palacios/src/palacios/vmm_perftune.c new file mode 100644 index 0000000..8ffe3a9 --- /dev/null +++ b/palacios/src/palacios/vmm_perftune.c @@ -0,0 +1,161 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2012, Peter Dinda + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include + + +void v3_strategy_driven_yield(struct guest_info *core, uint64_t time_since_last_did_work_usec) +{ + // yield according to strategy + switch (core->vm_info->perf_options.yield_strategy.strategy) { + case V3_YIELD_STRATEGY_GREEDY: + v3_yield(core,-1); + break; + case V3_YIELD_STRATEGY_FRIENDLY: + v3_yield(core,core->vm_info->perf_options.yield_strategy.time_usec); + break; + case V3_YIELD_STRATEGY_ADAPTIVE: + if (time_since_last_did_work_usec > core->vm_info->perf_options.yield_strategy.threshold_usec) { + v3_yield(core,core->vm_info->perf_options.yield_strategy.time_usec); + } else { + v3_yield(core,-1); + } + default: + PrintError("Unknown yield strategy (%d) using GREEDY\n",core->vm_info->perf_options.yield_strategy.strategy); + v3_yield(core,-1); + break; + } +} + + + +uint64_t v3_cycle_diff_in_usec(struct guest_info *core, uint64_t first, uint64_t second) +{ + uint64_t cycle_diff = second - first; + uint64_t mhz = (core->time_state.host_cpu_freq) / 1000; // KHZ->MHZ + + return cycle_diff / mhz ; // cycles / (millioncycles/sec) = sec/million = usec +} + +static void set_yield_defaults(struct v3_vm_info *vm) +{ + vm->perf_options.yield_strategy.strategy = V3_DEFAULT_YIELD_STRATEGY; + vm->perf_options.yield_strategy.threshold_usec = V3_DEFAULT_YIELD_THRESHOLD_USEC; + vm->perf_options.yield_strategy.time_usec = V3_DEFAULT_YIELD_TIME_USEC; +} + + +static void set_yield(struct v3_vm_info *vm, v3_cfg_tree_t *cfg) + +{ + char *t; + + set_yield_defaults(vm); + + // now override + + t = v3_cfg_val(cfg, "yield_strategy"); + + if (t) { + if (!strcasecmp(t,"greedy")) { + vm->perf_options.yield_strategy.strategy = V3_YIELD_STRATEGY_GREEDY; + V3_Print("Setting yield strategy to GREEDY\n"); + } else if (!strcasecmp(t, "friendly")) { + vm->perf_options.yield_strategy.strategy = V3_YIELD_STRATEGY_FRIENDLY; + V3_Print("Setting yield strategy to FRIENDLY\n"); + } else if (!strcasecmp(t, "adaptive")) { + vm->perf_options.yield_strategy.strategy = V3_YIELD_STRATEGY_ADAPTIVE; + V3_Print("Setting yield strategy to ADAPTIVE\n"); + } else { + V3_Print("Unknown yield strategy '%s', using default\n",t); + } + } else { + V3_Print("Yield strategy not given, using default\n"); + } + + t = v3_cfg_val(cfg, "threshold"); + + if (t) { + vm->perf_options.yield_strategy.threshold_usec = atoi(t); + V3_Print("Setting yield threshold to %llu\n",vm->perf_options.yield_strategy.threshold_usec); + } else { + V3_Print("Yield threshold not given, using default\n"); + } + + + t = v3_cfg_val(cfg, "time"); + + if (t) { + vm->perf_options.yield_strategy.time_usec = atoi(t); + V3_Print("Setting yield time to %llu\n",vm->perf_options.yield_strategy.time_usec); + } else { + V3_Print("Yield time not given, using default\n"); + } + + +} + + + + +/* + + + + greedy,friendly,adaptive + us + + + + .... + + ... + + +*/ +int v3_setup_performance_tuning(struct v3_vm_info *vm, v3_cfg_tree_t *cfg) +{ + v3_cfg_tree_t *t = v3_cfg_subtree(cfg,"perftune"); + + if (!t) { + V3_Print("No performance tuning tree - using defaults\n"); + set_yield_defaults(vm); + return 0; + } + + t = v3_cfg_subtree(t,"group"); + + while (t) { + char *id = v3_cfg_val(t,"name"); + if (!id) { + V3_Print("Skipping performance parameter group without name\n"); + } else { + if (!strcasecmp(id,"yield_strategy")) { + set_yield(vm,t); + } else { + V3_Print("Skipping unknown performance parameter group\n"); + } + } + t = v3_cfg_next_branch(t); + } + + return 0; +} +