From: Matthew Khouzam Date: Wed, 10 Feb 2016 03:39:42 +0000 (-0500) Subject: os.linux: make SoftIrqs support being raised while executing. X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=8140841e1fd24349a55d7a5b467dd825822949ed;p=deliverable%2Ftracecompass.git os.linux: make SoftIrqs support being raised while executing. 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 Reviewed-on: https://git.eclipse.org/r/66259 Reviewed-by: Alexandre Montplaisir Tested-by: Alexandre Montplaisir --- diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/kernelanalysis/StateValues.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/kernelanalysis/StateValues.java index ff3d5ee5c9..26e666edcb 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/kernelanalysis/StateValues.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/analysis/os/linux/core/kernelanalysis/StateValues.java @@ -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); } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqEntryHandler.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqEntryHandler.java index 39e08ef416..e91d1984a2 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqEntryHandler.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqEntryHandler.java @@ -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 */ diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqExitHandler.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqExitHandler.java index 110fe4d570..9a8a7038b6 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqExitHandler.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqExitHandler.java @@ -12,6 +12,10 @@ 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 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 bit 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); + } + } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqRaiseHandler.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqRaiseHandler.java index 6773c6491f..3e955d8b9e 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqRaiseHandler.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/kernel/handlers/SoftIrqRaiseHandler.java @@ -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); } } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java index 0aad6c0b4e..88994cd2e4 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/analysis/os/linux/ui/views/resources/ResourcesPresentationProvider.java @@ -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; 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 72b125af38..eac94cd000 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 @@ -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(),