From: Matthew Khouzam Date: Fri, 11 Mar 2016 19:16:09 +0000 (-0500) Subject: os.linux: Fix CPU state when Softirq is interrupted X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=6fdc59f887f741097adc6e5ddb331be85f9410f1;p=deliverable%2Ftracecompass.git os.linux: Fix CPU state when Softirq is interrupted This patch makes the cpu the aggregate of the PROCESS, all SOFTIRQs and all IRQs. The process now does a rigourous check of every state in the CPU. This can be later replaced with a virtual or aggregate entry if deemed necessary. This patch fixes bug 481855. Change-Id: I1fd368362daf269c12cc4f12f459c5a1e404e420 Signed-off-by: Matthew Khouzam Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/68002 Reviewed-by: Hudson CI --- diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/KernelStateProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/KernelStateProvider.java index 47133d70ee..93c187bb84 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/KernelStateProvider.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/KernelStateProvider.java @@ -59,7 +59,7 @@ public class KernelStateProvider extends AbstractTmfStateProvider { * Version number of this state provider. Please bump this if you modify the * contents of the generated state history in some way. */ - private static final int VERSION = 14; + private static final int VERSION = 15; // ------------------------------------------------------------------------ // Fields diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/KernelEventHandlerUtils.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/KernelEventHandlerUtils.java index 749cc5feae..a3a60d068f 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/KernelEventHandlerUtils.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/KernelEventHandlerUtils.java @@ -9,6 +9,8 @@ package org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers; +import java.util.List; + import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.analysis.os.linux.core.kernel.Attributes; import org.eclipse.tracecompass.analysis.os.linux.core.kernel.StateValues; @@ -17,6 +19,7 @@ import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundExc import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect; import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; @@ -205,26 +208,75 @@ public final class KernelEventHandlerUtils { throws StateValueTypeException, AttributeNotFoundException, TimeRangeException { int quark; - ITmfStateValue value; int currentCPUNode = getCurrentCPUNode(cpuNumber, ssb); - quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.CURRENT_THREAD); - if (ssb.queryOngoingState(quark).unboxInt() > 0) { - /* There was a process on the CPU */ - quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.SYSTEM_CALL); - if (ssb.queryOngoingState(quark).isNull()) { - /* That process was in user mode */ - value = StateValues.CPU_STATUS_RUN_USERMODE_VALUE; - } else { - /* That process was in a system call */ - value = StateValues.CPU_STATUS_RUN_SYSCALL_VALUE; - } - } else { - /* There was no real process scheduled, CPU was idle */ - value = StateValues.CPU_STATUS_IDLE_VALUE; - } quark = ssb.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATUS); + ITmfStateValue value = getCpuStatus(ssb, currentCPUNode); ssb.modifyAttribute(timestamp, value, quark); } + /** + * Get the ongoing Status state of a CPU. + * + * This will look through the states of the + * + *
    + *
  • IRQ
  • + *
  • Soft IRQ
  • + *
  • Process
  • + *
+ * + * under the CPU, giving priority to states higher in the list. If the state + * is a null value, we continue looking down the list. + * + * @param ssb + * The state system + * @param cpuQuark + * The *quark* of the CPU we are looking for. Careful, this is + * NOT the CPU number (or attribute name)! + * @return The state value that represents the status of the given CPU + * @throws AttributeNotFoundException + */ + private static ITmfStateValue getCpuStatus(ITmfStateSystemBuilder ssb, int cpuQuark) + throws AttributeNotFoundException { + + /* Check if there is a IRQ running */ + int irqQuarks = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.IRQS); + List irqs = ssb.getSubAttributes(irqQuarks, false); + for (Integer quark : irqs) { + final ITmfStateValue irqState = ssb.queryOngoingState(quark.intValue()); + if (!irqState.isNull()) { + return irqState; + } + } + + /* Check if there is a soft IRQ running */ + int softIrqQuarks = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.SOFT_IRQS); + List softIrqs = ssb.getSubAttributes(softIrqQuarks, false); + for (Integer quark : softIrqs) { + final ITmfStateValue softIrqState = ssb.queryOngoingState(quark.intValue()); + if (!softIrqState.isNull()) { + return softIrqState; + } + } + + /* + * Check if there is a thread running. If not, report IDLE. If there is, + * report the running state of the thread (usermode or system call). + */ + int currentThreadQuark = ssb.getQuarkRelativeAndAdd(cpuQuark, Attributes.CURRENT_THREAD); + ITmfStateValue currentThreadState = ssb.queryOngoingState(currentThreadQuark); + if (currentThreadState.isNull()) { + return TmfStateValue.nullValue(); + } + int tid = currentThreadState.unboxInt(); + if (tid == 0) { + return StateValues.CPU_STATUS_IDLE_VALUE; + } + int threadSystemCallQuark = ssb.getQuarkAbsoluteAndAdd(Attributes.THREADS, Integer.toString(tid), Attributes.SYSTEM_CALL); + return (ssb.queryOngoingState(threadSystemCallQuark).isNull() ? + StateValues.CPU_STATUS_RUN_USERMODE_VALUE : + StateValues.CPU_STATUS_RUN_SYSCALL_VALUE); + } + } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/ProcessForkHandler.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/ProcessForkHandler.java index 970eaee1c0..c34b52fd2a 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/ProcessForkHandler.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/ProcessForkHandler.java @@ -45,8 +45,9 @@ public class ProcessForkHandler extends KernelEventHandler { Integer parentTid = ((Long) content.getField(getLayout().fieldParentTid()).getValue()).intValue(); Integer childTid = ((Long) content.getField(getLayout().fieldChildTid()).getValue()).intValue(); - Integer parentTidNode = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), parentTid.toString()); - Integer childTidNode = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeThreads(ss), childTid.toString()); + final int threadsNode = KernelEventHandlerUtils.getNodeThreads(ss); + Integer parentTidNode = ss.getQuarkRelativeAndAdd(threadsNode, parentTid.toString()); + Integer childTidNode = ss.getQuarkRelativeAndAdd(threadsNode, childTid.toString()); /* Assign the PPID to the new process */ int quark = ss.getQuarkRelativeAndAdd(childTidNode, Attributes.PPID); diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/kernel/statesystem/TestValues.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/kernel/statesystem/TestValues.java index eac94cd000..a35725c268 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/kernel/statesystem/TestValues.java +++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/kernel/statesystem/TestValues.java @@ -25,7 +25,7 @@ import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; */ interface TestValues { - int size = 1036; + int size = 1034; long[] startTimes = { 1331668247314038062L, @@ -68,6 +68,7 @@ interface TestValues { 1331668247931793142L, 1331668247930941981L, 1331668247314038062L, + 1331668247314038062L, 1331668248011125682L, 1331668247959024716L, 1331668248011129576L, @@ -87,12 +88,10 @@ interface TestValues { 1331668247316120937L, 1331668247335112802L, 1331668247335112802L, - 1331668247314038062L, 1331668248004705322L, 1331668247314038062L, 1331668248004935409L, 1331668248004770916L, - 1331668247314038062L, 1331668248004925240L, 1331668247316553071L, 1331668247314038062L, @@ -268,7 +267,6 @@ interface TestValues { 1331668247926367737L, 1331668247423543945L, 1331668247314038062L, - 1331668247314038062L, 1331668247619316825L, 1331668247619491008L, 1331668247314038062L, @@ -1107,6 +1105,7 @@ interface TestValues { 1331668248482983146L, 1331668248482983146L, 1331668259054285979L, + 1331668259054285979L, 1331668248015170799L, 1331668248015172434L, 1331668248015176320L, @@ -1126,12 +1125,10 @@ interface TestValues { 1331668259054285979L, 1331668259054285979L, 1331668259054285979L, - 1331668259054285979L, 1331668248015959980L, 1331668259054285979L, 1331668248016172023L, 1331668248016172023L, - 1331668259054285979L, 1331668248016194935L, 1331668259054285979L, 1331668259054285979L, @@ -1307,7 +1304,6 @@ interface TestValues { 1331668248424394073L, 1331668259054285979L, 1331668259054285979L, - 1331668259054285979L, 1331668248140683324L, 1331668248140686546L, 1331668259054285979L, @@ -2156,6 +2152,7 @@ interface TestValues { TmfStateValue.nullValue(), TmfStateValue.nullValue(), TmfStateValue.nullValue(), + TmfStateValue.nullValue(), TmfStateValue.newValueString("sys_poll"), TmfStateValue.newValueString("lttng-consumerd"), TmfStateValue.nullValue(), @@ -2167,10 +2164,8 @@ interface TestValues { TmfStateValue.nullValue(), TmfStateValue.nullValue(), TmfStateValue.nullValue(), - TmfStateValue.nullValue(), TmfStateValue.newValueInt(1), TmfStateValue.newValueInt(-6), - TmfStateValue.nullValue(), TmfStateValue.newValueString("sys_ppoll"), TmfStateValue.newValueString("alsa-sink"), TmfStateValue.nullValue(), @@ -2349,7 +2344,6 @@ interface TestValues { TmfStateValue.nullValue(), TmfStateValue.nullValue(), TmfStateValue.nullValue(), - TmfStateValue.nullValue(), TmfStateValue.newValueInt(1), TmfStateValue.newValueInt(20), TmfStateValue.newValueString("sys_poll"), @@ -3143,5 +3137,4 @@ interface TestValues { TmfStateValue.nullValue(), TmfStateValue.nullValue(), }; -} - +} \ No newline at end of file