# Features impacting performance The Qualcomm^®^ Linux^®^ kernel includes features such as the CPU scheduler, CPU frequency governor, dynamic voltage and frequency scaling (DVFS), and memory management. This guide provides an overview of each feature and related reference links. Additionally, Qualcomm has added a feature called PerfHAL to enhance the performance of Qualcomm Linux. ## CPU scheduler The CPU scheduler manages how the CPU time is distributed among the processes running on Linux systems. It uses the earliest eligible virtual deadline first (EEVDF) scheduler, a feature provided by the Linux kernel. The EEVDF CPU scheduler uses per entity load tracking (PELT) to monitor the task load. For more information, see: - [An EEVDF CPU scheduler for Linux](https://lwn.net/Articles/925371/) - [Per-entity load tracking \[LWN.net\]](https://lwn.net/Articles/531853/) Utilization clamping (UCLAMP or util clamp) is a scheduler feature that helps manage performance requirements for tasks. For more information, see: - [Utilization Clamping](https://docs.kernel.org/scheduler/sched-util-clamp.html) - [Customize CPU scheduler](https://docs.qualcomm.com/doc/80-70022-10/topic/18-customize.html#customize-scheduler) ## CPU frequency governor A CPU frequency governor adjusts the CPU frequency based on the task load. The CPU scheduler provides the necessary inputs for this process. Qualcomm Linux uses the `schedutil` governor, a feature provided by the Linux kernel. This governor increases the frequency when the system is heavily loaded and reduces it when the load is low, ensuring an optimal balance between power consumption and performance. For more information, see: - [CPU frequency and voltage scaling code in the Linux kernel](https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt) - [Configure CPU](https://docs.qualcomm.com/doc/80-70022-10/topic/14-configure.html#cpu) - [Customize the CPU frequency governor](https://docs.qualcomm.com/doc/80-70022-10/topic/18-customize.html#cpu-frequency-governer) ## DVFS governors DVFS governors control the frequencies of CPU caches (L3), the last level cache controller (LLCC), and the DDR based on the system workload. These governors increase the frequency when the workload is high and decrease it when the workload is low, ensuring an optimal balance between power consumption and performance. Qualcomm Linux supports the following two types of DVFS governors for L3 cache: - LLCC - DDR ### Static map DVFS governor This governor aligns the frequencies of the CPU L3 cache and the DDR with the current CPU frequency to balance the power and the performance requirements. For example, if the CPU frequency is at its maximum, the L3 cache and DDR frequencies must also be at their maximum levels. The static mapping is available in the source code at `arch/arm64/boot/dts/qcom/.dtsi`. For customization options, see [Customize static map DVFS governor](https://docs.qualcomm.com/doc/80-70022-10/topic/18-customize.html#section-u1x-jps-51c-caharris-03-20-24-2005-37-832). ### BWMON governor The bandwidth monitoring (BWMON) governor dynamically adjusts the frequencies of the LLCC and DDR based on the measured traffic flow from the CPU to the LLCC and then to the DDR. The BWMON hardware block measures this traffic. It monitors the data throughput between memory and the other subsystems within a specified sampling window and uses this information to scale the LLCC and DDR frequencies to meet the required bandwidth. The BWMON governor driver is available in the source code at `drivers/soc/qcom/icc-bwmon.c`. For more information, see: - [\[PATCH v3 0/4\] soc/arm64: qcom: Add initial version of bwmon](https://lwn.net/ml/linux-kernel/20220531105137.110050-1-krzysztof.kozlowski@linaro.org/) - [Customize BWMON governor](https://docs.qualcomm.com/doc/80-70022-10/topic/18-customize.html#section-qxs-4ps-51c-caharris-03-20-24-2007-2-926) ## PerfHAL PerfHAL is a Qualcomm proprietary service that offers added functionality by making perflock APIs accessible. It's beneficial when you need short-term performance enhancements or power savings. Perflocks help in modifying system behavior to manage intermittent workloads. For example, if a specific code segment must run at a higher CPU frequency for a certain duration, use perflocks within that code to boost the CPU frequency. PerfHAL efficiently handles concurrent perflock requests from multiple clients. When several requests are aimed at the same resource, PerfHAL aggregates them to achieve the optimal performance level needed by the device. When a perflock of a client is no longer active, PerfHAL releases all the perflocks associated with that client. ### Perflock APIs Perflock APIs allow applications to adjust system parameters for specific use cases, helping them meet their performance and power objectives. User space applications use the `perf_lock_acq()` and `perf_lock_rel()` APIs to request specific values of system tunable parameters for both, a set time period or an indefinite time period. ### Acquire perflock Use `perf_lock_acq()` function to acquire a perflock with the necessary optimizations. The syntax for this function is as follows: `int perf_lock_acq(int handle, int duration, int list[], int numArgs)` Table : perf_lock_acq API parameters | Parameter | Description | | --- | --- | | `handle` | Identifies the client request. | | `duration` | | | `list` | An array of resource opcodes and value pairs. Opcodes
indicate a system parameter (resource) and the value to set
it (level). | | `numArgs` | Number of elements in the list array. | Table : perf_lock_acq API returns and result | Returns | Result | | --- | --- | | A non-zero integer | Success | | -1 | Failure | ### Perflock release The `perf_lock_rel()` function is used to release a perflock that's held by the `perf_lock_acq()` API. Use this function only for the perflocks that are set for an indefinite time period. The syntax for this function is as follows: `int perf_lock_rel(int handle)` Table : perf_lock_rel API parameters | Parameter | Description | | --- | --- | | `handle` | | Table : perf_lock_rel API returns and result | Returns | Result | | --- | --- | | A non-zero integer | Success | | -1 | Failure | ### Resource opcodes Perflock uses a combination of opcodes and their corresponding values to perform specific operations on a perflock resource. To know the supported opcodes on Qualcomm Dragonwing^™^ IQ-9075, Qualcomm Dragonwing^™^ IQ-8275, and Qualcomm Dragonwing^™^ IQ-615, see the corresponding addendum. The following guides are available to licensed users with authorized access: - [Qualcomm Linux Performance Guide - Addendum for Qualcomm Dragonwing IQ-9075](https://docs.qualcomm.com/bundle/resource/topics/80-70022-10A/overview.html) - [Qualcomm Linux Performance Guide - Addendum for Qualcomm Dragonwing IQ-8275](https://docs.qualcomm.com/bundle/resource/topics/80-70022-10B/overview.html) - [Qualcomm Linux Performance Guide - Addendum for Qualcomm Dragonwing IQ-615](https://docs.qualcomm.com/bundle/resource/topics/80-70022-10C/overview.html) The following table lists the supported opcodes: Table : Supported opcodes | Opcode | Purpose | Sysnode on device | | --- | --- | --- | | 0x44000000 | Sets the minimum acceptable performance level for individual
tasks and task groups. | `/proc/sys/kernel/sched_util_clamp_min` | | 0x44004000 | Sets the maximum acceptable performance level for individual
tasks and task groups. | `/proc/sys/kernel/sched_util_clamp_max` | | 0x44008100 | Sets the minimum frequency of the Silver cluster. | `/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq` | | 0x44008000 | Sets the minimum frequency of the Gold cluster. | `/sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq` | | 0x44008200 | Sets the minimum frequency of the Prime cluster. | `/sys/devices/system/cpu/cpufreq/policy7/scaling_min_freq` | | 0x4400C100 | Sets the maximum frequency of the Silver cluster. | `/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq` | | 0x4400C000 | Sets the maximum frequency of the Gold cluster. | `/sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq` | | 0x4400C200 | Sets the maximum frequency of the Prime cluster. | `/sys/devices/system/cpu/cpufreq/policy7/scaling_max_freq` | The following are some examples of the resource opcodes: - 0x44008100, 1958400: This pair of opcode and value indicates that the minimum frequency of the Silver cluster must be set to 1958400 KHz. - 0x44008100, 1958400, 0x4400C100, 2100000: This pair of opcode and value indicates that the minimum frequency of the Silver cluster must be set to 1958400 KHz. The maximum frequency of the Silver cluster must be set to 2100000 KHz. For more information about how to use and debug perflock, see [Customize perflock](https://docs.qualcomm.com/doc/80-70022-10/topic/18-customize.html#customize-perlocks). ## Memory RAM is used for all memory allocations made by Qualcomm Linux. RAM must be managed to meet performance requirements and ensure the smooth functioning of applications. The following figure shows memory partitioning: RAM Memory total (system RAM) Kernelstatic Kerneldynamic Freememory User spaceprocess Reserved Linux Non-Linux **Figure : Memory partitioning** The figure shows RAM allocation in systems supporting both Linux and non-Linux environments. - System RAM is partitioned between non-Linux and Linux components. - Non-Linux section includes a large block labeled Reserved, indicating memory allocated for non-Linux operations. - Linux section is divided into four blocks under Memory total (system RAM): - Kernel static - Kernel dynamic - User space process - Free memory Certain sections of RAM are managed independent of the Linux system. For example, firmware such as modem, video, and audio run from these specific RAM partitions. The Linux kernel manages all other RAM partitions. The Linux kernel features its own memory management subsystem, which includes: - Implementation of virtual memory and demand paging - Allocation of memory to both kernel internal structures and user space programs - Mapping of files into the address space of the processes - Other memory management operations ### RAM memory partitioning The following table describes various types of memory allocations. Note The commands specified in the following table should be run on the device. | RAM classification | Memory segment | Allocation types | Description | | --- | --- | --- | --- | | Non-Linux | – | – | | | Linux (system RAM) | Kernel static | Vmlinux + kernel page structures | | | Linux (system RAM) | Kernel dynamic | Slab |

cat /proc/meminfo | grep -i slab
Copy to clipboard


cat /proc/slabinfo
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | Kernel stack |

cat /proc/meminfo | grep -i kernelstack
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | PageTables |

cat /proc/meminfo | grep -i PageTables
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | Modules |

cat /proc/modules
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | Vmalloc |

cat /proc/vmallocinfo
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | Cached (kernel + user space) |

cat /proc/meminfo | grep -i cached
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | Buffers |

cat /proc/meminfo | grep -i Buffers
Copy to clipboard | | Linux (system RAM) | Kernel dynamic | Shmem |

cat /proc/meminfo | grep -i shmem
Copy to clipboard | | Linux (system RAM) | User space | ZUSED (ZRAM) | An anonymous memory post compression by ZRAM. | | Linux (system RAM) | User space | CMA | | | Linux (system RAM) | User space | ANON |


>
>
> cat /proc//smaps
> Copy to clipboard | | Linux (system RAM) | User space | ION |

mount -t debugfs none /sys/kernel/debug
Copy to clipboard


cat /sys/kernel/debug/dma_buf/bufinfo | grep bytes
Copy to clipboard | | Linux (system RAM) | User space | KGSL |


>
>
> cat /sys/class/kgsl/kgsl/page_alloc
> Copy to clipboard




>
>
> cat /sys/class/kgsl/kgsl/proc//kernel
> Copy to clipboard | | Linux (system RAM) | Free memory | – |

  • Free memory is the memory that's not yet used and is
    available for any allocation.


  • To check the available memory, run the following command:


    cat /proc/meminfo | grep -i MemFree
    Copy to clipboard



| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ## Real-time kernel Real-time (RT) Linux is an optional feature that's not enabled by default on Qualcomm Linux. It can be enabled based on the product requirements. RT Linux is designed to offer deterministic and predictable behavior for applications that are time‑sensitive. ### Set up workspace In Qualcomm Linux, the RT Linux kernel recipes are referred to as follows: - Base BSP: `linux-qcom-base-rt` - Custom BSP: `linux-qcom-custom-rt` The Qualcomm Linux kernel supports long-term support (LTS) RT kernel 6.6 version, which is maintained through the Yocto recipe in the `meta-qcom-realtime` layer at the following paths in the source code: - Base BSP: `recipes-kernel/linux/linux-kernel-base-rt_6.6.bb` - Custom BSP: `recipes-kernel/linux/linux-kernel-custom-rt_6.6.bb` For more information about how to clone the workspace and acquire all the meta layers to use Qualcomm RT Linux kernel, see [Sync and build with real-time Linux](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-254/how_to.html#sync-and-build-with-real-time-linux). ### Enable RT kernel Use the RT Linux kernel recipe to enable the RT kernel. This recipe fetches the kernel, downloads pre-empt RT patches, and applies them to the kernel. It also allows a fully pre-emptible kernel with: `CONFIG_PREEMPT_RT=y` For more information, see [Real-time (RT) kernel overview](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-3/real_time_kernel_overview.html). ### Verify kernel type After booting, verify the kernel type by running the following command on the device: uname -v Copy to clipboard The following is an output of the command: SMP PREMPT\_RT ### Test RT Linux kernel The RT Linux kernel test obtains the following information: - Real-time performance of the RT Linux kernel - RT Linux kernel latencies and key performance indicators (KPIs) Note This section is only applicable for QCS6490. Caution Don't reboot the system during the RT Linux kernel test as it runs for over 24 hours. ### Cyclictest Cyclictest tool is used for benchmarking the RT Linux kernel systems. It's used to evaluate the relative performance of the real-time systems. The Qualcomm Linux build has the cyclictest tool. For more information, see [Cyclictest](https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest/start). This guide describes the following cyclictests: - Cyclictest with no-load: System load isn't added to perform this test. - Cyclictest with stress-ng (next-generation): Specific percentage of load is added to perform this test to measure the worst case system latencies. For more information about stress-ng, see [Ubuntu Wiki - stress-ng](https://wiki.ubuntu.com/Kernel/Reference/stress-ng/). #### Prerequisites for cyclictest > > > Ensure to complete the following prerequisites before you run a cyclictest: 1. Configure and isolate the CPU core 1 to core 3 for the RT tasks. You may configure any other CPU cores depending on your requirement. For example, you can configure the RT CPUs in the source code at the following path: `layers/meta-qcom-realtime/blob/scarthgap/conf/layer.conf` For example, configure the CPU as follows: KERNEL_CMDLINE_EXTRA:qcm6490 = "pcie_pme=nomsi net.ifnames=0 pci=noaer kpti=off kasan=off kasan.stacktrace=off swiotlb=128 mitigations=auto kernel.sched_pelt_multiplier=4 rcupdate.rcu_expedited=1 rcu_nocbs=1-3 isolcpus=1-3 irqaffinity=4-7 nohz_full=1-3 no-steal-acc vfio_iommu_type1.allow_unsafe_interrupts=1" Copy to clipboard 2. Run the following commands on the RT Linux kernel: > > > echo 0 > /sys/kernel/tracing/tracing_on > Copy to clipboard > > > echo E0 > /sys/devices/virtual/workqueue/kgsl-workqueue/cpumask > Copy to clipboard > > > echo E0 > /sys/devices/virtual/workqueue/scsi_tmf_0/cpumask > Copy to clipboard > > > echo E0 > /sys/devices/virtual/workqueue/writeback/cpumask > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu1/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu1/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu1/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu3/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu3/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu3/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu4/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu4/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu4/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu5/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu5/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu5/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu6/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu6/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu6/cpuidle/state2/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu7/cpuidle/state0/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu7/cpuidle/state1/disable > Copy to clipboard > > > echo 1 > /sys/devices/system/cpu/cpu7/cpuidle/state2/disable > Copy to clipboard > > > echo performance > /sys/devices/system/cpu/cpufreq/policy7/scaling_governor > Copy to clipboard > > > echo performance > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor > Copy to clipboard > > > echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor > Copy to clipboard > > > echo +cpuset > /sys/fs/cgroup/cgroup.subtree_control > Copy to clipboard > > > mkdir /sys/fs/cgroup/cpuset > Copy to clipboard > > > echo +cpuset > /sys/fs/cgroup/cpuset/cgroup.subtree_control > Copy to clipboard > > > - Cyclictest with no-load > - To run a cyclictest with no-load, follow these steps: > > 1. Complete the [prerequisites](https://docs.qualcomm.com/doc/80-70022-10/topic/2-performance-features.html#prerequisites-for-cyclictest). > 2. Run the following commands to start cyclictest: > > > > > > > > mkdir /sys/fs/cgroup/cpuset/core1-3/ > > Copy to clipboard > > > > echo +cpuset > /sys/fs/cgroup/cpuset/core1-3/cgroup.subtree_control > Copy to clipboard > > > echo 1-3 > /sys/fs/cgroup/cpuset/core1-3/cpuset.cpus > Copy to clipboard > > > echo $$ > /sys/fs/cgroup/cpuset/core1-3/cgroup.procs > Copy to clipboard > > > cyclictest -a 1-3 -t 3 -m -l 100000000 -i 1000 -p 90 -h 800 --mainaffinity 4 --spike 100 > Copy to clipboard > 3. Note the latencies. > > - Cyclictest with stress-ng > - To run a cyclictest with stress-ng, follow these steps: > > > > 1. Complete the [prerequisites](https://docs.qualcomm.com/doc/80-70022-10/topic/2-performance-features.html#prerequisites-for-cyclictest). > 2. Open a shell and run the following commands to run stress-ng. In the second example command, the non-RT CPU is loaded with 60% load: > > > > > > > > > mkdir /tmp/temp-path > > Copy to clipboard > > > > > > > > > stress-ng --cpu 5 --cpu-load 60 --temp-path /tmp/temp-path --sched fifo --sched-prio 1 -t 2d > > Copy to clipboard > > > > This procedure completes in approximately 48 hours. In this example, CPU 1, 4, and 7 are loaded. > 3. Run the cyclictest and stress-ng simultaneously. Run the following commands to start cyclictest in another terminal: > > > > > > > > > mkdir /sys/fs/cgroup/cpuset/core1-3/ > > Copy to clipboard > > > > > > > > > echo +cpuset > /sys/fs/cgroup/cpuset/core1-3/cgroup.subtree_control > > Copy to clipboard > > > > echo 1-3 > /sys/fs/cgroup/cpuset/core1-3/cpuset.cpus > Copy to clipboard > > > echo $$ > /sys/fs/cgroup/cpuset/core1-3/cgroup.procs > Copy to clipboard > > > cyclictest -a 1-3 -t 3 -m -l 100000000 -i 1000 -p 90 -h 800 --mainaffinity 4 --spike 100 > Copy to clipboard > 4. Press Ctrl + C to stop stress-ng. > 5. Note the worst-case latencies. ### RT Linux kernel KPIs The following tables describe the cyclictests KPIs: KPIs for cyclictest with no-load | RT thread | Priority | Minimum latencies (in microseconds) | Maximum latencies (in microseconds) | | --- | --- | --- | --- | | T0 | 90 | 9 | 72 | | T1 | 90 | 9 | 62 | | T2 | 90 | 9 | 63 | KPIs for cyclictest with stress-ng | RT thread | Priority | Minimum latencies (in microseconds) | Maximum latencies (in microseconds) | | --- | --- | --- | --- | | T0 | 90 | 9 | 71 | | T1 | 90 | 9 | 73 | | T2 | 90 | 9 | 73 | ## Next steps - [Customize for performance tuning](https://docs.qualcomm.com/doc/80-70022-10/topic/18-customize.html#customize) - [Performance analysis tools](https://docs.qualcomm.com/doc/80-70022-10/topic/13-performance_tools.html#performance-tools) Last Published: Oct 10, 2025 [Previous Topic Get started with performance tuning and optimization](https://docs.qualcomm.com/bundle/publicresource/80-70022-10/topics/get-started.md) [Next Topic Performance analysis tools](https://docs.qualcomm.com/bundle/publicresource/80-70022-10/topics/13-performance_tools.md) Source: [https://docs.qualcomm.com/doc/80-70022-10/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70022-10/topic/2-performance-features.html)