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.


Basic HVM data structures and functions
[palacios.git] / palacios / src / palacios / vmm_pwrstat_telemetry.c
1 /*
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.
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2013, The V3VEE Project <http://www.v3vee.org>
11  * All rights reserved.
12  *
13  * Author: Kyle C. Hale <kh@u.northwestern.edu>
14  *                 Chang S. Bae <chang.bae@eecs.northwestern.edu>
15  *         Peter Dinda <pdinda@northwestern.edu>
16  *
17  * This is free software.  You are permitted to use,
18  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
19  */
20 #include <palacios/vm_guest.h>
21 #include <palacios/vmm_telemetry.h>
22 #include <palacios/vmm_pwrstat_telemetry.h>
23 #include <palacios/vmm_sprintf.h>
24 #include <interfaces/vmm_pwrstat.h>
25
26 /*
27   We will try to track:
28
29         V3_PWRSTAT_PKG_ENERGY,
30         V3_PWRSTAT_CORE_ENERGY,
31         V3_PWRSTAT_EXT_ENERGY, 
32         V3_PWRSTAT_DRAM_ENERGY,
33 */
34
35 #define HAVE(WHAT) (info->pwrstat_telem.active_counters[WHAT])
36
37 #define GUEST(WHAT)  do { if (HAVE(WHAT)) { V3_Print(info->vm_info, info, "%sGUEST:%u:%u:%s = %llu\n", hdr, info->vcpu_id, info->pcpu_id, #WHAT, info->pwrstat_telem.guest_counts[WHAT]); } } while (0)
38 #define HOST(WHAT)   do { if (HAVE(WHAT)) { V3_Print(info->vm_info, info, "%sHOST:%u:%u:%s = %llu\n", hdr, info->vcpu_id, info->pcpu_id, #WHAT, info->pwrstat_telem.host_counts[WHAT]); } } while (0)
39
40 #define START(WHAT) \
41 do { \
42   if(v3_pwrstat_ctr_valid(WHAT)) { \
43     info->pwrstat_telem.active_counters[WHAT]=1; \
44   } else { \
45   info->pwrstat_telem.active_counters[WHAT]=0;\
46   } \
47  } while (0) 
48
49 #define STOP(WHAT) info->pwrstat_telem.active_counters[WHAT]=0;
50
51 static int print_pwrstat_data(struct guest_info *info, char * hdr) 
52 {
53   GUEST(V3_PWRSTAT_PKG_ENERGY);
54   GUEST(V3_PWRSTAT_CORE_ENERGY);
55   GUEST(V3_PWRSTAT_EXT_ENERGY);
56   GUEST(V3_PWRSTAT_DRAM_ENERGY);
57
58   HOST(V3_PWRSTAT_PKG_ENERGY);
59   HOST(V3_PWRSTAT_CORE_ENERGY);
60   HOST(V3_PWRSTAT_EXT_ENERGY);
61   HOST(V3_PWRSTAT_DRAM_ENERGY);
62
63   return 0;
64 }
65
66   
67 static void telemetry_pwrstat (struct v3_vm_info * vm, void * private_data, char * hdr) 
68 {
69   int i;
70   struct guest_info *core = NULL;
71   
72   /*
73    * work through each pcore (vcore for now per excluding oversubscription) and gathering info
74    */
75   for(i=0; i<vm->num_cores; i++) {
76     core = &(vm->cores[i]);
77     if((core->core_run_state != CORE_RUNNING)) continue;
78     print_pwrstat_data(core, hdr);
79   }
80 }
81
82
83 void v3_pwrstat_telemetry_start (struct guest_info *info)
84 {
85   if (!info->vm_info->enable_telemetry) {
86     return;
87   }
88
89   memset(&(info->pwrstat_telem),0,sizeof(struct v3_core_pwrstat_telemetry));
90
91   v3_pwrstat_init();
92   
93   START(V3_PWRSTAT_PKG_ENERGY);
94   START(V3_PWRSTAT_CORE_ENERGY);
95   START(V3_PWRSTAT_EXT_ENERGY);
96   START(V3_PWRSTAT_DRAM_ENERGY);
97
98   info->pwrstat_telem.state=PWR_AWAIT_FIRST_ENTRY;
99
100   if (info->vcpu_id==0) { 
101     v3_add_telemetry_cb(info->vm_info, telemetry_pwrstat, NULL);
102   }
103 }
104
105
106 static void inline snapshot(uint64_t vals[]) {
107   vals[V3_PWRSTAT_PKG_ENERGY] = v3_pwrstat_get_value(V3_PWRSTAT_PKG_ENERGY);
108   vals[V3_PWRSTAT_CORE_ENERGY] = v3_pwrstat_get_value(V3_PWRSTAT_CORE_ENERGY);
109   vals[V3_PWRSTAT_EXT_ENERGY] = v3_pwrstat_get_value(V3_PWRSTAT_EXT_ENERGY);
110   vals[V3_PWRSTAT_DRAM_ENERGY] = v3_pwrstat_get_value(V3_PWRSTAT_DRAM_ENERGY);
111 }  
112
113
114 void v3_pwrstat_telemetry_enter(struct guest_info *info)
115 {
116   if (!info->vm_info->enable_telemetry) {
117     return;
118   }
119
120   switch (info->pwrstat_telem.state) { 
121   case PWR_AWAIT_FIRST_ENTRY:
122     snapshot(info->pwrstat_telem.last_snapshot);
123     info->pwrstat_telem.state=PWR_AWAIT_EXIT;
124     break;
125   
126   case PWR_AWAIT_ENTRY: {
127     // AWAIT_ENTRY - the snapshot in the struct is from the last exit
128     uint64_t snap[PWRSTAT_NUM_COUNTERS];
129     int i;
130
131     snapshot(snap);
132
133     for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) { 
134       info->pwrstat_telem.host_counts[i] += snap[i] - info->pwrstat_telem.last_snapshot[i];
135     }
136
137     for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) { 
138       info->pwrstat_telem.last_snapshot[i] = snap[i];
139     }
140
141     info->pwrstat_telem.state = PWR_AWAIT_EXIT;
142   }
143     break;
144
145   default:
146     PrintError(info->vm_info, info, "Impossible state on pwrstat telemetry entry\n");
147     break;
148   }
149   
150 }
151
152
153 void v3_pwrstat_telemetry_exit (struct guest_info *info)
154 {
155   if (!info->vm_info->enable_telemetry) {
156     return;
157   }
158
159   switch (info->pwrstat_telem.state) { 
160   case PWR_AWAIT_EXIT: {
161     // AWAIT_EXIT - the snapshot in the struct is from the last entryx
162     uint64_t snap[PWRSTAT_NUM_COUNTERS];
163     int i;
164
165     snapshot(snap);
166
167     for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) { 
168       info->pwrstat_telem.guest_counts[i] += snap[i] - info->pwrstat_telem.last_snapshot[i];
169     }
170
171     for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) { 
172       info->pwrstat_telem.last_snapshot[i] = snap[i];
173     }
174
175     info->pwrstat_telem.state = PWR_AWAIT_ENTRY;
176   }
177     break;
178   default:
179     PrintError(info->vm_info, info, "Impossible state on pwrstat telemetry exit\n");
180     break;
181   }
182   
183 }
184
185
186 void v3_pwrstat_telemetry_end (struct guest_info *info)
187 {
188   if (!info->vm_info->enable_telemetry) {
189     return;
190   }
191
192   v3_pwrstat_deinit();
193   
194   info->pwrstat_telem.state=PWR_AWAIT_FIRST_ENTRY;
195
196 }