カーネルを使用してCentOS 7を実行しています3.10.0-693.5.2.el7.x86_64
。
プロセスにメモリ制限を適用するためにcgroupを使用します。アプリケーションのローリングの再起動中は、メモリ要件を満たすためにメモリ制限が2倍になります。
ただし、再起動後にスワップメモリの制限を元の値に下げることはできず、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]#
大きな値(+200 MBなど)を書き込むのがうまくいくようです。
なぜこれが起こるのかを理解できませんでした。 cgroup ドキュメントでこのエラーを参照する内容が見つかりませんでした。現在のスワップ使用量が制限を超えた場合は、何か措置を講じる必要があると思います。
この種のエラーを経験した経験はありますか?
ベストアンサー1
何と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()
0以外の値が返されるmem_cgroup_resize_memsw_limit()
と、同じmem_cgroup_resize_limit()
値が順番に返されます。 mem_cgroup_resize_limit()
に値を返しますmem_cgroup_write()
。戻り値はユーザー空間に伝播されるため、戻り値が表示されますecho
。
現在のカーネルソースの実装は少し異なりますが、動作は同じです。最小値を使用した値より小さい値に調整することはできません。