커널을 사용하여 CentOS 7을 실행하고 있습니다 3.10.0-693.5.2.el7.x86_64
.
프로세스에 메모리 제한을 적용하기 위해 cgroup을 사용합니다. 애플리케이션을 롤링 다시 시작하는 동안 메모리 요구 사항을 충족하기 위해 메모리 제한이 두 배로 늘어납니다.
그러나 때때로 재부팅 후 스왑 메모리 제한을 원래 값으로 낮출 수 없으며 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 문서에서 이 오류를 참조하는 내용을 찾지 못했습니다. 현재 스왑 사용량이 한도를 초과하면 뭔가 조치를 취해야 한다고 생각합니다.
이런 종류의 오류를 겪은 경험이 있습니까?
답변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
초기화되며 현재 사용량이 요청한 제한보다 작거나 같은 경우에만 0으로 변경됩니다. 내 생각 엔 귀하의 경우에는 그렇지 않으므로 함수가 .-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
.
현재 커널 소스 구현은 약간 다르지만 동작은 동일합니다. 최소값을 사용된 값보다 작은 값으로 조정할 수 없습니다.