Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Configuration of global performance parameters
Peter Dinda [Thu, 9 Aug 2012 18:44:03 +0000 (13:44 -0500)]
Integration of yielding parameters into this framework

palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm_perftune.h [new file with mode: 0644]
palacios/src/palacios/Makefile
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_perftune.c [new file with mode: 0644]

index 468434f..5e18244 100644 (file)
@@ -42,6 +42,8 @@
 #include <palacios/vmm_exits.h>
 #include <palacios/vmm_events.h>
 
+#include <palacios/vmm_perftune.h>
+
 #ifdef V3_CONFIG_TELEMETRY
 #include <palacios/vmm_telemetry.h>
 #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 (file)
index 0000000..0a60d6c
--- /dev/null
@@ -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 <pdinda@northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * 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 <palacios/vmm_types.h>
+
+
+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 <perftune/> 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
index 6d14934..4a4b04e 100644 (file)
@@ -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
index f02ab25..75d9ea7 100644 (file)
@@ -37,6 +37,7 @@
 
 
 #include <palacios/vmm_host_events.h>
+#include <palacios/vmm_perftune.h>
 
 #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 (file)
index 0000000..8ffe3a9
--- /dev/null
@@ -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 <pdinda@northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vm_guest.h>
+
+
+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");
+    }
+    
+    
+}
+
+    
+
+
+/*
+<vm>
+  <perftune>
+     <group name="yield_strategy">
+        <strategy>greedy,friendly,adaptive</strategy>
+        <threshold>us</threshold>
+        <time>us</time>
+     </group>
+     <group name="something else">
+        <group-specific>....</group-specific>
+     </group>
+     ...
+  </perftune>
+</vm>
+*/
+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;
+}
+