Skip to content

Commit db56fb7

Browse files
committed
vm: cleaning VM flow analysis code
Signed-off-by: philippe <beliasossim@gmail.com>
1 parent 396b8f9 commit db56fb7

11 files changed

Lines changed: 300 additions & 41 deletions

File tree

vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/plugin.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
id="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.state.system.module"
6060
name="Exit analysis">
6161
<tracetype
62+
applies="true"
6263
class="org.eclipse.tracecompass.tmf.core.trace.TmfTrace">
6364
</tracetype>
6465
</module>
@@ -72,8 +73,23 @@
7273
</module>
7374
<module
7475
analysis_module="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.VMNativeCallStackAnalysis"
75-
id="org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui.module3"
76+
applies_experiment="true"
77+
id="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.vm.native.callstack"
7678
name="VM Native CallStack">
79+
<tracetype
80+
class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace">
81+
</tracetype>
7782
</module>
7883
</extension>
84+
<extension
85+
point="org.eclipse.tracecompass.tmf.core.dataprovider">
86+
<dataProviderFactory
87+
class="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.core.data.provider.KvmExitDataProviderFactory"
88+
id="org.eclipse.incubator.overhead.xy.rate.dataprovider">
89+
</dataProviderFactory>
90+
<dataProviderFactory
91+
class="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.core.data.provider.VMNativeDataProviderFactory"
92+
id="org.eclipse.incubator.overhead.timegraph.dataprovider">
93+
</dataProviderFactory>
94+
</extension>
7995
</plugin>

vm/org.eclipse.tracecompass.incubator.virtual.machine.analysis.core/src/org/eclipse/tracecompass/incubator/internal/virtual/machine/analysis/core/flow/analysis/ExecutionSequence.java

Lines changed: 104 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,97 @@
88
import java.io.PrintWriter;
99

