diff options
author | Andrey Smetanin <asmetanin@virtuozzo.com> | 2015-12-23 08:54:00 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-01-08 13:04:43 -0500 |
commit | ac3e5fcae8ca658e7dcc3fdcd50af7e4779f58c1 (patch) | |
tree | 37a76f87d2f8deacc228a4928dfb8d185e7edfc8 | |
parent | 18659a9cb1885d00dd428f8857f7f628e54a45ee (diff) |
kvm/x86: Hyper-V SynIC timers tracepoints
Trace the following Hyper SynIC timers events:
* periodic timer start
* one-shot timer start
* timer callback
* timer expiration and message delivery result
* timer config setup
* timer count setup
* timer cleanup
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/hyperv.c | 27 | ||||
-rw-r--r-- | arch/x86/kvm/trace.h | 170 |
2 files changed, 196 insertions, 1 deletions
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 2d83d4598507..c58ba67175ac 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c | |||
@@ -405,6 +405,9 @@ static void stimer_cleanup(struct kvm_vcpu_hv_stimer *stimer) | |||
405 | { | 405 | { |
406 | struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer); | 406 | struct kvm_vcpu *vcpu = stimer_to_vcpu(stimer); |
407 | 407 | ||
408 | trace_kvm_hv_stimer_cleanup(stimer_to_vcpu(stimer)->vcpu_id, | ||
409 | stimer->index); | ||
410 | |||
408 | hrtimer_cancel(&stimer->timer); | 411 | hrtimer_cancel(&stimer->timer); |
409 | clear_bit(stimer->index, | 412 | clear_bit(stimer->index, |
410 | vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap); | 413 | vcpu_to_hv_vcpu(vcpu)->stimer_pending_bitmap); |
@@ -417,6 +420,8 @@ static enum hrtimer_restart stimer_timer_callback(struct hrtimer *timer) | |||
417 | struct kvm_vcpu_hv_stimer *stimer; | 420 | struct kvm_vcpu_hv_stimer *stimer; |
418 | 421 | ||
419 | stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer); | 422 | stimer = container_of(timer, struct kvm_vcpu_hv_stimer, timer); |
423 | trace_kvm_hv_stimer_callback(stimer_to_vcpu(stimer)->vcpu_id, | ||
424 | stimer->index); | ||
420 | stimer_mark_pending(stimer, true); | 425 | stimer_mark_pending(stimer, true); |
421 | 426 | ||
422 | return HRTIMER_NORESTART; | 427 | return HRTIMER_NORESTART; |
@@ -448,6 +453,11 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) | |||
448 | } else | 453 | } else |
449 | stimer->exp_time = time_now + stimer->count; | 454 | stimer->exp_time = time_now + stimer->count; |
450 | 455 | ||
456 | trace_kvm_hv_stimer_start_periodic( | ||
457 | stimer_to_vcpu(stimer)->vcpu_id, | ||
458 | stimer->index, | ||
459 | time_now, stimer->exp_time); | ||
460 | |||
451 | hrtimer_start(&stimer->timer, | 461 | hrtimer_start(&stimer->timer, |
452 | ktime_add_ns(ktime_now, | 462 | ktime_add_ns(ktime_now, |
453 | 100 * (stimer->exp_time - time_now)), | 463 | 100 * (stimer->exp_time - time_now)), |
@@ -466,6 +476,10 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) | |||
466 | return 0; | 476 | return 0; |
467 | } | 477 | } |
468 | 478 | ||
479 | trace_kvm_hv_stimer_start_one_shot(stimer_to_vcpu(stimer)->vcpu_id, | ||
480 | stimer->index, | ||
481 | time_now, stimer->count); | ||
482 | |||
469 | hrtimer_start(&stimer->timer, | 483 | hrtimer_start(&stimer->timer, |
470 | ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)), | 484 | ktime_add_ns(ktime_now, 100 * (stimer->count - time_now)), |
471 | HRTIMER_MODE_ABS); | 485 | HRTIMER_MODE_ABS); |
@@ -475,6 +489,9 @@ static int stimer_start(struct kvm_vcpu_hv_stimer *stimer) | |||
475 | static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config, | 489 | static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config, |
476 | bool host) | 490 | bool host) |
477 | { | 491 | { |
492 | trace_kvm_hv_stimer_set_config(stimer_to_vcpu(stimer)->vcpu_id, | ||
493 | stimer->index, config, host); | ||
494 | |||
478 | stimer_cleanup(stimer); | 495 | stimer_cleanup(stimer); |
479 | if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0) | 496 | if ((stimer->config & HV_STIMER_ENABLE) && HV_STIMER_SINT(config) == 0) |
480 | config &= ~HV_STIMER_ENABLE; | 497 | config &= ~HV_STIMER_ENABLE; |
@@ -486,6 +503,9 @@ static int stimer_set_config(struct kvm_vcpu_hv_stimer *stimer, u64 config, | |||
486 | static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count, | 503 | static int stimer_set_count(struct kvm_vcpu_hv_stimer *stimer, u64 count, |
487 | bool host) | 504 | bool host) |
488 | { | 505 | { |
506 | trace_kvm_hv_stimer_set_count(stimer_to_vcpu(stimer)->vcpu_id, | ||
507 | stimer->index, count, host); | ||
508 | |||
489 | stimer_cleanup(stimer); | 509 | stimer_cleanup(stimer); |
490 | stimer->count = count; | 510 | stimer->count = count; |
491 | if (stimer->count == 0) | 511 | if (stimer->count == 0) |
@@ -564,8 +584,13 @@ static int stimer_send_msg(struct kvm_vcpu_hv_stimer *stimer) | |||
564 | 584 | ||
565 | static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer) | 585 | static void stimer_expiration(struct kvm_vcpu_hv_stimer *stimer) |
566 | { | 586 | { |
587 | int r; | ||
588 | |||
567 | stimer->msg_pending = true; | 589 | stimer->msg_pending = true; |
568 | if (!stimer_send_msg(stimer)) { | 590 | r = stimer_send_msg(stimer); |
591 | trace_kvm_hv_stimer_expiration(stimer_to_vcpu(stimer)->vcpu_id, | ||
592 | stimer->index, r); | ||
593 | if (!r) { | ||
569 | stimer->msg_pending = false; | 594 | stimer->msg_pending = false; |
570 | if (!(stimer->config & HV_STIMER_PERIODIC)) | 595 | if (!(stimer->config & HV_STIMER_PERIODIC)) |
571 | stimer->config &= ~HV_STIMER_ENABLE; | 596 | stimer->config &= ~HV_STIMER_ENABLE; |
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 4be350003bce..ad9f6a23f139 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h | |||
@@ -1118,6 +1118,176 @@ TRACE_EVENT(kvm_hv_synic_set_msr, | |||
1118 | __entry->vcpu_id, __entry->msr, __entry->data, __entry->host) | 1118 | __entry->vcpu_id, __entry->msr, __entry->data, __entry->host) |
1119 | ); | 1119 | ); |
1120 | 1120 | ||
1121 | /* | ||
1122 | * Tracepoint for stimer_set_config. | ||
1123 | */ | ||
1124 | TRACE_EVENT(kvm_hv_stimer_set_config, | ||
1125 | TP_PROTO(int vcpu_id, int timer_index, u64 config, bool host), | ||
1126 | TP_ARGS(vcpu_id, timer_index, config, host), | ||
1127 | |||
1128 | TP_STRUCT__entry( | ||
1129 | __field(int, vcpu_id) | ||
1130 | __field(int, timer_index) | ||
1131 | __field(u64, config) | ||
1132 | __field(bool, host) | ||
1133 | ), | ||
1134 | |||
1135 | TP_fast_assign( | ||
1136 | __entry->vcpu_id = vcpu_id; | ||
1137 | __entry->timer_index = timer_index; | ||
1138 | __entry->config = config; | ||
1139 | __entry->host = host; | ||
1140 | ), | ||
1141 | |||
1142 | TP_printk("vcpu_id %d timer %d config 0x%llx host %d", | ||
1143 | __entry->vcpu_id, __entry->timer_index, __entry->config, | ||
1144 | __entry->host) | ||
1145 | ); | ||
1146 | |||
1147 | /* | ||
1148 | * Tracepoint for stimer_set_count. | ||
1149 | */ | ||
1150 | TRACE_EVENT(kvm_hv_stimer_set_count, | ||
1151 | TP_PROTO(int vcpu_id, int timer_index, u64 count, bool host), | ||
1152 | TP_ARGS(vcpu_id, timer_index, count, host), | ||
1153 | |||
1154 | TP_STRUCT__entry( | ||
1155 | __field(int, vcpu_id) | ||
1156 | __field(int, timer_index) | ||
1157 | __field(u64, count) | ||
1158 | __field(bool, host) | ||
1159 | ), | ||
1160 | |||
1161 | TP_fast_assign( | ||
1162 | __entry->vcpu_id = vcpu_id; | ||
1163 | __entry->timer_index = timer_index; | ||
1164 | __entry->count = count; | ||
1165 | __entry->host = host; | ||
1166 | ), | ||
1167 | |||
1168 | TP_printk("vcpu_id %d timer %d count %llu host %d", | ||
1169 | __entry->vcpu_id, __entry->timer_index, __entry->count, | ||
1170 | __entry->host) | ||
1171 | ); | ||
1172 | |||
1173 | /* | ||
1174 | * Tracepoint for stimer_start(periodic timer case). | ||
1175 | */ | ||
1176 | TRACE_EVENT(kvm_hv_stimer_start_periodic, | ||
1177 | TP_PROTO(int vcpu_id, int timer_index, u64 time_now, u64 exp_time), | ||
1178 | TP_ARGS(vcpu_id, timer_index, time_now, exp_time), | ||
1179 | |||
1180 | TP_STRUCT__entry( | ||
1181 | __field(int, vcpu_id) | ||
1182 | __field(int, timer_index) | ||
1183 | __field(u64, time_now) | ||
1184 | __field(u64, exp_time) | ||
1185 | ), | ||
1186 | |||
1187 | TP_fast_assign( | ||
1188 | __entry->vcpu_id = vcpu_id; | ||
1189 | __entry->timer_index = timer_index; | ||
1190 | __entry->time_now = time_now; | ||
1191 | __entry->exp_time = exp_time; | ||
1192 | ), | ||
1193 | |||
1194 | TP_printk("vcpu_id %d timer %d time_now %llu exp_time %llu", | ||
1195 | __entry->vcpu_id, __entry->timer_index, __entry->time_now, | ||
1196 | __entry->exp_time) | ||
1197 | ); | ||
1198 | |||
1199 | /* | ||
1200 | * Tracepoint for stimer_start(one-shot timer case). | ||
1201 | */ | ||
1202 | TRACE_EVENT(kvm_hv_stimer_start_one_shot, | ||
1203 | TP_PROTO(int vcpu_id, int timer_index, u64 time_now, u64 count), | ||
1204 | TP_ARGS(vcpu_id, timer_index, time_now, count), | ||
1205 | |||
1206 | TP_STRUCT__entry( | ||
1207 | __field(int, vcpu_id) | ||
1208 | __field(int, timer_index) | ||
1209 | __field(u64, time_now) | ||
1210 | __field(u64, count) | ||
1211 | ), | ||
1212 | |||
1213 | TP_fast_assign( | ||
1214 | __entry->vcpu_id = vcpu_id; | ||
1215 | __entry->timer_index = timer_index; | ||
1216 | __entry->time_now = time_now; | ||
1217 | __entry->count = count; | ||
1218 | ), | ||
1219 | |||
1220 | TP_printk("vcpu_id %d timer %d time_now %llu count %llu", | ||
1221 | __entry->vcpu_id, __entry->timer_index, __entry->time_now, | ||
1222 | __entry->count) | ||
1223 | ); | ||
1224 | |||
1225 | /* | ||
1226 | * Tracepoint for stimer_timer_callback. | ||
1227 | */ | ||
1228 | TRACE_EVENT(kvm_hv_stimer_callback, | ||
1229 | TP_PROTO(int vcpu_id, int timer_index), | ||
1230 | TP_ARGS(vcpu_id, timer_index), | ||
1231 | |||
1232 | TP_STRUCT__entry( | ||
1233 | __field(int, vcpu_id) | ||
1234 | __field(int, timer_index) | ||
1235 | ), | ||
1236 | |||
1237 | TP_fast_assign( | ||
1238 | __entry->vcpu_id = vcpu_id; | ||
1239 | __entry->timer_index = timer_index; | ||
1240 | ), | ||
1241 | |||
1242 | TP_printk("vcpu_id %d timer %d", | ||
1243 | __entry->vcpu_id, __entry->timer_index) | ||
1244 | ); | ||
1245 | |||
1246 | /* | ||
1247 | * Tracepoint for stimer_expiration. | ||
1248 | */ | ||
1249 | TRACE_EVENT(kvm_hv_stimer_expiration, | ||
1250 | TP_PROTO(int vcpu_id, int timer_index, int msg_send_result), | ||
1251 | TP_ARGS(vcpu_id, timer_index, msg_send_result), | ||
1252 | |||
1253 | TP_STRUCT__entry( | ||
1254 | __field(int, vcpu_id) | ||
1255 | __field(int, timer_index) | ||
1256 | __field(int, msg_send_result) | ||
1257 | ), | ||
1258 | |||
1259 | TP_fast_assign( | ||
1260 | __entry->vcpu_id = vcpu_id; | ||
1261 | __entry->timer_index = timer_index; | ||
1262 | __entry->msg_send_result = msg_send_result; | ||
1263 | ), | ||
1264 | |||
1265 | TP_printk("vcpu_id %d timer %d msg send result %d", | ||
1266 | __entry->vcpu_id, __entry->timer_index, | ||
1267 | __entry->msg_send_result) | ||
1268 | ); | ||
1269 | |||
1270 | /* | ||
1271 | * Tracepoint for stimer_cleanup. | ||
1272 | */ | ||
1273 | TRACE_EVENT(kvm_hv_stimer_cleanup, | ||
1274 | TP_PROTO(int vcpu_id, int timer_index), | ||
1275 | TP_ARGS(vcpu_id, timer_index), | ||
1276 | |||
1277 | TP_STRUCT__entry( | ||
1278 | __field(int, vcpu_id) | ||
1279 | __field(int, timer_index) | ||
1280 | ), | ||
1281 | |||
1282 | TP_fast_assign( | ||
1283 | __entry->vcpu_id = vcpu_id; | ||
1284 | __entry->timer_index = timer_index; | ||
1285 | ), | ||
1286 | |||
1287 | TP_printk("vcpu_id %d timer %d", | ||
1288 | __entry->vcpu_id, __entry->timer_index) | ||
1289 | ); | ||
1290 | |||
1121 | #endif /* _TRACE_KVM_H */ | 1291 | #endif /* _TRACE_KVM_H */ |
1122 | 1292 | ||
1123 | #undef TRACE_INCLUDE_PATH | 1293 | #undef TRACE_INCLUDE_PATH |