Fix task state unknown with Linux >= 4.1
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Thu, 24 Mar 2016 13:33:07 +0000 (09:33 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 25 Mar 2016 18:49:43 +0000 (14:49 -0400)
The control flow view displays the task state as WAIT_UNKNOWN with
newer kernels. This is caused by a new task state value. The mask is
adjusted to fit this new value.

The fix is backward compatible.

Change-Id: I568dd51cd597ab64819cc6a83a3c6f06ec859489
Signed-off-by: Francis Giraldeau <francis.giraldeau@gmail.com>
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/67377
Reviewed-by: Hudson CI
Reviewed-by: Alexandre Montplaisir <alexmonthy@efficios.com>
Tested-by: Alexandre Montplaisir <alexmonthy@efficios.com>
analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/src/org/eclipse/tracecompass/analysis/os/linux/core/tests/kernel/KernelThreadInformationProviderTest.java
analysis/org.eclipse.tracecompass.analysis.os.linux.core.tests/testfiles/kernel_analysis/lttng_kernel_analysis.xml
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/kernel/LinuxValues.java
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/SchedSwitchHandler.java

index 2722a5fa30f0ab1b48480c62475057cd229a8c7a..b22ab40bc2419422df527fe7dbbb9f02d17556e4 100644 (file)
@@ -118,7 +118,7 @@ public class KernelThreadInformationProviderTest {
         Integer tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, -1);
         assertNull(tid);
 
-        tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 80);
+        tid = KernelThreadInformationProvider.getThreadOnCpu(module, 0, 90);
         assertNull(tid);
 
         /* Check with invalid cpus */
@@ -171,7 +171,7 @@ public class KernelThreadInformationProviderTest {
         Integer ppid = KernelThreadInformationProvider.getParentPid(module, 11, -1);
         assertNull(ppid);
 
-        ppid = KernelThreadInformationProvider.getParentPid(module, 11, 80);
+        ppid = KernelThreadInformationProvider.getParentPid(module, 11, 90);
         assertNull(ppid);
 
         /* Check with invalid cpus */
@@ -252,7 +252,7 @@ public class KernelThreadInformationProviderTest {
         List<ITmfStateInterval> intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, -15, -5, 3, monitor);
         assertTrue(intervals.isEmpty());
 
-        intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 80, 1500000000L, 50, monitor);
+        intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process21, 90, 1500000000L, 50, monitor);
         assertTrue(intervals.isEmpty());
 
         /* Check invalid quarks */
@@ -293,6 +293,10 @@ public class KernelThreadInformationProviderTest {
         intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 25, 50L, 3, monitor);
         testIntervals("tid 20 [25,50,3]", intervals, values6);
 
+        ITmfStateValue[] values7 = { StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE };
+        intervals = KernelThreadInformationProvider.getStatusIntervalsForThread(module, process20, 80L, 85L, 3, monitor);
+        testIntervals("tid 20 [80,85,3]", intervals, values7);
+
     }
 
 }
index 4e0469a9dc6a1e23cca50ad0fb3560ae36b82983..ea93d1758d61205cdc2229d6e600213a494fec44 100644 (file)
 <field name="next_tid" value="20" type="long" />
 <field name="next_prio" value="20" type="long" />
 </event>
+<event timestamp="80" name="sched_switch">
+<field name="cpu" value="1" type="int" />
+<field name="prev_comm" value="proc20" type="string" />
+<field name="prev_tid" value="20" type="long" />
+<field name="prev_prio" value="20" type="long" />
+<field name="prev_state" value="2048" type="long" />
+<field name="next_comm" value="proc21" type="string" />
+<field name="next_tid" value="21" type="long" />
+<field name="next_prio" value="20" type="long" />
+</event>
 </trace>
\ No newline at end of file
index 91b6cac23541a0eca7017e01eb134d53b3c34cd2..8e1b63a7ddfb013dd97752f9f2a9d0de4bac9003 100644 (file)
@@ -38,7 +38,8 @@ public interface LinuxValues {
      * #define TASK_WAKEKILL 128
      * #define TASK_WAKING 256
      * #define TASK_PARKED 512
-     * #define TASK_STATE_MAX 1024
+     * #define TASK_NOLOAD 1024
+     * #define TASK_STATE_MAX 2048
      * </pre>
      */
     /**
@@ -100,11 +101,16 @@ public interface LinuxValues {
      */
     int TASK_PARK = 512;
 
+    /**
+     * Task that do not contribute to load average (since Linux 4.1)
+     */
+    int TASK_NOLOAD = 1024;
+
     /**
      * This is the maximum value + 1 that the task state can be. TASK_STATE_MAX
      * - 1 is useful to mask the task state.
      */
-    int TASK_STATE_MAX = 1024;
+    int TASK_STATE_MAX = 2048;
 
     /**
      * Process statuses, used in LTTng statedump events.
index a250921b99d903528b9d3c102efe9951a57ef830..47133d70eee33c18f0a7783d4d79f0aaed7834bd 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 = 13;
+    private static final int VERSION = 14;
 
     // ------------------------------------------------------------------------
     // Fields
index 7aabf0fd9967296d6aa92761cdfa48ca2e72e0c9..f6054030d9b495d2c0212524b85e5791b8484cce 100644 (file)
@@ -86,12 +86,16 @@ public class SchedSwitchHandler extends KernelEventHandler {
     private static void setOldProcessStatus(ITmfStateSystemBuilder ss, Long prevState, Integer formerThreadNode, long timestamp) throws AttributeNotFoundException {
         ITmfStateValue value;
         /*
-         * Empirical observations and look into the linux code have shown that
-         * the TASK_STATE_MAX flag is used internally and |'ed with other
-         * states, most often the running state, so it is ignored from the
-         * prevState value.
+         * Empirical observations and look into the linux code have
+         * shown that the TASK_STATE_MAX flag is used internally and
+         * |'ed with other states, most often the running state, so it
+         * is ignored from the prevState value.
+         *
+         * Since Linux 4.1, the TASK_NOLOAD state was created and
+         * TASK_STATE_MAX is now 2048. We use TASK_NOLOAD as the new max
+         * because it does not modify the displayed state value.
          */
-        int state = (int) (prevState & ~(LinuxValues.TASK_STATE_MAX));
+        int state = (int) (prevState & (LinuxValues.TASK_NOLOAD - 1));
 
         if (isRunning(state)) {
             value = StateValues.PROCESS_STATUS_WAIT_FOR_CPU_VALUE;
This page took 0.031031 seconds and 5 git commands to generate.