2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2012, Peter Dinda <pdinda@northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Peter Dinda <pdinda@northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vm_guest.h>
24 void v3_strategy_driven_yield(struct guest_info *core, uint64_t time_since_last_did_work_usec)
26 // yield according to strategy
27 switch (core->vm_info->perf_options.yield_strategy.strategy) {
28 case V3_YIELD_STRATEGY_GREEDY:
31 case V3_YIELD_STRATEGY_FRIENDLY:
32 v3_yield(core,core->vm_info->perf_options.yield_strategy.time_usec);
34 case V3_YIELD_STRATEGY_ADAPTIVE:
35 if (time_since_last_did_work_usec > core->vm_info->perf_options.yield_strategy.threshold_usec) {
36 v3_yield(core,core->vm_info->perf_options.yield_strategy.time_usec);
41 PrintError(core->vm_info, core, "Unknown yield strategy (%d) using GREEDY\n",core->vm_info->perf_options.yield_strategy.strategy);
49 uint64_t v3_cycle_diff_in_usec(struct guest_info *core, uint64_t first, uint64_t second)
51 uint64_t cycle_diff = second - first;
52 uint64_t mhz = (core->time_state.host_cpu_freq) / 1000; // KHZ->MHZ
54 return cycle_diff / mhz ; // cycles / (millioncycles/sec) = sec/million = usec
57 static void set_yield_defaults(struct v3_vm_info *vm)
59 vm->perf_options.yield_strategy.strategy = V3_DEFAULT_YIELD_STRATEGY;
60 vm->perf_options.yield_strategy.threshold_usec = V3_DEFAULT_YIELD_THRESHOLD_USEC;
61 vm->perf_options.yield_strategy.time_usec = V3_DEFAULT_YIELD_TIME_USEC;
65 static void set_yield(struct v3_vm_info *vm, v3_cfg_tree_t *cfg)
70 set_yield_defaults(vm);
74 t = v3_cfg_val(cfg, "strategy");
77 if (!strcasecmp(t,"greedy")) {
78 vm->perf_options.yield_strategy.strategy = V3_YIELD_STRATEGY_GREEDY;
79 V3_Print(vm, VCORE_NONE, "Setting yield strategy to GREEDY\n");
80 } else if (!strcasecmp(t, "friendly")) {
81 vm->perf_options.yield_strategy.strategy = V3_YIELD_STRATEGY_FRIENDLY;
82 V3_Print(vm, VCORE_NONE, "Setting yield strategy to FRIENDLY\n");
83 } else if (!strcasecmp(t, "adaptive")) {
84 vm->perf_options.yield_strategy.strategy = V3_YIELD_STRATEGY_ADAPTIVE;
85 V3_Print(vm, VCORE_NONE, "Setting yield strategy to ADAPTIVE\n");
87 V3_Print(vm, VCORE_NONE, "Unknown yield strategy '%s', using default\n",t);
90 V3_Print(vm, VCORE_NONE, "Yield strategy not given, using default\n");
93 t = v3_cfg_val(cfg, "threshold");
96 vm->perf_options.yield_strategy.threshold_usec = atoi(t);
97 V3_Print(vm, VCORE_NONE, "Setting yield threshold to %llu\n",vm->perf_options.yield_strategy.threshold_usec);
99 V3_Print(vm, VCORE_NONE, "Yield threshold not given, using default\n");
103 t = v3_cfg_val(cfg, "time");
106 vm->perf_options.yield_strategy.time_usec = atoi(t);
107 V3_Print(vm, VCORE_NONE, "Setting yield time to %llu\n",vm->perf_options.yield_strategy.time_usec);
109 V3_Print(vm, VCORE_NONE, "Yield time not given, using default\n");
122 <strategy>greedy,friendly,adaptive</strategy>
123 <threshold>us</threshold>
126 <group name="something else">
127 <group-specific>....</group-specific>
133 int v3_setup_performance_tuning(struct v3_vm_info *vm, v3_cfg_tree_t *cfg)
135 v3_cfg_tree_t *t = v3_cfg_subtree(cfg,"perftune");
138 V3_Print(vm, VCORE_NONE, "No performance tuning tree - using defaults\n");
139 set_yield_defaults(vm);
143 t = v3_cfg_subtree(t,"group");
146 char *id = v3_cfg_val(t,"name");
148 V3_Print(vm, VCORE_NONE, "Skipping performance parameter group without name\n");
150 if (!strcasecmp(id,"yield")) {
153 V3_Print(vm, VCORE_NONE, "Skipping unknown performance parameter group\n");
156 t = v3_cfg_next_branch(t);