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) 2013, Oscar Mondragon <omondrag@cs.unm.edu>
11 * Copyright (c) 2013, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Oscar Mondragon <omondrag@cs.unm.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21 #include <palacios/vmm.h>
22 #include <palacios/vm_guest.h>
23 #include <palacios/vmm_extensions.h>
24 #include <palacios/vmm_cpu_mapper.h>
26 #ifndef V3_CONFIG_DEBUG_EXT_CPU_MAPPER_EDF
28 #define PrintDebug(fmt, args...)
34 * cpu_mapper for EDF Scheduling
40 #define UTILIZATION 80
42 // Next Fit heuristic implementation
44 int nextFit(int save, int tdf,struct v3_vm_info *vm){
46 PrintDebug(vm, VCORE_NONE,"nextFit for tdf %d \n", tdf);
48 int V = vm->num_cores; // Number of virtual cores
49 int L = vm->avail_cores; // Number of Logical cores
50 int speedRatio[L]; // mapped virtual cores to logical core ratio. Must be less or equal than UTILIZATION X TDF
51 uint64_t speedVCores[V]; // Virtual core speeds
52 int mapping[V]; // mapping array
53 int vc=0; // virtual core id
54 int lc=0; // logical core id
55 uint_t cpu_khz = V3_CPU_KHZ(); // Physical core speed
67 // Initialize Virtual cores utilization vector
68 v3_cfg_tree_t * cfg_tree = vm->cfg_data->cfg;
69 v3_cfg_tree_t * core = v3_cfg_subtree(v3_cfg_subtree(cfg_tree, "cores"), "core");
73 uint_t vcSpeed = cpu_khz;
74 char *speed = v3_cfg_val(core, "khz");
76 vcSpeed = atoi(speed);
79 speedVCores[vc] = vcSpeed;
81 core = v3_cfg_next_branch(core);
83 /*PrintDebug(VM_NONE, VCORE_NONE,"mapper. vc %d, speed %llu, vcores %d, lcores %d, cpu_khz %u\n",
95 // TODO Control Target CPU case
99 //PrintDebug(VM_NONE, VCORE_NONE,"mapper. vc %d, ratio %llu, tdf %d\n",vc, (speedRatio[lc] + 100*speedVCores[vc]/cpu_khz), tdf);
101 if( (speedRatio[lc] + 100*speedVCores[vc]/cpu_khz) <= (UTILIZATION*tdf)){
103 speedRatio[lc] += 100*speedVCores[vc]/cpu_khz;
106 if (((lc+1)< L) && (100*speedVCores[vc]/cpu_khz <= (UTILIZATION*tdf))){
109 speedRatio[lc] += 100*speedVCores[vc]/cpu_khz;
112 return -1; // Could not map
124 // Assing computed TDF
125 struct v3_time *vm_ts = &(vm->time_state);
126 vm_ts->td_denom = tdf;
128 // mapping virtual cores in logical cores
129 for (vc = 0; vc < vm->num_cores; vc++) {
130 struct guest_info * core = &(vm->cores[vc]);
131 core-> pcpu_id = mapping[vc];
136 PrintDebug(vm, VCORE_NONE,"mapper. Number of Logical cores: %d",L);
137 PrintDebug(vm, VCORE_NONE, "mapper. Mapping Array:\n");
139 PrintDebug(vm, VCORE_NONE,"mapper. vcore %d: %d ",x,mapping[x]);
147 int edf_mapper_vm_init(struct v3_vm_info *vm){
149 PrintDebug(vm, VCORE_NONE,"mapper. Initializing edf cpu_mapper");
154 int edf_mapper_admit(struct v3_vm_info *vm, unsigned int cpu_mask){
155 PrintDebug(vm, VCORE_NONE,"mapper. Edf cpu_mapper admit\n");
157 int min_tdf = MIN_TDF;
158 int max_tdf = MAX_TDF;
159 int tdf = MAX_TDF; // Time dilation factor
162 // Binary Search of TDF
166 while( (max_tdf-min_tdf) > 0 ){
168 mappable = nextFit(-1,tdf,vm);
180 mappable = nextFit(-1,tdf,vm);
189 PrintDebug(vm, VCORE_NONE,"mapper. Calculated TDF denom %d\n",tdf);
193 int edf_mapper_admit_core(struct v3_vm_info * vm, int vcore_id, int target_cpu){
194 PrintDebug(vm, VCORE_NONE,"mapper. Edf cpu_mapper admit core\n");
199 static struct vm_cpu_mapper_impl edf_mapper = {
204 .vm_init = edf_mapper_vm_init,
206 .admit = edf_mapper_admit,
207 .admit_core = edf_mapper_admit_core
213 ext_mapper_edf_init() {
214 PrintDebug(VM_NONE, VCORE_NONE,"mapper. Creating (%s) cpu_mapper\n",edf_mapper.name);
215 return v3_register_cpu_mapper(&edf_mapper);
219 ext_mapper_edf_vm_init() {
223 static struct v3_extension_impl mapper_edf_impl = {
225 .name = "cpu_mapper for EDF Scheduler",
226 .init = ext_mapper_edf_init,
227 .vm_init = ext_mapper_edf_vm_init,
235 register_extension(&mapper_edf_impl);