From c74e6f948300b02dda0ab0da99f4622d5f3cb773 Mon Sep 17 00:00:00 2001 From: dyokism Date: Mon, 22 Jun 2026 18:05:40 +0700 Subject: [PATCH 1/2] fix: prevent schedutil deadlock on Samsung Snapdragon devices - Add a device rule in device_mitigation.json to blacklist the schedutil governor on Samsung Snapdragon devices. - Update EncoreConfigStore.cpp to silently fall back to the walt governor if schedutil is requested by the user. - Add a native shell check to service.sh to ensure the schedutil governor is bypassed during early boot before the daemon starts. --- config/device_mitigation.json | 21 ++++++++++++++++++++- jni/EncoreConfigStore.cpp | 15 +++++++++++++++ module/service.sh | 9 +++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/config/device_mitigation.json b/config/device_mitigation.json index 46c5ada5..a1de8e62 100644 --- a/config/device_mitigation.json +++ b/config/device_mitigation.json @@ -2,5 +2,24 @@ "default": { "items": ["DISABLE_DDR_TWEAK", "NO_PERFORMANCE_CPUGOV", "QCOM_NO_GPU_POWERSAVE"] }, - "device_rules": {} + "device_rules": { + "snapdragon_samsung_schedutil_bug": { + "name": "Snapdragon/Samsung Schedutil Mitigation", + "description": "Prevents 100% CPU usage deadlock on Prime Core by blacklisting schedutil on Samsung Snapdragon kernels.", + "filter_type": "all", + "items": [ + "NO_SCHEDUTIL_CPUGOV" + ], + "filter_condition": { + "soc": { + "operator": "regex", + "value": "(?i)(sm[0-9]+|qcom|qualcomm|snapdragon)" + }, + "model": { + "operator": "regex", + "value": "(?i)(sm-|samsung)" + } + } + } + } } diff --git a/jni/EncoreConfigStore.cpp b/jni/EncoreConfigStore.cpp index a86dfbdd..b14a1b61 100644 --- a/jni/EncoreConfigStore.cpp +++ b/jni/EncoreConfigStore.cpp @@ -25,6 +25,7 @@ #include #include +#include "DeviceMitigationStore.hpp" #include "EncoreConfigStore.hpp" bool EncoreConfigStore::load_config(const std::string &config_path) { @@ -153,6 +154,14 @@ std::string EncoreConfigStore::read_default_cpu_governor() const { } file.close(); + + auto mitigations = device_mitigation_store.get_cached_mitigation_items(false); + if (mitigations.contains("NO_SCHEDUTIL_CPUGOV")) { + if (default_governor == "schedutil") { + default_governor = "walt"; + } + } + return default_governor; } @@ -219,6 +228,12 @@ bool EncoreConfigStore::parse_config(const rapidjson::Document &doc) { } } + auto mitigations = device_mitigation_store.get_cached_mitigation_items(new_config.preferences.use_device_mitigation); + if (mitigations.contains("NO_SCHEDUTIL_CPUGOV")) { + if (new_config.cpu_governor.balance == "schedutil") new_config.cpu_governor.balance = "walt"; + if (new_config.cpu_governor.powersave == "schedutil") new_config.cpu_governor.powersave = "walt"; + } + { std::lock_guard lock(mutex_); config_ = new_config; diff --git a/module/service.sh b/module/service.sh index b9baee71..eb028bec 100644 --- a/module/service.sh +++ b/module/service.sh @@ -30,6 +30,15 @@ rm -f "$MODULE_CONFIG/encore.log" "$MODULE_CONFIG/sysmon.log" # Parse Governor to use chmod 644 "$CPUFREQ/scaling_governor" default_gov=$(cat "$CPUFREQ/scaling_governor") + +# Add mitigation for Samsung Snapdragon Bug +SOC_ID=$(cat "$MODULE_CONFIG/soc_recognition" 2>/dev/null) +if [ "$SOC_ID" = "2" ] && getprop ro.product.brand | grep -iq "samsung"; then + if [ "$default_gov" = "schedutil" ]; then + default_gov="walt" + fi +fi + echo "$default_gov" >$MODULE_CONFIG/default_cpu_gov # Create cleanup script From cb68003681900e7216dc1519058ef0d1b3a38bec Mon Sep 17 00:00:00 2001 From: dyokism Date: Tue, 23 Jun 2026 11:59:15 +0700 Subject: [PATCH 2/2] fix: only apply schedutil mitigation if walt is available - Check available governors in sysfs before replacing schedutil - Ensures compatibility on older pre-GKI kernels --- jni/EncoreConfigStore.cpp | 19 +++++++++++++++++-- module/service.sh | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/jni/EncoreConfigStore.cpp b/jni/EncoreConfigStore.cpp index b14a1b61..e1788715 100644 --- a/jni/EncoreConfigStore.cpp +++ b/jni/EncoreConfigStore.cpp @@ -138,6 +138,21 @@ bool EncoreConfigStore::reload() { return load_config(config_path_); } +// Skip bypass on pre-GKI kernels where 'walt' doesn't exist and 'schedutil' is safe. +static bool is_governor_supported(const std::string &gov) { + std::ifstream file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"); + if (!file.is_open()) { + return false; + } + std::string available_gov; + while (file >> available_gov) { + if (available_gov == gov) { + return true; + } + } + return false; +} + std::string EncoreConfigStore::read_default_cpu_governor() const { // Fallback governor std::string default_governor = "schedutil"; @@ -156,7 +171,7 @@ std::string EncoreConfigStore::read_default_cpu_governor() const { file.close(); auto mitigations = device_mitigation_store.get_cached_mitigation_items(false); - if (mitigations.contains("NO_SCHEDUTIL_CPUGOV")) { + if (mitigations.contains("NO_SCHEDUTIL_CPUGOV") && is_governor_supported("walt")) { if (default_governor == "schedutil") { default_governor = "walt"; } @@ -229,7 +244,7 @@ bool EncoreConfigStore::parse_config(const rapidjson::Document &doc) { } auto mitigations = device_mitigation_store.get_cached_mitigation_items(new_config.preferences.use_device_mitigation); - if (mitigations.contains("NO_SCHEDUTIL_CPUGOV")) { + if (mitigations.contains("NO_SCHEDUTIL_CPUGOV") && is_governor_supported("walt")) { if (new_config.cpu_governor.balance == "schedutil") new_config.cpu_governor.balance = "walt"; if (new_config.cpu_governor.powersave == "schedutil") new_config.cpu_governor.powersave = "walt"; } diff --git a/module/service.sh b/module/service.sh index eb028bec..1cf26c9a 100644 --- a/module/service.sh +++ b/module/service.sh @@ -35,7 +35,9 @@ default_gov=$(cat "$CPUFREQ/scaling_governor") SOC_ID=$(cat "$MODULE_CONFIG/soc_recognition" 2>/dev/null) if [ "$SOC_ID" = "2" ] && getprop ro.product.brand | grep -iq "samsung"; then if [ "$default_gov" = "schedutil" ]; then - default_gov="walt" + if grep -q "walt" "$CPUFREQ/scaling_available_governors"; then + default_gov="walt" + fi fi fi