페이지 교환이 취소되면 zram 무료 백업 페이지가 교환됩니까?

페이지 교환이 취소되면 zram 무료 백업 페이지가 교환됩니까?

다음 시나리오를 상상해 보십시오. 2GiB가 zram으로 교체되고 1GiB로 압축됩니다.

메모리 압박이 완화되고 2GiB가 스왑 불가능해지면 Linux에서 압축된 zram 페이지를 저장하는 데 사용되는 1GiB 페이지를 확보할 수 있습니까?

그렇다면 기존 페이지 조각 모음이 수행됩니까?
압축된 페이지에는 여러 페이지가 있어야 합니다. 한 페이지만 남기고 모두 교체되지 않으면 어떻게 되나요? 마지막 페이지도 해제될 때까지 모든 페이지가 메모리에 유지됩니까?

답변1

기본적으로 '아니오'라고 말하겠지만 그렇게 해도 괜찮습니다.

$ lsblk --discard /dev/zram0 
NAME  DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
zram0        0        4K       2T         0

이것은 zram0일회용 장치를 의미합니다.

~에서man swapon:

-d,--discard[=policy]

스왑 폐기 활성화,스왑 지원 장치가 삭제 또는 정리 작업을 지원하는지 여부.
[...]
마운트 /etc/fstab옵션 discard, discard=once또는 discard=pages을 사용하여 폐기 플래그를 활성화할 수도 있습니다.

특정 Linux 배포판에서 명령 또는 이에 상응하는 명령이 실행되는 위치를 파악 swapon하고 그에 따라 추가하면 됩니다.교환 --discard옵션 또는 discard이 장소의 옵션(또는 최소한 =pages변형)입니다 .

답변2

짧은 답변: 네, zram 배경 페이지가 자동으로 공개됩니다.

실험적 확인(커널 5.10.105) 결과, zram 장치를 사용하지 않는 경우에도 사용되지 않은 zram 저장소가 자동으로 해제되는 것으로 보입니다 discard.

요약:다음 스크립트는 많은 양의 메모리를 할당하는 프로세스를 실행합니다.
검사를 통해 zram 사용량이 zramctl처음에는 증가하다가 프로세스를 중지하고 스왑 페이지를 제거한 후 기준선으로 돌아갑니다.

# * I've run this on a freshly booted VM *

# zram is mounted with nodiscard to exclude any effects of
# `discard`.
sudo grep zram /etc/fstab
# /dev/zram0 none swap nodiscard,pri=5

# We have ~6 GiB of RAM
grep -i memtotal /proc/meminfo
# MemTotal:        6386852 kB

# Show zram usage.
# `DATA` is the total amount of uncompressed data currently stored in zram.
zramctl
# NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd          3.1G   4K   58B    4K       4 [SWAP]

# Start a process that allocates 10 GiB of RAM
stress-ng -- --vm-bytes $((10*1024**3)) --vm-keep --vm 1 &

# *Wait some time for the stress test command to be swapped out*

# zram usage has gone up from 4 KiB to 3.1 GiB
zramctl
# NAME       ALGORITHM DISKSIZE  DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd          3.1G  3.1G  1.1G  1.2G       4 [SWAP]

# Stop stress test
kill %1

# zram usage decreased from 3.1 GiB to 0.3 GiB
zramctl
# NAME       ALGORITHM DISKSIZE   DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd          3.1G 336.8M 48.6M 57.6M       4 [SWAP]

# Read the first byte of all memory pages of all processes.
# This evicts all non-kernel swapped pages without using `swapoff`, which might
# reset the zram device.
sudo ./read_all_mem_pages.rb

# Now zram usage is almost back to zero
zramctl
# NAME       ALGORITHM DISKSIZE  DATA COMPR TOTAL STREAMS MOUNTPOINT
# /dev/zram0 zstd          3.1G 18.4M  3.5M  5.9M       4 [SWAP]

원천 read_all_mem_pages.rb:

#!/usr/bin/env ruby

def access_all_pages(pid)
  name = File.basename(File.readlink("/proc/#{pid}/exe")) rescue return
  puts "#{pid} (#{name})"
  File.open("/proc/#{pid}/mem", 'r') do |mem|
    for_each_mem_page(pid) do |page_address|
      mem.seek(page_address)
      mem.read(1) rescue nil
    end
  end
end

def for_each_mem_page(pid)
  File.foreach("/proc/#{pid}/maps") do |line|
    fields = line.split
    range, dest = fields[0], fields[-1]
    next if dest == "[vsyscall]"
    start, end_ = range.split('-').map { |x| x.to_i(16) }
    address = start
    while address < end_
      yield address
      address += 4096
    end
  end
end

pids = Dir.children('/proc').grep(/^\d+$/).map(&:to_i)
pids.each { |pid| access_all_pages(pid) }

답변3

나는 zRam이 소비하는 메모리가 결코 해제되지 않는다고 믿습니다. 바라보다

sudo zramctl --output-all
NAME       DISKSIZE  DATA COMPR ALGORITHM STREAMS ZERO-PAGES TOTAL MEM-LIMIT MEM-USED MIGRATED MOUNTPOINT
/dev/zram0     5,4G 56,6M 26,5M lz4             2        697 28,2M        0B    28,2M       0B [SWAP]

중요한 것은 "TOTAL"의 증감이 아니라 제가 테스트한 한 절대 감소하지 않는 "MEM-USED"입니다. (0으로 되돌리려면 zramswap.service를 다시 시작해야 했습니다). "--output-all" 스위치를 사용하여 zramctl에서 "MEM-USED" 필드만 가져올 수 있습니다.

관련 정보