#!/usr/bin/env bash # Written by Draco (tytydraco @ GitHub) write() { # Bail out if file does not exist [[ ! -f "$1" ]] && return 1 # Make file writable in case it is not already chmod +w "$1" 2> /dev/null # Write the new value and bail if there's an error if ! echo "$2" > "$1" 2> /dev/null then echo "Failed: $1 → $2" return 1 fi # Log the success echo "$1 → $2" } # Check for root permissions and bail if not granted if [[ "$(id -u)" -ne 0 ]] then echo "No root permissions. Exiting." exit 1 fi # Log the date and time for records sake echo "Time of execution: $(date)" # We need to execute this multiple times because # sched_downmirate must be less than sched_upmigrate, and # sched_upmigrate must be greater than sched_downmigrate for _ in $(seq 2) do # Migrate tasks down at this much load write /proc/sys/kernel/sched_downmigrate 80 write /proc/sys/kernel/sched_group_downmigrate "80 80" # Migrate tasks up at this much load write /proc/sys/kernel/sched_upmigrate 80 write /proc/sys/kernel/sched_group_upmigrate "80 80" done # Limit max perf event processing time to this much CPU usage write /proc/sys/kernel/perf_cpu_time_max_percent 5 # Do not group task groups automatically write /proc/sys/kernel/sched_autogroup_enabled 0 # Execute child process before parent after fork write /proc/sys/kernel/sched_child_runs_first 1 # Preliminary requirement for the following values write /proc/sys/kernel/sched_tunable_scaling 0 # Reduce the maximum scheduling period for lower latency write /proc/sys/kernel/sched_latency_ns 2000000 # Schedule 10 tasks in the guarenteed sched period write /proc/sys/kernel/sched_min_granularity_ns 200000 # Require preeptive tasks to surpass half of a sched period in vmruntime write /proc/sys/kernel/sched_wakeup_granularity_ns 1000000 # Reduce the frequency of task migrations write /proc/sys/kernel/sched_migration_cost_ns 5000000 # Always allow sched boosting on top-app tasks write /proc/sys/kernel/sched_min_task_util_for_colocation 0 # Improve real time latencies by reducing the scheduler migration time write /proc/sys/kernel/sched_nr_migrate 8 # Disable scheduler statistics to reduce overhead write /proc/sys/kernel/sched_schedstats 0 # Start non-blocking writeback later write /proc/sys/vm/dirty_background_ratio 10 # Start blocking writeback later write /proc/sys/vm/dirty_ratio 30 # Require dirty memory to stay in memory for longer write /proc/sys/vm/dirty_expire_centisecs 3000 # Run the dirty memory flusher threads less often write /proc/sys/vm/dirty_writeback_centisecs 3000 # Disable read-ahead for swap devices write /proc/sys/vm/page-cluster 0 # Update /proc/stat less often to reduce jitter write /proc/sys/vm/stat_interval 10 # Swap to the swap device at a fair rate write /proc/sys/vm/swappiness 100 # Allow more inodes and dentries to be cached write /proc/sys/vm/vfs_cache_pressure 60 if [[ -f "/sys/kernel/debug/sched_features" ]] then # Consider scheduling tasks that are eager to run write /sys/kernel/debug/sched_features NEXT_BUDDY # Schedule tasks on their origin CPU if possible write /sys/kernel/debug/sched_features TTWU_QUEUE # Use a high resolution timer for the scheduler write /sys/kernel/debug/sched_features HRTICK fi if [[ -d "/dev/stune/" ]] then # Artificially inflate top-app task load write /dev/stune/top-app/schedtune.boost 10 # Prefer to schedule top-app tasks on idle CPUs write /dev/stune/top-app/schedtune.prefer_idle 1 fi for cpu in /sys/devices/system/cpu/cpu*/cpufreq/ do avail_govs="$(cat "${cpu}scaling_available_governors")" case "$avail_govs" in *schedutil*) write "${cpu}scaling_governor" schedutil # Consider changing frequencies once per scheduling period write "${cpu}schedutil/up_rate_limit_us" 5000 write "${cpu}schedutil/down_rate_limit_us" 5000 write "${cpu}schedutil/rate_limit_us" 5000 # Jump to max frequency at 90% load write "${cpu}schedutil/hispeed_load" 90 write "${cpu}schedutil/hispeed_freq" "$(cat "${cpu}cpuinfo_max_freq")" ;; *interactive*) write "${cpu}scaling_governor" interactive # Consider changing frequencies once per scheduling period write "${cpu}interactive/timer_rate" 5000 write "${cpu}interactive/min_sample_time" 5000 # Jump to max frequency at 90% load write "${cpu}interactive/go_hispeed_load" 90 write "${cpu}interactive/hispeed_freq" "$(cat "${cpu}cpuinfo_max_freq")" ;; esac done for queue in /sys/block/*/queue/ do # Choose the first governor available avail_scheds="$(cat "${queue}scheduler")" for sched in cfq noop kyber bfq mq-deadline none do if [[ "$avail_scheds" == *"$sched"* ]] then write "${queue}scheduler" "$sched" break fi done # Do not use I/O as a source of randomness write "${queue}add_random" 0 # Disable I/O statistics accounting write "${queue}iostats" 0 # Only attempt simple merges write "${queue}nomerges" 1 # Force request completion on the origin CPU for maximum cache locality write "${queue}rq_affinity" 2 # Reduce heuristic read-ahead in exchange for I/O latency write "${queue}read_ahead_kb" 16 # Reduce the maximum number of I/O requests in exchange for latency write "${queue}nr_requests" 64 done # Always return success, even if the last write fails exit 0