Commit | Line | Data |
---|---|---|
451ba2f7 AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2012, 2015 Ericsson | |
3 | * Copyright (c) 2010, 2011 École Polytechnique de Montréal | |
4 | * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com> | |
5 | * | |
6 | * All rights reserved. This program and the accompanying materials are | |
7 | * made available under the terms of the Eclipse Public License v1.0 which | |
8 | * accompanies this distribution, and is available at | |
9 | * http://www.eclipse.org/legal/epl-v10.html | |
10 | * | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.lttng.scope.lttng.kernel.core.analysis.os.internal; | |
14 | ||
15 | import static java.util.Objects.requireNonNull; | |
16 | ||
17 | import java.util.Map; | |
18 | ||
19 | import org.eclipse.jdt.annotation.Nullable; | |
20 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; | |
21 | import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; | |
22 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
23 | import org.lttng.scope.lttng.kernel.core.activator.internal.Activator; | |
24 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IPIEntryHandler; | |
25 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IPIExitHandler; | |
26 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IrqEntryHandler; | |
27 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.IrqExitHandler; | |
28 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.KernelEventHandler; | |
29 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.PiSetprioHandler; | |
30 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.ProcessExitHandler; | |
31 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.ProcessForkHandler; | |
32 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.ProcessFreeHandler; | |
33 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SchedMigrateTaskHandler; | |
34 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SchedSwitchHandler; | |
35 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SchedWakeupHandler; | |
36 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SoftIrqEntryHandler; | |
37 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SoftIrqExitHandler; | |
38 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SoftIrqRaiseHandler; | |
39 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.StateDumpHandler; | |
40 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SysEntryHandler; | |
41 | import org.lttng.scope.lttng.kernel.core.analysis.os.handlers.internal.SysExitHandler; | |
42 | import org.lttng.scope.lttng.kernel.core.trace.layout.ILttngKernelEventLayout; | |
43 | ||
44 | import com.google.common.collect.ImmutableMap; | |
45 | ||
46 | import ca.polymtl.dorsal.libdelorean.ITmfStateSystemBuilder; | |
47 | import ca.polymtl.dorsal.libdelorean.exceptions.AttributeNotFoundException; | |
48 | import ca.polymtl.dorsal.libdelorean.exceptions.StateValueTypeException; | |
49 | import ca.polymtl.dorsal.libdelorean.exceptions.TimeRangeException; | |
50 | ||
51 | /** | |
52 | * This is the state change input plugin for the state system which handles the | |
53 | * kernel traces. | |
54 | * | |
55 | * Attribute tree: | |
56 | * | |
57 | * <pre> | |
58 | * |- CPUs | |
59 | * | |- <CPU number> -> CPU Status | |
60 | * | | |- CURRENT_THREAD | |
61 | * | | |- SOFT_IRQS | |
62 | * | | | |- <Soft IRQ number> -> Soft IRQ Status | |
63 | * | | |- IRQS | |
64 | * | | | |- <IRQ number> -> IRQ Status | |
65 | * |- THREADS | |
66 | * | |- <Thread number> -> Thread Status | |
67 | * | | |- PPID | |
68 | * | | |- EXEC_NAME | |
69 | * | | |- PRIO | |
70 | * | | |- SYSTEM_CALL | |
71 | * | | |- CURRENT_CPU_RQ | |
72 | * </pre> | |
73 | * | |
74 | * @author Alexandre Montplaisir | |
75 | */ | |
76 | public class KernelStateProvider extends AbstractTmfStateProvider { | |
77 | ||
78 | // ------------------------------------------------------------------------ | |
79 | // Static fields | |
80 | // ------------------------------------------------------------------------ | |
81 | ||
82 | /** | |
83 | * Version number of this state provider. Please bump this if you modify the | |
84 | * contents of the generated state history in some way. | |
85 | */ | |
86 | private static final int VERSION = 25; | |
87 | ||
88 | // ------------------------------------------------------------------------ | |
89 | // Fields | |
90 | // ------------------------------------------------------------------------ | |
91 | ||
92 | private final Map<String, KernelEventHandler> fEventNames; | |
93 | private final ILttngKernelEventLayout fLayout; | |
94 | ||
95 | private final KernelEventHandler fSysEntryHandler; | |
96 | private final KernelEventHandler fSysExitHandler; | |
97 | ||
98 | // ------------------------------------------------------------------------ | |
99 | // Constructor | |
100 | // ------------------------------------------------------------------------ | |
101 | ||
102 | /** | |
103 | * Instantiate a new state provider plugin. | |
104 | * | |
105 | * @param trace | |
106 | * The LTTng 2.0 kernel trace directory | |
107 | * @param layout | |
108 | * The event layout to use for this state provider. Usually | |
109 | * depending on the tracer implementation. | |
110 | */ | |
111 | public KernelStateProvider(ITmfTrace trace, ILttngKernelEventLayout layout) { | |
112 | super(trace, "Kernel"); //$NON-NLS-1$ | |
113 | fLayout = layout; | |
114 | fEventNames = buildEventNames(layout); | |
115 | ||
116 | fSysEntryHandler = new SysEntryHandler(fLayout); | |
117 | fSysExitHandler = new SysExitHandler(fLayout); | |
118 | } | |
119 | ||
120 | // ------------------------------------------------------------------------ | |
121 | // Event names management | |
122 | // ------------------------------------------------------------------------ | |
123 | ||
124 | private static Map<String, KernelEventHandler> buildEventNames(ILttngKernelEventLayout layout) { | |
125 | ImmutableMap.Builder<String, KernelEventHandler> builder = ImmutableMap.builder(); | |
126 | ||
127 | builder.put(layout.eventIrqHandlerEntry(), new IrqEntryHandler(layout)); | |
128 | builder.put(layout.eventIrqHandlerExit(), new IrqExitHandler(layout)); | |
129 | builder.put(layout.eventSoftIrqEntry(), new SoftIrqEntryHandler(layout)); | |
130 | builder.put(layout.eventSoftIrqExit(), new SoftIrqExitHandler(layout)); | |
131 | builder.put(layout.eventSoftIrqRaise(), new SoftIrqRaiseHandler(layout)); | |
132 | builder.put(layout.eventSchedSwitch(), new SchedSwitchHandler(layout)); | |
133 | builder.put(layout.eventSchedPiSetprio(), new PiSetprioHandler(layout)); | |
134 | builder.put(layout.eventSchedProcessFork(), new ProcessForkHandler(layout)); | |
135 | builder.put(layout.eventSchedProcessExit(), new ProcessExitHandler(layout)); | |
136 | builder.put(layout.eventSchedProcessFree(), new ProcessFreeHandler(layout)); | |
137 | builder.put(layout.eventSchedProcessWaking(), new SchedWakeupHandler(layout)); | |
138 | builder.put(layout.eventSchedMigrateTask(), new SchedMigrateTaskHandler(layout)); | |
139 | ||
140 | for (String s : layout.getIPIIrqVectorsEntries()) { | |
141 | builder.put(s, new IPIEntryHandler(layout)); | |
142 | } | |
143 | for (String s : layout.getIPIIrqVectorsExits()) { | |
144 | builder.put(s, new IPIExitHandler(layout)); | |
145 | } | |
146 | ||
147 | final String eventStatedumpProcessState = layout.eventStatedumpProcessState(); | |
148 | if (eventStatedumpProcessState != null) { | |
149 | builder.put(eventStatedumpProcessState, new StateDumpHandler(layout)); | |
150 | } | |
151 | ||
152 | for (String eventSchedWakeup : layout.eventsSchedWakeup()) { | |
153 | builder.put(eventSchedWakeup, new SchedWakeupHandler(layout)); | |
154 | } | |
155 | ||
156 | return builder.build(); | |
157 | } | |
158 | ||
159 | // ------------------------------------------------------------------------ | |
160 | // IStateChangeInput | |
161 | // ------------------------------------------------------------------------ | |
162 | ||
163 | @Override | |
164 | public int getVersion() { | |
165 | return VERSION; | |
166 | } | |
167 | ||
168 | @Override | |
169 | public KernelStateProvider getNewInstance() { | |
170 | return new KernelStateProvider(this.getTrace(), fLayout); | |
171 | } | |
172 | ||
173 | @Override | |
174 | protected void eventHandle(@Nullable ITmfEvent event) { | |
175 | if (event == null) { | |
176 | return; | |
177 | } | |
178 | ||
179 | final String eventName = event.getName(); | |
180 | ||
181 | try { | |
182 | final ITmfStateSystemBuilder ss = requireNonNull(getStateSystemBuilder()); | |
183 | /* | |
184 | * Feed event to the history system if it's known to cause a state | |
185 | * transition. | |
186 | */ | |
187 | KernelEventHandler handler = fEventNames.get(eventName); | |
188 | if (handler == null) { | |
189 | if (isSyscallExit(eventName)) { | |
190 | handler = fSysExitHandler; | |
191 | } else if (isSyscallEntry(eventName)) { | |
192 | handler = fSysEntryHandler; | |
193 | } | |
194 | } | |
195 | if (handler != null) { | |
196 | handler.handleEvent(ss, event); | |
197 | } | |
198 | ||
199 | } catch (AttributeNotFoundException ae) { | |
200 | /* | |
201 | * This would indicate a problem with the logic of the manager here, | |
202 | * so it shouldn't happen. | |
203 | */ | |
204 | Activator.instance().logError("Attribute not found: " + ae.getMessage(), ae); //$NON-NLS-1$ | |
205 | ||
206 | } catch (TimeRangeException tre) { | |
207 | /* | |
208 | * This would happen if the events in the trace aren't ordered | |
209 | * chronologically, which should never be the case ... | |
210 | */ | |
211 | Activator.instance().logError("TimeRangeExcpetion caught in the state system's event manager.\n" + //$NON-NLS-1$ | |
212 | "Are the events in the trace correctly ordered?\n" + tre.getMessage(), tre); //$NON-NLS-1$ | |
213 | ||
214 | } catch (StateValueTypeException sve) { | |
215 | /* | |
216 | * This would happen if we were trying to push/pop attributes not of | |
217 | * type integer. Which, once again, should never happen. | |
218 | */ | |
219 | Activator.instance().logError("State value error: " + sve.getMessage(), sve); //$NON-NLS-1$ | |
220 | } | |
221 | } | |
222 | ||
223 | private boolean isSyscallEntry(String eventName) { | |
224 | return (eventName.startsWith(fLayout.eventSyscallEntryPrefix()) | |
225 | || eventName.startsWith(fLayout.eventCompatSyscallEntryPrefix())); | |
226 | } | |
227 | ||
228 | private boolean isSyscallExit(String eventName) { | |
229 | return (eventName.startsWith(fLayout.eventSyscallExitPrefix()) || | |
230 | eventName.startsWith(fLayout.eventCompatSyscallExitPrefix())); | |
231 | } | |
232 | ||
233 | } |