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, The V3VEE Project <http://www.v3vee.org>
11 * All rights reserved.
13 * Author: Kyle C. Hale <kh@u.northwestern.edu>
14 * Chang S. Bae <chang.bae@eecs.northwestern.edu>
15 * Peter Dinda <pdinda@northwestern.edu>
17 * This is free software. You are permitted to use,
18 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
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>
29 V3_PWRSTAT_PKG_ENERGY,
30 V3_PWRSTAT_CORE_ENERGY,
31 V3_PWRSTAT_EXT_ENERGY,
32 V3_PWRSTAT_DRAM_ENERGY,
35 #define HAVE(WHAT) (info->pwrstat_telem.active_counters[WHAT])
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)
42 if(v3_pwrstat_ctr_valid(WHAT)) { \
43 info->pwrstat_telem.active_counters[WHAT]=1; \
45 info->pwrstat_telem.active_counters[WHAT]=0;\
49 #define STOP(WHAT) info->pwrstat_telem.active_counters[WHAT]=0;
51 static int print_pwrstat_data(struct guest_info *info, char * hdr)
53 GUEST(V3_PWRSTAT_PKG_ENERGY);
54 GUEST(V3_PWRSTAT_CORE_ENERGY);
55 GUEST(V3_PWRSTAT_EXT_ENERGY);
56 GUEST(V3_PWRSTAT_DRAM_ENERGY);
58 HOST(V3_PWRSTAT_PKG_ENERGY);
59 HOST(V3_PWRSTAT_CORE_ENERGY);
60 HOST(V3_PWRSTAT_EXT_ENERGY);
61 HOST(V3_PWRSTAT_DRAM_ENERGY);
67 static void telemetry_pwrstat (struct v3_vm_info * vm, void * private_data, char * hdr)
70 struct guest_info *core = NULL;
73 * work through each pcore (vcore for now per excluding oversubscription) and gathering info
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);
83 void v3_pwrstat_telemetry_start (struct guest_info *info)
85 if (!info->vm_info->enable_telemetry) {
89 memset(&(info->pwrstat_telem),0,sizeof(struct v3_core_pwrstat_telemetry));
93 START(V3_PWRSTAT_PKG_ENERGY);
94 START(V3_PWRSTAT_CORE_ENERGY);
95 START(V3_PWRSTAT_EXT_ENERGY);
96 START(V3_PWRSTAT_DRAM_ENERGY);
98 info->pwrstat_telem.state=PWR_AWAIT_FIRST_ENTRY;
100 if (info->vcpu_id==0) {
101 v3_add_telemetry_cb(info->vm_info, telemetry_pwrstat, NULL);
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);
114 void v3_pwrstat_telemetry_enter(struct guest_info *info)
116 if (!info->vm_info->enable_telemetry) {
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;
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];
133 for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) {
134 info->pwrstat_telem.host_counts[i] += snap[i] - info->pwrstat_telem.last_snapshot[i];
137 for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) {
138 info->pwrstat_telem.last_snapshot[i] = snap[i];
141 info->pwrstat_telem.state = PWR_AWAIT_EXIT;
146 PrintError(info->vm_info, info, "Impossible state on pwrstat telemetry entry\n");
153 void v3_pwrstat_telemetry_exit (struct guest_info *info)
155 if (!info->vm_info->enable_telemetry) {
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];
167 for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) {
168 info->pwrstat_telem.guest_counts[i] += snap[i] - info->pwrstat_telem.last_snapshot[i];
171 for (i=0;i<PWRSTAT_NUM_COUNTERS;i++) {
172 info->pwrstat_telem.last_snapshot[i] = snap[i];
175 info->pwrstat_telem.state = PWR_AWAIT_ENTRY;
179 PrintError(info->vm_info, info, "Impossible state on pwrstat telemetry exit\n");
186 void v3_pwrstat_telemetry_end (struct guest_info *info)
188 if (!info->vm_info->enable_telemetry) {
194 info->pwrstat_telem.state=PWR_AWAIT_FIRST_ENTRY;