cgroups 메모리 제한 - 쓰기 오류: 장치 또는 리소스가 사용 중입니다.

cgroups 메모리 제한 - 쓰기 오류: 장치 또는 리소스가 사용 중입니다.

커널을 사용하여 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으로 변경됩니다. 내 생각 엔 귀하의 경우에는 그렇지 않으므로 함수가 .-EBUSYDevice 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.

현재 커널 소스 구현은 약간 다르지만 동작은 동일합니다. 최소값을 사용된 값보다 작은 값으로 조정할 수 없습니다.

관련 정보