[PATCH] mm, memcg: Add memory.transparent_hugepage_disabled

补丁目的

Linux 中通过 /sys/kernel/mm/transparent_hugepage/enabled 控制系统级是否启用 Transparent Huge Pages(THP,透明大页),但有时候即便全局开启了 THP(比如设置为 “always” 或 “madvise”),仍然希望限制某些特定 应用或容器 不使用 THP,因为它可能消耗更多内存或 CPU。

为了解决这个问题,补丁为 memory cgroup(memcg) 引入了一个布尔标志:

memory.transparent_hugepage_disabled

设置为 1 后,所属的 cgroup 里的进程将无法使用 THP(除了 DAX 情况)。

关键文件分析

用户空间 echo 1 > memory.transparent_hugepage_disabled
          ↓
内核 memcg->transparent_hugepage_disabled = true
          ↓
每次分配 THP 页时,判断该字段
          ↓
若为 true → 禁用 THP 分配,使用普通页

include/linux/memcontrol.h

在 struct mem_cgroup 中添加字段:

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
    struct deferred_split deferred_split_queue;
    bool transparent_hugepage_disabled;
#endif

新增的布尔值标志位记录:该 cgroup 是否禁用 THP。

mm/memcontrol.c

mem_cgroup_css_alloc() 中的继承逻辑为支持 memcg 层级继承父节点的配置(保持行为一致性)。

if (parent)
    memcg->transparent_hugepage_disabled = parent->transparent_hugepage_disabled;
else
    memcg->transparent_hugepage_disabled = false;

为 memory cgroup 添加文件接口,添加后路径会是:/sys/fs/cgroup/memory//memory.transparent_hugepage_disabled

{
    .name = "transparent_hugepage_disabled",
    .flags = CFTYPE_NOT_ON_ROOT,
    .read_u64 = transparent_hugepage_disabled_read,
    .write_u64 = transparent_hugepage_disabled_write,
},

mm/huge_mm.h

增加对该标志的调用接口:

#ifdef CONFIG_MEMCG
extern bool memcg_transparent_hugepage_disabled(struct vm_area_struct *vma);
#else
static inline bool memcg_transparent_hugepage_disabled(...) { return false; }
#endif

在 THP 决策函数中插入该逻辑判断:

if (memcg_transparent_hugepage_disabled(vma))
    return false;

这使得即便全局允许 THP,若所在 memcg 设置了该标志位,依然禁用 THP。

mm/shmem.c

在匿名页分配外,还对 tmpfs 文件页(shmem)启用了相同检查:

if (memcg_transparent_hugepage_disabled(vma))
    goto alloc_nohuge;

确保对 tmpfs 的 hugepage 使用也遵守该 cgroup 限制。

memcg_transparent_hugepage_disabled()

bool memcg_transparent_hugepage_disabled(struct vm_area_struct *vma)
{
    struct mem_cgroup *memcg = get_mem_cgroup_from_mm(vma->vm_mm);
    return memcg && memcg->transparent_hugepage_disabled;
}

社区观点

主要的 usecase 是在 VM 和其他 workload 混部环境下,实现精细化控制:让 VM 使用 THP,而屏蔽掉其他曾遇到 THP 问题的应用。不过当前的 THP 语义已经很复杂,再引入 memcg 级别的开关,会让使用者更加混乱,除非你有非常强的动机。

当前接口只作用于当前 cgroup,而不是像其他 memcg 参数一样支持向下继承,设计上不一致。

patch 也没有说明对 kcompactd 有什么影响或优化。


文章作者: 易百分
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 易百分 !
  目录