1010
/**
11-
* Represents a complete execution sequence: Guest → VM Exit → Host → VM Entry
11+
* Represents a complete execution sequence in a virtualized environment:
12+
* <pre>
13+
* Guest → VM Exit → Hypervisor (Host) → VM Entry
14+
* </pre>
15+
* <p>
16+
* This class aggregates events occurring in both the guest and the hypervisor,
17+
* as well as the VM exit and entry transitions that connect them.
18+
* </p>
1219
*
13-
* @author philippe
20+
* @author Francois Belias
1421
*/
1522
public class ExecutionSequence {
23+
24+
/**
25+
* List of events that occurred in the guest before the VM exit.
26+
*/
1627
private final List<FlowEvent> guestEvents = new ArrayList<>();
28+
29+
/**
30+
* List of events that occurred in the hypervisor (host)
31+
* between VM exit and VM entry.
32+
*/
1733
private final List<FlowEvent> hypervisorEvents = new ArrayList<>();
34+
35+
/**
36+
* Event representing the VM exit (transition from guest to host).
37+
*/
1838
private FlowEvent vmExit;
39+
40+
/**
41+
* Event representing the VM entry (transition from host back to guest).
42+
*/
1943
private FlowEvent vmEntry;
2044

45+
/**
46+
* Adds an event to the guest event list.
47+
*
48+
* @param event
49+
* the guest event to add
50+
*/
2151
void addGuestEvent(FlowEvent event) {
2252
guestEvents.add(event);
2353
}
2454

55+
/**
56+
* Adds an event to the hypervisor event list.
57+
*
58+
* @param event
59+
* the hypervisor event to add
60+
*/
2561
void addHypervisorEvent(FlowEvent event) {
2662
hypervisorEvents.add(event);
2763
}
2864

65+
/**
66+
* Sets the VM exit event.
67+
*
68+
* @param event
69+
* the VM exit event
70+
*/
2971
void setVmExit(FlowEvent event) {
3072
this.vmExit = event;
3173
}
3274

75+
/**
76+
* Sets the VM entry event.
77+
*
78+
* @param event
79+
* the VM entry event
80+
*/
3381
void setVmEntry(FlowEvent event) {
3482
this.vmEntry = event;
3583
}
3684

85+
/**
86+
* Prints the execution sequence for debugging purposes.
87+
* <p>
88+
* The sequence is printed both to the standard output and appended
89+
* to a file on disk.
90+
* </p>
91+
*
92+
* @throws IOException
93+
* if an I/O error occurs while writing to the file
94+
*/
3795
void printSequence() throws IOException {
3896
try (
39-
40-
FileOutputStream fos = new FileOutputStream(new File("/home/philippe/Desktop/virtualized_flow.txt"), true); //$NON-NLS-1$
97+
FileOutputStream fos = new FileOutputStream(
98+
new File("/home/philippe/Desktop/virtualized_flow.txt"), true); //$NON-NLS-1$
4199
PrintWriter writer = new PrintWriter(fos)) {
100+
101+
// Print guest events
42102
for (FlowEvent guestEvent : guestEvents) {
43103
KernelEventInfo evt = guestEvent.kernelEvent;
44104
System.out.printf(" [GUEST] %s (TID:%d, CPU:%d)\n", evt.name, evt.tid, evt.cpuid); //$NON-NLS-1$
@@ -47,41 +107,66 @@ void printSequence() throws IOException {
47107

48108
// Print VM exit
49109
if (vmExit != null) {
50-
System.out.printf(" ↓ [VM_EXIT] %s (CPU:%d, VCPU:%d, exit_reason:%s)\n", vmExit.kernelEvent.name, //$NON-NLS-1$
51-
vmExit.kernelEvent.cpuid, vmExit.kernelEvent.vcpuid, vmExit.kernelEvent.exitReason);
52-
53-
writer.printf(" ↓ [VM_EXIT] %s (CPU:%d, VCPU:%d, exit_reason:%s)\n", vmExit.kernelEvent.name, //$NON-NLS-1$
54-
vmExit.kernelEvent.cpuid, vmExit.kernelEvent.vcpuid, vmExit.kernelEvent.exitReason);
110+
System.out.printf(" ↓ [VM_EXIT] %s (CPU:%d, VCPU:%d, exit_reason:%s)\n", //$NON-NLS-1$
111+
vmExit.kernelEvent.name,
112+
vmExit.kernelEvent.cpuid,
113+
vmExit.kernelEvent.vcpuid,
114+
vmExit.kernelEvent.exitReason);
115+
116+
writer.printf(" ↓ [VM_EXIT] %s (CPU:%d, VCPU:%d, exit_reason:%s)\n", //$NON-NLS-1$
117+
vmExit.kernelEvent.name,
118+
vmExit.kernelEvent.cpuid,
119+
vmExit.kernelEvent.vcpuid,
120+
vmExit.kernelEvent.exitReason);
55121
}
56122

57123
// Print hypervisor events
58124
for (FlowEvent hypervisorEvent : hypervisorEvents) {
59125
KernelEventInfo evt = hypervisorEvent.kernelEvent;
60-
System.out.printf(" [HOST] %s (PID:%d, CPU:%d)\n", evt.name, evt.pid, evt.cpuid); //$NON-NLS-1$
126+
System.out.printf(" [HOST] %s (PID:%d, CPU:%d)\n", //$NON-NLS-1$
127+
evt.name, evt.pid, evt.cpuid);
61128

62-
writer.printf(" [HOST] %s (PID:%d, CPU:%d)\n", evt.name, evt.pid, evt.cpuid); //$NON-NLS-1$
129+
writer.printf(" [HOST] %s (PID:%d, CPU:%d)\n", //$NON-NLS-1$
130+
evt.name, evt.pid, evt.cpuid);
63131
}
64132

65133
// Print VM entry
66134
if (vmEntry != null) {
67-
System.out.printf(" ↑ [VM_ENTRY] %s (CPU:%d, VCPU:%d)\n", vmEntry.kernelEvent.name, //$NON-NLS-1$
68-
vmEntry.kernelEvent.cpuid, vmEntry.kernelEvent.vcpuid);
69-
70-
writer.printf(" ↑ [VM_ENTRY] %s (CPU:%d, VCPU:%d)\n", vmEntry.kernelEvent.name, //$NON-NLS-1$
71-
vmEntry.kernelEvent.cpuid, vmEntry.kernelEvent.vcpuid);
135+
System.out.printf(" ↑ [VM_ENTRY] %s (CPU:%d, VCPU:%d)\n", //$NON-NLS-1$
136+
vmEntry.kernelEvent.name,
137+
vmEntry.kernelEvent.cpuid,
138+
vmEntry.kernelEvent.vcpuid);
139+
140+
writer.printf(" ↑ [VM_ENTRY] %s (CPU:%d, VCPU:%d)\n", //$NON-NLS-1$
141+
vmEntry.kernelEvent.name,
142+
vmEntry.kernelEvent.cpuid,
143+
vmEntry.kernelEvent.vcpuid);
72144
}
73145

74146
// Print timing summary
75147
if (!guestEvents.isEmpty() && vmEntry != null) {
76-
long totalDuration = vmEntry.kernelEvent.timestamp -
77-
guestEvents.get(0).kernelEvent.timestamp;
78-
System.out.printf(" Total sequence duration: %d µs\n", totalDuration / 1000); //$NON-NLS-1$
148+
long totalDuration = vmEntry.kernelEvent.timestamp
149+
- guestEvents.get(0).kernelEvent.timestamp;
79150

151+
System.out.printf(" Total sequence duration: %d µs\n", totalDuration / 1000); //$NON-NLS-1$
80152
writer.printf(" Total sequence duration: %d µs\n", totalDuration / 1000); //$NON-NLS-1$
81153
}
82154
}
83155
}
84156

157+
/**
158+
* Indicates whether the execution sequence is complete.
159+
* <p>
160+
* A sequence is considered complete if it contains:
161+
* <ul>
162+
* <li>At least one guest event</li>
163+
* <li>A VM exit event</li>
164+
* <li>A VM entry event</li>
165+
* </ul>
166+
* </p>
167+
*
168+
* @return {@code true} if the sequence is complete, {@code false} otherwise
169+
*/
85170
boolean isComplete() {
86171
return !guestEvents.isEmpty() && vmExit != null && vmEntry != null;
87172
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,45 @@
11
package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis;
22

33
/**
4-
* Represents a single event in the unified flow
4+
* Represents a single event within a unified execution flow.
5+
* <p>
6+
* A {@code FlowEvent} wraps a {@link KernelEventInfo} and classifies it
7+
* according to its role in the execution sequence (guest, hypervisor,
8+
* VM transition, etc.).
9+
* </p>
10+
*
11+
* @author Francois Belias
512
*/
613
public class FlowEvent {
14+
15+
/**
16+
* The underlying kernel event associated with this flow event.
17+
*/
718
final KernelEventInfo kernelEvent;
19+
20+
/**
21+
* The type of this flow event within the execution flow.
22+
*/
823
final FlowEventType type;
9-
long correlatedGuestTimestamp = -1; // For hypervisor events
1024

25+
/**
26+
* Timestamp of the corresponding guest event, used for correlating
27+
* hypervisor events back to guest execution.
28+
* <p>
29+
* This value is primarily used for {@link FlowEventType#HYPERVISOR_EVENT}
30+
* and is set to {@code -1} when not applicable.
31+
* </p>
32+
*/
33+
long correlatedGuestTimestamp = -1;
34+
35+
/**
36+
* Constructs a {@code FlowEvent}.
37+
*
38+
* @param kernelEvent
39+
* the underlying kernel event
40+
* @param type
41+
* the type of the flow event
42+
*/
1143
FlowEvent(KernelEventInfo kernelEvent, FlowEventType type) {
1244
this.kernelEvent = kernelEvent;
1345
this.type = type;
@@ -16,12 +48,36 @@ public class FlowEvent {
1648

1749

1850
/**
19-
* Types of events in the unified flow
51+
* Enumerates the different types of events in a unified execution flow.
52+
* <p>
53+
* These types describe the role of each event in the interaction between
54+
* guest execution and hypervisor activity.
55+
* </p>
2056
*/
2157
enum FlowEventType {
22-
GUEST_EVENT, // Normal guest process event
23-
VM_EXIT, // VM exit to hypervisor
24-
HYPERVISOR_EVENT, // Host/hypervisor processing
25-
VM_ENTRY, // VM entry back to guest
26-
NATIVE // Native system
58+
59+
/**
60+
* A regular event occurring in the guest (virtual machine).
61+
*/
62+
GUEST_EVENT,
63+
64+
/**
65+
* A VM exit event, marking the transition from guest to hypervisor.
66+
*/
67+
VM_EXIT,
68+
69+
/**
70+
* An event occurring in the hypervisor (host) while handling a VM exit.
71+
*/
72+
HYPERVISOR_EVENT,
73+
74+
/**
75+
* A VM entry event, marking the transition from hypervisor back to guest.
76+
*/
77+
VM_ENTRY,
78+
79+
/**
80+
* An event occurring in a native (non-virtualized) environment.
81+
*/
82+
NATIVE
2783
}

0 commit comments

Comments
 (0)