os.linux: Fix CPU state when Softirq is interrupted
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Fri, 11 Mar 2016 19:16:09 +0000 (14:16 -0500)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Tue, 29 Mar 2016 19:22:17 +0000 (15:22 -0400)
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 <matthew.khouzam@ericsson.com>
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
Reviewed-on: https://git.eclipse.org/r/68002
Reviewed-by: Hudson CI
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/KernelStateProvider.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/KernelEventHandlerUtils.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/ProcessForkHandler.java
lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/kernel/statesystem/TestValues.java

index 47133d70eee33c18f0a7783d4d79f0aaed7834bd..93c187bb8400455a21aafe3bf7f40ebce3cf2880 100644 (file)
@@ -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
index 749cc5feae3034edc1f3bbf56b62b6ec5f19980e..a3a60d068fdf95b4a468459b008b57f55d9d36fd 100644 (file)
@@ -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
+     *
+     * <ul>
+     * <li>IRQ</li>
+     * <li>Soft IRQ</li>
+     * <li>Process</li>
+     * </ul>
+     *
+     * 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<Integer> 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<Integer> 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);
+    }
+
 }
index 970eaee1c0bf5ddab2cc120e7e97f919deca274a..c34b52fd2a9ee8b82d24451dd20aea89a5b2843b 100644 (file)
@@ -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);
index eac94cd00045ade15190e49521171ba1efa98f8c..a35725c2685669b17b69ab6a9d2fa05a1691474b 100644 (file)
@@ -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
This page took 0.030673 seconds and 5 git commands to generate.