os.linux: make SoftIrqs support being raised while executing.
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 10 Feb 2016 03:39:42 +0000 (22:39 -0500)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Thu, 17 Mar 2016 04:01:25 +0000 (00:01 -0400)
In order to do this, statevalues are now bitmasks. Many more checks
at SoftIrq Raise, Entry and Exit handlers now take into account if
there are other SoftIrqs running and will retain their state.

Fixes part 2 of bug 381497

Change-Id: I2f109d1e4e3a227c10dcdf8f54df7b42c7776d4a
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/66259
Reviewed-by: Alexandre Montplaisir <alexmonthy@efficios.com>
Tested-by: Alexandre Montplaisir <alexmonthy@efficios.com>
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/kernelanalysis/StateValues.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqEntryHandler.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqExitHandler.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqRaiseHandler.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java
lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/analysis/kernel/statesystem/TestValues.java

index ff3d5ee5c90504432104251ce711731b5bf3abed..26e666edcb3d1c89212590cdda9c1e1b274ae2ff 100644 (file)
@@ -25,19 +25,6 @@ import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
 @SuppressWarnings("javadoc")
 public interface StateValues {
 
-    /* CPU Status */
-    int CPU_STATUS_IDLE = 0;
-    int CPU_STATUS_RUN_USERMODE = 1;
-    int CPU_STATUS_RUN_SYSCALL = 2;
-    int CPU_STATUS_IRQ = 3;
-    int CPU_STATUS_SOFTIRQ = 4;
-
-    ITmfStateValue CPU_STATUS_IDLE_VALUE = TmfStateValue.newValueInt(CPU_STATUS_IDLE);
-    ITmfStateValue CPU_STATUS_RUN_USERMODE_VALUE = TmfStateValue.newValueInt(CPU_STATUS_RUN_USERMODE);
-    ITmfStateValue CPU_STATUS_RUN_SYSCALL_VALUE = TmfStateValue.newValueInt(CPU_STATUS_RUN_SYSCALL);
-    ITmfStateValue CPU_STATUS_IRQ_VALUE = TmfStateValue.newValueInt(CPU_STATUS_IRQ);
-    ITmfStateValue CPU_STATUS_SOFTIRQ_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFTIRQ);
-
     /* Process status */
     int PROCESS_STATUS_UNKNOWN = 0;
     int PROCESS_STATUS_WAIT_BLOCKED = 1;
@@ -61,8 +48,33 @@ public interface StateValues {
     ITmfStateValue PROCESS_STATUS_INTERRUPTED_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_INTERRUPTED);
     ITmfStateValue PROCESS_STATUS_WAIT_FOR_CPU_VALUE = TmfStateValue.newValueInt(PROCESS_STATUS_WAIT_FOR_CPU);
 
-    /* SoftIRQ-specific stuff. -1: null/disabled, >= 0: running on that CPU */
-    int SOFT_IRQ_RAISED = -2;
+    /* CPU Status */
+    int CPU_STATUS_IDLE = 0;
+    /**
+     * Soft IRQ raised, could happen in the CPU attribute but should not since
+     * this means that the CPU went idle when a softirq was raised.
+     *
+     * @since 2.0
+     */
+    int CPU_STATUS_SOFT_IRQ_RAISED = (1 << 0);
+    int CPU_STATUS_RUN_USERMODE = (1 << 1);
+    int CPU_STATUS_RUN_SYSCALL = (1 << 2);
+    int CPU_STATUS_SOFTIRQ = (1 << 3);
+    int CPU_STATUS_IRQ = (1 << 4);
+
+    ITmfStateValue CPU_STATUS_IDLE_VALUE = TmfStateValue.newValueInt(CPU_STATUS_IDLE);
+    ITmfStateValue CPU_STATUS_RUN_USERMODE_VALUE = TmfStateValue.newValueInt(CPU_STATUS_RUN_USERMODE);
+    ITmfStateValue CPU_STATUS_RUN_SYSCALL_VALUE = TmfStateValue.newValueInt(CPU_STATUS_RUN_SYSCALL);
+    ITmfStateValue CPU_STATUS_IRQ_VALUE = TmfStateValue.newValueInt(CPU_STATUS_IRQ);
+    ITmfStateValue CPU_STATUS_SOFTIRQ_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFTIRQ);
+
+    /** Soft IRQ is raised, CPU is in user mode */
+    ITmfStateValue SOFT_IRQ_RAISED_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFT_IRQ_RAISED);
 
