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]#
寫入更大的值(例如 +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
.實現是目前核心原始碼有點不同,但行為是相同的。您不能將最小值調整為小於使用值的值。