Centos

cgroups 記憶體限制 - 寫入錯誤:設備或資源忙

  • August 6, 2018

我正在執行帶有核心的 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]#

寫入更大的值(例如 +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,
},

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);

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;

請注意,它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.

實現是目前核心原始碼有點不同,但行為是相同的。您不能將最小值調整為小於使用值的值。

引用自:https://unix.stackexchange.com/questions/412040