# Learn Real-time (RT) kernel

A real-time system is a deterministic system, where response to an event
is expected in a set time.

A system is classified as compatible with RT if:

- It’s devoid of unbounded latency.
- The maximum response time is calculated with precision.
- It meets the set criteria for scheduling of tasks (latency and
deadline).

Linux can be configured as a real-time operating system (RTOS) in which
real-time tasks have well-defined periodic execution cycles (cycle
time) and meet execution criteria within specified limits (jitter).

To install the patches, see [Versions of PREEMPT_RT
patches](https://wiki.linuxfoundation.org/realtime/start).

Note

The real-time support is for kernel space process and not for user space.

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

<!-- Generated by Microsoft Visio, SVG Export RT-kernel-build-sequence.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="11.0625in" height="1.68056in" viewbox="0 0 796.5 121" xml:space="preserve" color-interpolation-filters="sRGB" class="st8" aria-label="Representation of RT kernel build sequence."><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvSubprocessMaster" v:prompt="" v:val="VT4(Rectangle)"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: #fafafa; stroke: #d2d7e1; stroke-width: 1.5 }
.svg-1 .st2 { marker-end: url("#1-mrkr4-8"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
.svg-1 .st3 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.37313432835821 }
.svg-1 .st4 { fill: #6280cc; stroke: #6280cc; stroke-opacity: 0; stroke-width: 2.5 }
.svg-1 .st5 { fill: none; stroke: none; stroke-width: 2.5 }
.svg-1 .st6 { fill: #ffffff; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-1 .st7 { font-size: 1em }
.svg-1 .st8 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend4">		<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"></path>	</g>	<marker id="1-mrkr4-8" class="st3" v:arrowtype="4" v:arrowsize="2" v:setback="5.36" refx="-5.36" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-2.68,-2.68) "></use>	</marker></defs><g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<v:userdefs>		<v:ud v:nameu="msvThemeOrder" v:val="VT0(0):26"></v:ud>	</v:userdefs>	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="0" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1057-1" v:mid="1057" v:groupcontext="shape" transform="translate(19.5,-19.5)">		<title>Rectangle</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="39" width="757.5" height="82" rx="4" ry="4" class="st1"></rect>	</g>	<g id="shape1047-3" v:mid="1047" v:groupcontext="shape" transform="translate(177.472,-60.891) rotate(-0.00602379)">		<title>Sheet.1047</title>		<path d="M0 121 L39.2 121" class="st2"></path>	</g>	<g id="shape1045-9" v:mid="1045" v:groupcontext="shape" transform="translate(29.4085,-29.9018) rotate(0.3)">		<title>Rectangle.12</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="59.014" width="151.263" height="61.986" rx="3" ry="3" class="st4"></rect>	</g>	<g id="shape1046-11" v:mid="1046" v:groupcontext="shape" transform="translate(63.7851,-41.4924)">		<title>Sheet.1046</title>		<desc>Set up workspace</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="40.7827" cy="101.992" width="81.57" height="38.0152"></v:textrect>		<rect x="0" y="82.9848" width="81.5655" height="38.0152" class="st5"></rect>		<text x="21.12" y="97.79" class="st6" v:langid="1033"><v:paragraph v:horizalign="1" v:bulletsize="0.166667"></v:paragraph><v:tablist></v:tablist>Set up<v:newlinechar></v:newlinechar><tspan x="5.16" dy="1.2em" class="st7"> </tspan>workspace</text>		</g>	<g id="shape1037-15" v:mid="1037" v:groupcontext="shape" transform="translate(225.2,-30.2467) rotate(0.3)">		<title>Rectangle.1004</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="59.7039" width="151.263" height="61.2961" rx="3" ry="3" class="st4"></rect>	</g>	<g id="shape1042-17" v:mid="1042" v:groupcontext="shape" transform="translate(260.052,-42.9924)">		<title>Sheet.1042</title>		<desc>Enable RT kernel</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="40.3056" cy="103.492" width="80.62" height="35.0152"></v:textrect>		<rect x="0" y="85.9848" width="80.6111" height="35.0152" class="st5"></rect>		<text x="9.1" y="99.29" class="st6" v:langid="1033"><v:paragraph v:horizalign="1" v:bulletsize="0.166667"></v:paragraph><v:tablist></v:tablist>Enable RT <v:newlinechar></v:newlinechar><tspan x="21.41" dy="1.2em" class="st7">kernel</tspan></text>		</g>	<g id="shape1038-21" v:mid="1038" v:groupcontext="shape" transform="translate(420.988,-30.2467) rotate(0.3)">		<title>Rectangle.1005</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="59.7039" width="151.263" height="61.2961" rx="3" ry="3" class="st4"></rect>	</g>	<g id="shape1041-23" v:mid="1041" v:groupcontext="shape" transform="translate(460.289,-42.5745)">		<title>Sheet.1041</title>		<desc>Configure RT kernel</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="35.8567" cy="103.075" width="71.72" height="35.851"></v:textrect>		<rect x="0" y="85.149" width="71.7135" height="35.851" class="st5"></rect>		<text x="5.45" y="98.87" class="st6" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Configure<v:newlinechar></v:newlinechar><tspan x="6.74" dy="1.2em" class="st7">RT kernel</tspan></text>		</g>	<g id="shape1039-27" v:mid="1039" v:groupcontext="shape" transform="translate(616.776,-30.2467) rotate(0.3)">		<title>Rectangle.1006</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="59.7039" width="151.263" height="61.2961" rx="3" ry="3" class="st4"></rect>	</g>	<g id="shape1040-29" v:mid="1040" v:groupcontext="shape" transform="translate(643.537,-40.1277)">		<title>Sheet.1040</title>		<desc>Verify kernel configurations</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="49.2313" cy="100.628" width="98.47" height="40.7446"></v:textrect>		<rect x="0" y="80.2554" width="98.4627" height="40.7446" class="st5"></rect>		<text x="10.63" y="96.43" class="st6" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Verify kernel <tspan x="4.17" dy="1.2em" class="st7">configurations</tspan></text>		</g>	<g id="shape1053-33" v:mid="1053" v:groupcontext="shape" transform="translate(373.836,-60.0849) rotate(-1.01902)">		<title>Sheet.1053</title>		<path d="M0 121 L36.49 121" class="st2"></path>	</g>	<g id="shape1055-38" v:mid="1055" v:groupcontext="shape" transform="translate(569.625,-60.0849) rotate(-1.01902)">		<title>Sheet.1055</title>		<path d="M0 121 L36.49 121" class="st2"></path>	</g></g>
</svg>

**Figure : Build sequence**

## Set up workspace

The Qualcomm Linux kernel supports the LTS RT kernel (6.18.x), which is maintained
through the Yocto recipe in the `meta-qcom` layer in the
`recipes-kernel/linux/linux-qcom-rt_6.18.bb` file.

The Linux RT kernel recipe in Qualcomm Linux is referred as
`linux-qcom-rt_6.18.bb`.

For more information about cloning the workspace and getting all Qualcomm Linux meta layers to
use Qualcomm RT Linux, see [Sync and build with real-time Linux](https://docs.qualcomm.com/bundle/publicresource/topics/80-80020-254/how_to.html#sync-and-build-with-real-time-linux).

## Enable RT kernel

The Qualcomm Linux `meta-qcom` layer supports `linux-qcom-rt_6.18.bb` recipe that fetches and builds the Qualcomm Linux kernel for the supported machines by default.

The `meta-qcom` layer applies the changes on top of the
existing layer. During the kernel build, `meta-qcom` layer
enables  `PREEMPT_RT` using `rt.config` based on the kernel version,
and allows real-time configurations.

Note

- Use `linux-qcom-rt_6.18.bb <https://github.com/qualcomm-linux/meta-qcom/blob/master/recipes-kernel/linux/linux-qcom-rt_6.18.bb>` for QLI.2.0 .
- Use `linux-qcom-next-rt_git.bb <https://github.com/qualcomm-linux/meta-qcom/blob/master/recipes-kernel/linux/linux-qcom-next-rt_git.bb>` for `qcom-next`.

For more information about supported machines, see [Identify supported Qualcomm machines](https://docs.qualcomm.com/doc/80-80020-3/topic/getting_started_chapter2.html#supported-machines).

## Configure RT kernel

- To configure the RT kernel, use the following procedure:

SRC_URI += " \
              file://0001-arch-Kconfig-Add-RT-kernel-support.patch \
      "
    Copy to clipboard

- To apply the external configurations on the RT kernel:

    - Maintain the configuration file in the
`recipes-kernel/linux/linux-qcom-6.18/configs/<your_config>.cfg` recipe.
    - Append the configuration file to `SRC_URI` in the `recipes-kernel/linux/linux-qcom-rt_6.18.bb` file.
- To add a configuration fragment to the RT kernel, make the following change:

SRC_URI += " \
                file://configs/qcom_rt.cfg \
        "
        Copy to clipboard
- To modify the kernel command-line, add the command-line parameters into the `meta-qcom/ci/base.yml` file to `KERNEL_CMDLINE_EXTRA` variable.
- The following example shows how to modify a command-line:

KERNEL_CMDLINE_EXTRA:append = " qcom_scm.download_mode=1 <new_parameter>"
        Copy to clipboard

## Kernel configuration for RT kernel

Optional and mandatory kernel configurations are used in the RT kernel.

To enable full preemption in the RT kernel, use `CONFIG_PREEMPT_RT`.

The `CONFIG_PREEMPT_RT` flag is enabled by default as part of the
`linux-qcom-rt_6.18.bb` recipe in `rt.config`.

The following example shows the kernel configuration:

CONFIG_PREEMPT_RT
    zcat proc/config.gz | grep CONFIG_PREEMPT
    CONFIG_PREEMPT_NONE is not set
    CONFIG_PREEMPT_VOLUNTARY is not set
    CONFIG_PREEMPT is not set
    CONFIG_PREEMPT_RT=y
    Copy to clipboard

To optimize the RT kernel response, use the following configurations:

CONFIG_NO_HZ
    zcat proc/config.gz | grep NO_HZ
    CONFIG_NO_HZ_COMMON=y
    CONFIG_NO_HZ_IDLE is not set
    CONFIG_NO_HZ_FULL=y
    CONFIG_NO_HZ is not set
    
    CONFIG_CPUSETS
    zcat proc/config.gz | grep CPUSETS
    CONFIG_CPUSETS=y
    Copy to clipboard

Set the following kernel configuration options when affining the RT
task:

- `CONFIG_NO_HZ_FULL` - When enabled, it configures the kernel to
avoid sending scheduling-clock interrupts to CPUs with a single
runnable task.
- `CONFIG_CPUSETS` - Use the `CONFIG_CPUSETS` configuration option
to enable `cpuset`, where the CPU is grouped to form a set.

When affining the RT task to a set of CPUs, use the `CONFIG_CPUSETS` configuration option:

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

<!-- Generated by Microsoft Visio, SVG Export compile-RT-kernel.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="11.0278in" height="2.04638in" viewbox="0 0 794 147.339" xml:space="preserve" color-interpolation-filters="sRGB" class="st7" aria-label="Representation of RT kernel verification."><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvSubprocessMaster" v:prompt="" v:val="VT4(Rectangle)"></v:ud>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-2 .st1 { fill: #fafafa; stroke: #d2d7e1; stroke-width: 1.5 }
.svg-2 .st2 { fill: #6280cc; stroke: #6280cc; stroke-width: 0.75 }
.svg-2 .st3 { fill: none; stroke: none; stroke-width: 2.5 }
.svg-2 .st4 { fill: #ffffff; font-family: Roboto Flex, Qualcomm-Next, sans-serif; font-size: 1.16666em }
.svg-2 .st5 { marker-end: url("#2-mrkr4-23"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.75 }
.svg-2 .st6 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.40983606557377 }
.svg-2 .st7 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend4">		<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"></path>	</g>	<marker id="2-mrkr4-23" class="st6" v:arrowtype="4" v:arrowsize="2" v:setback="4.88" refx="-4.88" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-2.44,-2.44) "></use>	</marker></defs><g v:mid="0" v:index="1" v:groupcontext="foregroundPage">	<v:userdefs>		<v:ud v:nameu="msvThemeOrder" v:val="VT0(0):26"></v:ud>	</v:userdefs>	<title>Page-1</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="0" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1012-1" v:mid="1012" v:groupcontext="shape" transform="translate(19.5,-25.7966)">		<title>Rectangle.1012</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="47.1861" width="755" height="100.153" rx="4" ry="4" class="st1"></rect>	</g>	<g id="shape1003-3" v:mid="1003" v:groupcontext="shape" transform="translate(607.142,-39.1556) rotate(0.3)">		<title>Rectangle.1006</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="76.1386" width="152.753" height="71.2005" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1002-5" v:mid="1002" v:groupcontext="shape" transform="translate(416.204,-40.185) rotate(0.3)">		<title>Rectangle.1005</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="76.1386" width="152.753" height="71.2005" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1001-7" v:mid="1001" v:groupcontext="shape" transform="translate(225.265,-41.2143) rotate(0.3)">		<title>Rectangle.1004</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="76.1386" width="152.753" height="71.2005" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1004-9" v:mid="1004" v:groupcontext="shape" transform="translate(606.609,-29.48)">		<title>Sheet.1004</title>		<desc>Tune RT kernel</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="76.3765" cy="100.816" width="152.76" height="93.0467"></v:textrect>		<rect x="0" y="54.2924" width="152.753" height="93.0467" class="st3"></rect>		<text x="29.92" y="105.02" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Tune RT kernel</text>		</g>	<g id="shape1005-12" v:mid="1005" v:groupcontext="shape" transform="translate(421.974,-20.5)">		<title>Sheet.1005</title>		<desc>Debug RT kernel</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="70.0118" cy="94.1696" width="140.03" height="106.339"></v:textrect>		<rect x="0" y="41" width="140.024" height="106.339" class="st3"></rect>		<text x="19.15" y="98.37" class="st4" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Debug RT kernel</text>		</g>	<g id="shape1006-15" v:mid="1006" v:groupcontext="shape" transform="translate(224.719,-39.3528)">		<title>Sheet.1006</title>		<desc>Test RT kernel</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="76.3765" cy="109.954" width="152.76" height="74.7697"></v:textrect>		<rect x="0" y="72.5694" width="152.753" height="74.7697" class="st3"></rect>		<text x="31.75" y="114.15" class="st4" v:langid="1033"><v:paragraph v:horizalign="1" v:bulletsize="0.166667"></v:paragraph><v:tablist></v:tablist>Test RT kernel</text>		</g>	<g id="shape1007-18" v:mid="1007" v:groupcontext="shape" transform="translate(378.229,-74.2937) rotate(0.313268)">		<title>Sheet.1007</title>		<path d="M0 147.34 L29.65 147.34" class="st5"></path>	</g>	<g id="shape1008-24" v:mid="1008" v:groupcontext="shape" transform="translate(569.167,-73.2498) rotate(0.313268)">		<title>Sheet.1008</title>		<path d="M0 147.34 L29.65 147.34" class="st5"></path>	</g>	<g id="shape1009-29" v:mid="1009" v:groupcontext="shape" transform="translate(34.3126,-41.1898) rotate(0.3)">		<title>Rectangle.12</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="75.2824" width="152.753" height="72.0568" rx="2.88" ry="2.88" class="st2"></rect>	</g>	<g id="shape1010-31" v:mid="1010" v:groupcontext="shape" transform="translate(33.7706,-39.2787)">		<title>Sheet.1010</title>		<desc>Build RT kernel</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="76.3765" cy="109.954" width="152.76" height="74.7697"></v:textrect>		<rect x="0" y="72.5694" width="152.753" height="74.7697" class="st3"></rect>		<text x="29.97" y="114.15" class="st4" v:langid="1033"><v:paragraph v:horizalign="1" v:bulletsize="0.166667"></v:paragraph><v:tablist></v:tablist>Build RT kernel</text>		</g>	<g id="shape1011-34" v:mid="1011" v:groupcontext="shape" transform="translate(187.329,-72.9171) rotate(0.313268)">		<title>Sheet.1011</title>		<path d="M0 147.34 L29.65 147.34" class="st5"></path>	</g></g>
</svg>

**Figure: RT kernel verification**

## Build a RT kernel

To build the RT kernel, run the following commands:

1. To ensure that you are in the KAS shell, run the following command:

> 
> 
> kas shell meta-qcom/ci/qcs6490-rb3gen2-core-kit.yml:meta-qcom/ci/linux-qcom-rt_6.18.yml:meta-qcom/ci/qcom-distro.yml
>     Copy to clipboard

2. To compile the BitBake Qualcomm Linux multimedia image, run the following command:

> 
> 
> bitbake qcom-multimedia-image
>     Copy to clipboard

## Tune RT kernel

Tune the RT kernel to achieve a deterministic latency for RT tasks in the
device.

Set the CPU cores that run RT tasks to run at maximum operating
frequency while preventing thermal mitigation of CPU frequency. For
example, in an idle sleep scenario, RT tasks face scheduling latency due
to CPU wake time delay.

To configure the system before running the tests, do the following for QCS6490 and Qualcomm Dragonwing™ IQ-9075 Development Kit:

1. Disable the timer migration, using the following command:

echo 0 > /proc/sys/kernel/timer_migration
        Copy to clipboard
2. Affine all kernel work queues in `/sys/devices/virtual/workqueue/*` to the housekeeping CPUs, using the following command:

for wq in /sys/devices/virtual/workqueue/*; do
           [ -w "$wq/cpumask" ] && echo 7F > "$wq/cpumask"
        done
        7F = CPUs 0-6 (binary 0111 1111)
        Copy to clipboard
3. Set CPU frequency governor to performance, using the following command:

for policy in /sys/devices/system/cpu/cpufreq/policy*; do
           [ -w "$policy/scaling_governor" ] && echo performance > "$policy/scaling_governor"
        done
        Copy to clipboard
4. Disable RT accounting/throttling, using the following command:

echo -1 > /proc/sys/kernel/sched_rt_runtime_us
        Copy to clipboard
5. Set IRQ affinity to housekeeping CPUs, using the following command:

ALLOW_CPUS="0,1,2,3,4,5,6"
        cpu_list_to_mask() {
           MASK=0
           for cpu in $(echo $1 | tr ',' ' '); do
              MASK=$((MASK | (1 << cpu)))
           done
           printf "%x\n" "$MASK"
        }
        MASK=$(cpu_list_to_mask "$ALLOW_CPUS")
        echo "Setting IRQ affinity to CPUs: $ALLOW_CPUS (mask=0x$MASK)"
        for irq in /proc/irq/[0-9]*; do
           smp_file="$irq/smp_affinity"
           [ -w "$smp_file" ] && echo "$MASK" > "$smp_file" 2>/dev/null
        done
        Copy to clipboard

To configure the system before running the tests, do the following for the DragonwingTM IQ-8275 Development Kit:

1. Disable the timer migration, using the following command:

echo 0 > /proc/sys/kernel/timer_migration
        Copy to clipboard
2. Affine all kernel work queues in `/sys/devices/virtual/workqueue/*` to the housekeeping CPUs, using the following command:

for wq in /sys/devices/virtual/workqueue/*; do
           [ -w "$wq/cpumask" ] && echo F7 > "$wq/cpumask"
        done
        F7 = CPUs 0–2,4-7 (binary 1111 0111)
        Copy to clipboard
3. Set CPU frequency governor to performance, using the following command:

for policy in /sys/devices/system/cpu/cpufreq/policy*; do
           [ -w "$policy/scaling_governor" ] && echo performance > "$policy/scaling_governor"
        done
        Copy to clipboard
4. Disable RT accounting/throttling, using the following command:

echo -1 > /proc/sys/kernel/sched_rt_runtime_us
        Copy to clipboard
5. Set IRQ affinity to housekeeping CPUs, using the following command:

ALLOW_CPUS="0,1,2,4,5,6,7"
        cpu_list_to_mask() {
           MASK=0
           for cpu in $(echo $1 | tr ',' ' '); do
              MASK=$((MASK | (1 << cpu)))
           done
           printf "%x\n" "$MASK"
        }
        MASK=$(cpu_list_to_mask "$ALLOW_CPUS")
        echo "Setting IRQ affinity to CPUs: $ALLOW_CPUS (mask=0x$MASK)"
        for irq in /proc/irq/[0-9]*; do
           smp_file="$irq/smp_affinity"
           [ -w "$smp_file" ] && echo "$MASK" > "$smp_file" 2>/dev/null
        done
        Copy to clipboard

The following example shows how to add a kernel command-line parameter
to disable RCU callbacks (**rcu\_nocbs**) in `meta-qcom/conf/machine/<machine-name.conf>`:

- CPU cores 7
- IRQ affine to core 0-6
- RCU no call back 7

QCOM_RT_CPU        = "7"
    QCOM_IRQAFF        = "0-6"
    QCOM_RCU_NOCBS     = "7"
    QCOM_RCU_EXPEDITED = "1"
    QCOM_CPUIDLE_OFF   = "1"
    Copy to clipboard

## Test RT kernel

A suite of tests is available in the Linux foundation RT test suite.

The cyclic test determines the best- and worst-case latencies for an RT
application.

1. Access the RT test suite source code at [rt-tests/rt-tests.git](https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git/).
2. To include the RT test suites as a part of the image, change the `layer.conf` file in the standard Yocto build:

IMAGE_INSTALL:append = "rt-tests numactl"
        Copy to clipboard
3. Run the following cyclic test for QCS6490 and Qualcomm Dragonwing™ IQ-9075 Development Kit:

cyclictest -a 7 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100
        -a 7 → pin threads to CPU 7 (RT cores)
        -t 1 → 1 threads
        -m → lock memory (avoid page faults)
        -l 100000000 → long run
        -i 1000 → 1 ms interval
        -p 99 → RT priority
        -h 100 → histogram up to 100 µs
        Copy to clipboard

    - Run the following cyclic test for the DragonwingTM IQ-8275 Development Kit:

cyclictest -a 3 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100
            Copy to clipboard

For more information, see [RT-Tests](https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/rt-tests).

Last Published: Mar 04, 2026

[Previous Topic
Configure the pinctrl driver](https://docs.qualcomm.com/bundle/publicresource/80-80020-3/topics/pinctrl-configuration.md) [Next Topic
Enable virtualization](https://docs.qualcomm.com/bundle/publicresource/80-80020-3/topics/virtualization.md)