mik*_*ike 5 memory centos swap cgroups
我正在使用内核运行 CentOS 7 3.10.0-693.5.2.el7.x86_64
。
我使用 cgroups 对进程应用内存限制。在应用程序滚动重启期间,内存限制加倍以适应内存需求。
但是有时在重新启动后无法将交换内存限制降低到原始值并且 cgroup 返回错误 write error: Device or resource busy
如
[root@us app]# echo "643825664" > memory.limit_in_bytes
[root@us app]# echo "673825664" > memory.memsw.limit_in_bytes
-bash: echo: write error: Device or resource busy
[root@us app]# echo "873825664" > memory.memsw.limit_in_bytes
[root@us app]#
Run Code Online (Sandbox Code Playgroud)
写入更大的值(例如 +200MB)似乎可以正常工作。
我还没有弄清楚为什么会发生这种情况。我在 cgroup 文档中没有找到任何涉及此错误的内容。我认为它必须在当前交换使用率高于限制的情况下做一些事情。
您对此类错误有任何经验吗?
什么cat memory.memsw.usage_in_bytes
发言权?您不能将最大值设置为低于当前限制。
查看 3.10 Linux 源代码,修改memsw.limit_in_bytes
结果调用mem_cgroup_write()
:
{
.name = "memsw.limit_in_bytes",
.private = MEMFILE_PRIVATE(_MEMSWAP, RES_LIMIT),
.write_string = mem_cgroup_write,
.read = mem_cgroup_read,
},
Run Code Online (Sandbox Code Playgroud)
mem_cgroup_write()
定义在:https :
//elixir.bootlin.com/linux/v3.10/source/mm/memcontrol.c#L5199
mem_cgroup_write()
mem_cgroup_resize_memsw_limit()
当类型为时依次调用_MEMSWAP
:
else if (type == _MEMSWAP)
ret = mem_cgroup_resize_memsw_limit(memcg, val);
Run Code Online (Sandbox Code Playgroud)
mem_cgroup_resize_memsw_limit()
定义在:https :
//elixir.bootlin.com/linux/v3.10/source/mm/memcontrol.c#L4647
该函数调用res_counter_set_limit()
:https :
//elixir.bootlin.com/linux/v3.10/source/include/linux/res_counter.h#L200
该函数的实现是:
unsigned long flags;
int ret = -EBUSY;
spin_lock_irqsave(&cnt->lock, flags);
if (cnt->usage <= limit) {
cnt->limit = limit;
ret = 0;
}
spin_unlock_irqrestore(&cnt->lock, flags);
return ret;
Run Code Online (Sandbox Code Playgroud)
请注意,ret
初始化为-EBUSY
(对应于Device or resource busy
您看到的消息),并且仅当当前使用量小于或等于请求的限制时才更改为零。我的猜测是,在你的情况下它不是,所以函数返回-EBUSY
.
如果res_counter_set_limit()
将非零值返回给mem_cgroup_resize_memsw_limit()
,则mem_cgroup_resize_limit()
依次返回相同的值。 mem_cgroup_resize_limit()
将值返回到mem_cgroup_write()
。该返回值会传播到用户空间,这就是为什么您会看到从echo
.
实现是当前内核源代码有点不同,但行为是相同的。您不能将最小值调整为小于使用值的值。
归档时间: |
|
查看次数: |
3535 次 |
最近记录: |