-    ITmfStateValue SOFT_IRQ_RAISED_VALUE = TmfStateValue.newValueInt(SOFT_IRQ_RAISED);
+    /**
+     * If the softirq is running and another is raised at the same time.
+     *
+     * @since 2.0
+     */
+    ITmfStateValue SOFT_IRQ_RAISED_RUNNING_VALUE = TmfStateValue.newValueInt(CPU_STATUS_SOFT_IRQ_RAISED | CPU_STATUS_SOFTIRQ);
 }
index 39e08ef416510c6ea953514829928b0e460f55a0..e91d1984a28d0cc036346a4482e501b6f7472d30 100644 (file)
@@ -18,7 +18,6 @@ import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEven
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
-import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 
 /**
@@ -46,14 +45,13 @@ public class SoftIrqEntryHandler extends KernelEventHandler {
         long timestamp = KernelEventHandlerUtils.getTimestamp(event);
         Integer softIrqId = ((Long) event.getContent().getField(getLayout().fieldVec()).getValue()).intValue();
         int currentCPUNode = KernelEventHandlerUtils.getCurrentCPUNode(cpu, ss);
-        int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu,ss);
+        int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
 
         /*
-         * Mark this SoftIRQ as active in the resource tree. The state value =
-         * the CPU on which this SoftIRQ is processed
+         * Mark this SoftIRQ as active in the resource tree.
          */
         int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeSoftIRQs(cpu, ss), softIrqId.toString());
-        ITmfStateValue value = TmfStateValue.newValueInt(cpu.intValue());
+        ITmfStateValue value = StateValues.CPU_STATUS_SOFTIRQ_VALUE;
         ss.modifyAttribute(timestamp, value, quark);
 
         /* Change the status of the running process to interrupted */
index 110fe4d570d328cfde30075d8df93bcbf6e17ef9..9a8a7038b69ea318550428c31aab4e0144042085 100644 (file)
 
 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.kernelanalysis.StateValues;
 import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
@@ -45,11 +49,19 @@ public class SoftIrqExitHandler extends KernelEventHandler {
         int currentThreadNode = KernelEventHandlerUtils.getCurrentThreadNode(cpu, ss);
         /* Put this SoftIRQ back to inactive (= -1) in the resource tree */
         int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeSoftIRQs(cpu, ss), softIrqId.toString());
-        ITmfStateValue value = TmfStateValue.nullValue();
         long timestamp = KernelEventHandlerUtils.getTimestamp(event);
-
-        ss.modifyAttribute(timestamp, value, quark);
-
+        if (isSoftIrqRaised(ss.queryOngoingState(quark))) {
+            ss.modifyAttribute(timestamp, StateValues.SOFT_IRQ_RAISED_VALUE, quark);
+        } else {
+            ss.modifyAttribute(timestamp, TmfStateValue.nullValue(), quark);
+        }
+        List<Integer> softIrqs = ss.getSubAttributes(ss.getParentAttributeQuark(quark), false);
+        /* Only set status to running and no exit if ALL softirqs are exited. */
+        for (Integer softIrq : softIrqs) {
+            if (!ss.queryOngoingState(softIrq).isNull()) {
+                return;
+            }
+        }
         /* Set the previous process back to running */
         KernelEventHandlerUtils.setProcessToRunning(timestamp, currentThreadNode, ss);
 
