├── CONTRIBUTING.md ├── LICENSE ├── PKGBUILD ├── README.md ├── ktweak └── ktweak.service /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | KTweak is open to external collaboration, suggestions, and ideas. In order to effectively contribute to the project, ensure you follow the guidelines below before suggesting a change. 3 | 4 | # Pull Requests 5 | * Ensure your proposed changes abide by the Code of Conduct 6 | * Provide substantial logic or evidence that your change is beneficial 7 | * Match the code style of the current project in your commits 8 | 9 | # Code of Conduct 10 | ## Standards 11 | All suggested changes must abide by the following regulations. 12 | 13 | * No proprietary specific tweaks. KTweak is designed to be a universal module. Please do not include OEM and custom kernel specific tunings in your suggestions. 14 | * All changes must be well-documented in the README.md. If you make a change to the `ktweak` script, update the README.md documentation accordingly to keep end-users aware of the changes. 15 | * All changes must be backed by logic or evidence. It is best to include benchmarks in your results, however this cannot always be expected (margin of error, unpredictable events, etc). Just ensure to read up on the documentation of the tunable and make sure your change makes sense. Other contributors can critique your tweak choice to fact-check it, as well. 16 | 17 | ## Contributor Responsibilities 18 | Project maintainers should strive to keep KTweak genuine and free of the common mistakes made by other device tweaking modules (see the README.md). This includes regularly scanning recent issues and pull requests for both beneficial and detrimental changes and fact checking them. 19 | 20 | Maintainers may also approve or reject pull requests, close and review issues, and perform other miscellaneous regulations that are deemed necessary. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2022, Tyler Nijmeh 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: 2 | 3 | pkgname=ktweak-git 4 | pkgver=1.0.ac279a9 5 | pkgrel=1 6 | pkgdesc="KTweak - A no-nonsense kernel tweak script for Linux and Android systems, backed by evidence" 7 | arch=('any') 8 | url="https://github.com/tytydraco/KTweak.git" 9 | license=('GPL3') 10 | depends=() 11 | makedepends=('git') 12 | source=("$pkgname"::'git+https://github.com/tytydraco/ktweak') 13 | md5sums=('SKIP') 14 | provides=(ktweak) 15 | 16 | pkgver() { 17 | cd "$pkgname" 18 | echo "1.0.`git rev-parse --short HEAD`" 19 | } 20 | 21 | package() { 22 | cd "$srcdir/${pkgname}/" 23 | chmod +x ktweak 24 | mkdir -p "$pkgdir/usr/bin/" 25 | mkdir -p "$pkgdir/etc/systemd/system/" 26 | install -Dm744 ktweak "$pkgdir/usr/bin/ktweak" 27 | install -Dm644 ktweak.service "$pkgdir/etc/systemd/system/ktweak.service" 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KTweak 2 | A no-nonsense kernel tweak script for Linux and Android systems, backed by evidence. 3 | 4 | # Another "kernel optimizer"? 5 | No. Well, yes. However, a "kernel optimizer" is a poor way to put it. KTweak performs kernel adjustments based on facts and evidence, unlike other optimizers with poorly written or heavily obfuscated code. 6 | 7 | * [NFS Injector](https://github.com/Magisk-Modules-Grave/nfsinjector) uses closed source, compiled binaries with various typos in the README. It also provides a "pro" version that costs money. 8 | * [MAGNETAR](https://github.com/Magisk-Modules-Grave/MAGNETAR) also uses closed source, compiled binaries. I'd love to say more about this, but I can't even find out what the module even does. 9 | * [FDE.AI](https://forum.xda-developers.com/apps/magisk/beta-feradroid-engine-v0-19-ultimate-t3284421) also uses closed source, compiled binaries with a paid variant. 10 | * [LKT](https://github.com/Magisk-Modules-Grave/legendary_kernel_tweaks/blob/master/common/system.prop) sets random nonsensical build.props that don't even exist. 11 | * [ZeetaTweaks](https://t.me/zeetaaprojbot) is a clone of KTweak with the values changed. As of the V11 zip, it disables essential system services, deletes files permanently from /data/data, kills perfd (which is the userspace boosting daemon), disables SELinux, disables fsync, and various other detrimental changes. 12 | 13 | # What's different about KTweak? 14 | Unlike other "kernel optimizers", KTweak is: 15 | 16 | * Entirely open source with no compiled components 17 | * Concise, at less than 200 lines long 18 | * Backed by benchmarks and evidence 19 | * Designed by an experienced kernel developer 20 | * Non-intrusive and completely systemless 21 | 22 | # Benchmarks 23 | The following benchmarks were performed on a OnePlus 7 Pro running the stock kernel provided by the OEM on Android 10. **KTweak sacrifices throughput for latency**, since latency correlates to UI / UX smoothness. This explains the slight regression with the scheduler throughput. 24 | 25 | 26 | ### Scheduler latency via `schbench` (lower is better) 27 | - Stock: 28 | `50.0th: 4052 29 | 75.0th: 14288 30 | 90.0th: 26848 31 | 95.0th: 32960 32 | *99.0th: 45120 33 | 99.5th: 49856 34 | 99.9th: 59200 35 | min=0, max=73600` 36 | 37 | - KTweak: 38 | `50.0th: 1054 39 | 75.0th: 1790 40 | 90.0th: 2628 41 | 95.0th: 3836 42 | *99.0th: 8880 43 | 99.5th: 11472 44 | 99.9th: 18080 45 | min=0, max=32781` 46 | 47 | ### Synthmark Latencymark (lower is better) 48 | - Stock: 10 / 12 49 | - KTweak: 4 / 4 50 | 51 | ### Scheduler throughput via `perf bench sched messaging` (lower is better) 52 | - Stock: 0.331 seconds 53 | - KTweak: 0.808 seconds 54 | 55 | ### Scheduler throughput via `perf bench sched pipe` (lower is better) 56 | - Stock: 16.159 seconds 57 | - KTweak: 18.599 seconds 58 | 59 | # The Tweaks 60 | Head over to the [script itself](ktweak) to learn what everything does. It is documented in the comments. 61 | 62 | # Contact 63 | You can find me on telegram at @tytydraco. 64 | Feel free to email me at tylernij@gmail.com. 65 | 66 | Join the releases channel at @ktweak, or the discussion channel at @ktweak_discussion. 67 | -------------------------------------------------------------------------------- /ktweak: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Written by Draco (tytydraco @ GitHub) 3 | 4 | # The name of the current branch for logging purposes 5 | BRANCH="balance" 6 | 7 | # Maximum unsigned integer size in C 8 | UINT_MAX="4294967295" 9 | 10 | # Duration in nanoseconds of one scheduling period 11 | SCHED_PERIOD="$((4 * 1000 * 1000))" 12 | 13 | # How many tasks should we have at a maximum in one scheduling period 14 | SCHED_TASKS="8" 15 | 16 | write() { 17 | # Bail out if file does not exist 18 | [[ ! -f "$1" ]] && return 1 19 | 20 | # Make file writable in case it is not already 21 | chmod +w "$1" 2> /dev/null 22 | 23 | # Write the new value and bail if there's an error 24 | if ! echo "$2" > "$1" 2> /dev/null 25 | then 26 | echo "Failed: $1 → $2" 27 | return 1 28 | fi 29 | 30 | # Log the success 31 | echo "$1 → $2" 32 | } 33 | 34 | # Check for root permissions and bail if not granted 35 | if [[ "$(id -u)" -ne 0 ]] 36 | then 37 | echo "No root permissions. Exiting." 38 | exit 1 39 | fi 40 | 41 | # Detect if we are running on Android 42 | grep -q android /proc/cmdline && ANDROID=true 43 | 44 | # Log the date and time for records sake 45 | echo "Time of execution: $(date)" 46 | echo "Branch: $BRANCH" 47 | 48 | # Sync to data in the rare case a device crashes 49 | sync 50 | 51 | # Limit max perf event processing time to this much CPU usage 52 | write /proc/sys/kernel/perf_cpu_time_max_percent 5 53 | 54 | # Group tasks for less stutter but less throughput 55 | write /proc/sys/kernel/sched_autogroup_enabled 1 56 | 57 | # Execute child process before parent after fork 58 | write /proc/sys/kernel/sched_child_runs_first 1 59 | 60 | # Preliminary requirement for the following values 61 | write /proc/sys/kernel/sched_tunable_scaling 0 62 | 63 | # Reduce the maximum scheduling period for lower latency 64 | write /proc/sys/kernel/sched_latency_ns "$SCHED_PERIOD" 65 | 66 | # Schedule this ratio of tasks in the guarenteed sched period 67 | write /proc/sys/kernel/sched_min_granularity_ns "$((SCHED_PERIOD / SCHED_TASKS))" 68 | 69 | # Require preeptive tasks to surpass half of a sched period in vmruntime 70 | write /proc/sys/kernel/sched_wakeup_granularity_ns "$((SCHED_PERIOD / 2))" 71 | 72 | # Reduce the frequency of task migrations 73 | write /proc/sys/kernel/sched_migration_cost_ns 5000000 74 | 75 | # Always allow sched boosting on top-app tasks 76 | [[ "$ANDROID" == true ]] && write /proc/sys/kernel/sched_min_task_util_for_colocation 0 77 | 78 | # Improve real time latencies by reducing the scheduler migration time 79 | write /proc/sys/kernel/sched_nr_migrate 32 80 | 81 | # Disable scheduler statistics to reduce overhead 82 | write /proc/sys/kernel/sched_schedstats 0 83 | 84 | # Disable unnecessary printk logging 85 | write /proc/sys/kernel/printk_devkmsg off 86 | 87 | # Start non-blocking writeback later 88 | write /proc/sys/vm/dirty_background_ratio 10 89 | 90 | # Start blocking writeback later 91 | write /proc/sys/vm/dirty_ratio 30 92 | 93 | # Require dirty memory to stay in memory for longer 94 | write /proc/sys/vm/dirty_expire_centisecs 3000 95 | 96 | # Run the dirty memory flusher threads less often 97 | write /proc/sys/vm/dirty_writeback_centisecs 3000 98 | 99 | # Disable read-ahead for swap devices 100 | write /proc/sys/vm/page-cluster 0 101 | 102 | # Update /proc/stat less often to reduce jitter 103 | write /proc/sys/vm/stat_interval 10 104 | 105 | # Swap to the swap device at a fair rate 106 | write /proc/sys/vm/swappiness 100 107 | 108 | # Fairly prioritize page cache and file structures 109 | write /proc/sys/vm/vfs_cache_pressure 100 110 | 111 | # Enable Explicit Congestion Control 112 | write /proc/sys/net/ipv4/tcp_ecn 1 113 | 114 | # Enable fast socket open for receiver and sender 115 | write /proc/sys/net/ipv4/tcp_fastopen 3 116 | 117 | # Disable SYN cookies 118 | write /proc/sys/net/ipv4/tcp_syncookies 0 119 | 120 | if [[ -f "/sys/kernel/debug/sched_features" ]] 121 | then 122 | # Consider scheduling tasks that are eager to run 123 | write /sys/kernel/debug/sched_features NEXT_BUDDY 124 | 125 | # Schedule tasks on their origin CPU if possible 126 | write /sys/kernel/debug/sched_features TTWU_QUEUE 127 | fi 128 | 129 | [[ "$ANDROID" == true ]] && if [[ -d "/dev/stune/" ]] 130 | then 131 | # We are not concerned with prioritizing latency 132 | write /dev/stune/top-app/schedtune.prefer_idle 0 133 | 134 | # Mark top-app as boosted, find high-performing CPUs 135 | write /dev/stune/top-app/schedtune.boost 1 136 | fi 137 | 138 | # Loop over each CPU in the system 139 | for cpu in /sys/devices/system/cpu/cpu*/cpufreq 140 | do 141 | # Fetch the available governors from the CPU 142 | avail_govs="$(cat "$cpu/scaling_available_governors")" 143 | 144 | # Attempt to set the governor in this order 145 | for governor in schedutil interactive 146 | do 147 | # Once a matching governor is found, set it and break for this CPU 148 | if [[ "$avail_govs" == *"$governor"* ]] 149 | then 150 | write "$cpu/scaling_governor" "$governor" 151 | break 152 | fi 153 | done 154 | done 155 | 156 | # Apply governor specific tunables for schedutil 157 | find /sys/devices/system/cpu/ -name schedutil -type d | while IFS= read -r governor 158 | do 159 | # Consider changing frequencies once per scheduling period 160 | write "$governor/up_rate_limit_us" "$((SCHED_PERIOD / 1000))" 161 | write "$governor/down_rate_limit_us" "$((4 * SCHED_PERIOD / 1000))" 162 | write "$governor/rate_limit_us" "$((SCHED_PERIOD / 1000))" 163 | 164 | # Jump to hispeed frequency at this load percentage 165 | write "$governor/hispeed_load" 90 166 | write "$governor/hispeed_freq" "$UINT_MAX" 167 | done 168 | 169 | # Apply governor specific tunables for interactive 170 | find /sys/devices/system/cpu/ -name interactive -type d | while IFS= read -r governor 171 | do 172 | # Consider changing frequencies once per scheduling period 173 | write "$governor/timer_rate" "$((SCHED_PERIOD / 1000))" 174 | write "$governor/min_sample_time" "$((SCHED_PERIOD / 1000))" 175 | 176 | # Jump to hispeed frequency at this load percentage 177 | write "$governor/go_hispeed_load" 90 178 | write "$governor/hispeed_freq" "$UINT_MAX" 179 | done 180 | 181 | for queue in /sys/block/*/queue 182 | do 183 | # Choose the first governor available 184 | avail_scheds="$(cat "$queue/scheduler")" 185 | for sched in cfq noop kyber bfq mq-deadline none 186 | do 187 | if [[ "$avail_scheds" == *"$sched"* ]] 188 | then 189 | write "$queue/scheduler" "$sched" 190 | break 191 | fi 192 | done 193 | 194 | # Do not use I/O as a source of randomness 195 | write "$queue/add_random" 0 196 | 197 | # Disable I/O statistics accounting 198 | write "$queue/iostats" 0 199 | 200 | # Reduce heuristic read-ahead in exchange for I/O latency 201 | write "$queue/read_ahead_kb" 128 202 | 203 | # Reduce the maximum number of I/O requests in exchange for latency 204 | write "$queue/nr_requests" 64 205 | done 206 | 207 | # Always return success, even if the last write fails 208 | exit 0 209 | -------------------------------------------------------------------------------- /ktweak.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=KTweak 3 | 4 | Wants=network.target 5 | After=syslog.target network-online.target 6 | 7 | [Service] 8 | Type=simple 9 | ExecStart=ktweak 10 | Restart=on-failure 11 | RestartSec=10 12 | KillMode=process 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | --------------------------------------------------------------------------------