diff --git a/lmkd.cpp b/lmkd.cpp index 6133938..741e891 100644 --- a/lmkd.cpp +++ b/lmkd.cpp @@ -3154,14 +3154,44 @@ static void destroy_mp_psi(enum vmpressure_level level) { mpevfd[level] = -1; } +enum class MemcgVersion { + kNotFound, + kV1, + kV2, +}; + +static MemcgVersion __memcg_version() { + std::string cgroupv2_path, memcg_path; + + if (!CgroupGetControllerPath("memory", &memcg_path)) { + return MemcgVersion::kNotFound; + } + return CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, &cgroupv2_path) && + cgroupv2_path == memcg_path + ? MemcgVersion::kV2 + : MemcgVersion::kV1; +} + +static MemcgVersion memcg_version() { + static MemcgVersion version = __memcg_version(); + + return version; +} + static bool init_psi_monitors() { /* * When PSI is used on low-ram devices or on high-end devices without memfree levels - * use new kill strategy based on zone watermarks, free swap and thrashing stats + * use new kill strategy based on zone watermarks, free swap and thrashing stats. + * Also use the new strategy if memcg has not been mounted in the v1 cgroups hiearchy since + * the old strategy relies on memcg attributes that are available only in the v1 cgroups + * hiearchy. */ bool use_new_strategy = GET_LMK_PROPERTY(bool, "use_new_strategy", low_ram_device || !use_minfree_levels); - + if (!use_new_strategy && memcg_version() != MemcgVersion::kV1) { + ALOGE("Old kill strategy can only be used with v1 cgroup hierarchy"); + return false; + } /* In default PSI mode override stall amounts using system properties */ if (use_new_strategy) { /* Do not use low pressure level */ @@ -3186,6 +3216,13 @@ static bool init_psi_monitors() { } static bool init_mp_common(enum vmpressure_level level) { + // The implementation of this function relies on memcg statistics that are only available in the + // v1 cgroup hierarchy. + if (memcg_version() != MemcgVersion::kV1) { + ALOGE("%s: global monitoring is only available for the v1 cgroup hierarchy", __func__); + return false; + } + int mpfd; int evfd; int evctlfd;