@@ -57,4 +69,17 @@ public class SoftIrqExitHandler extends KernelEventHandler {
         KernelEventHandlerUtils.cpuExitInterrupt(timestamp, cpu, ss);
     }
 
+    /**
+     * This checks if the running <stong>bit</strong> is set
+     *
+     * @param state
+     *            the state to check
+     * @return true if in a softirq. The softirq may be pre-empted by an irq
+     */
+    private static boolean isSoftIrqRaised(@Nullable ITmfStateValue state) {
+        return (state != null &&
+                !state.isNull() &&
+                (state.unboxInt() & StateValues.CPU_STATUS_SOFT_IRQ_RAISED) == StateValues.CPU_STATUS_SOFT_IRQ_RAISED);
+    }
+
 }
index 6773c6491fe46a19cd40cf15741caacfb63ab4fb..3e955d8b9e9158da657ae967dbc2623cb07d2591 100644 (file)
@@ -12,6 +12,7 @@
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.core.kernel.handlers;
 
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.StateValues;
 import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
@@ -42,10 +43,20 @@ public class SoftIrqRaiseHandler extends KernelEventHandler {
             return;
         }
         /*
-         * Mark this SoftIRQ as *raised* in the resource tree. State value = -2
+         * Mark this SoftIRQ as *raised* in the resource tree.
          */
         int quark = ss.getQuarkRelativeAndAdd(KernelEventHandlerUtils.getNodeSoftIRQs(cpu, ss), softIrqId.toString());
-        ITmfStateValue value = StateValues.SOFT_IRQ_RAISED_VALUE;
+
+        ITmfStateValue value = (isInSoftirq(ss.queryOngoingState(quark)) ?
+                StateValues.SOFT_IRQ_RAISED_RUNNING_VALUE :
+                StateValues.SOFT_IRQ_RAISED_VALUE);
         ss.modifyAttribute(KernelEventHandlerUtils.getTimestamp(event), value, quark);
+
+    }
+
+    private static boolean isInSoftirq(@Nullable ITmfStateValue state) {
+        return (state != null &&
+                !state.isNull() &&
+                (state.unboxInt() & StateValues.CPU_STATUS_SOFTIRQ) == StateValues.CPU_STATUS_SOFTIRQ);
     }
 }
index 0aad6c0b4e6e7d374a4b180edce21432e215c09b..88994cd2e4f56fa565397af498ba5a31b5ae2472 100644 (file)
@@ -111,7 +111,7 @@ public class ResourcesPresentationProvider extends TimeGraphPresentationProvider
             } else if (entry.getType() == Type.IRQ) {
                 return State.IRQ_ACTIVE;
             } else if (entry.getType() == Type.SOFT_IRQ) {
-                if (value == StateValues.SOFT_IRQ_RAISED) {
+                if (value == StateValues.CPU_STATUS_SOFT_IRQ_RAISED) {
                     return State.SOFT_IRQ_RAISED;
                 }
                 return State.SOFT_IRQ_ACTIVE;
index 72b125af386ddcf7a5785fc9501f27e01c3fb8e0..eac94cd00045ade15190e49521171ba1efa98f8c 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
+ * Copyright (c) 2013, 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -2118,7 +2118,7 @@ interface TestValues {
         TmfStateValue.nullValue(),
         TmfStateValue.nullValue(),
         TmfStateValue.newValueInt(1397),
-        TmfStateValue.newValueInt(1),
+        TmfStateValue.newValueInt(2),
         TmfStateValue.nullValue(),
         TmfStateValue.nullValue(),
         TmfStateValue.nullValue(),
@@ -2139,7 +2139,7 @@ interface TestValues {
         TmfStateValue.nullValue(),
         TmfStateValue.nullValue(),
         TmfStateValue.newValueInt(1432),
-        TmfStateValue.newValueInt(2),
+        TmfStateValue.newValueInt(4),
         TmfStateValue.nullValue(),
         TmfStateValue.nullValue(),
         TmfStateValue.nullValue(),
This page took 0.037078 seconds and 5 git commands to generate.