Linux 커널은 64비트 시스템에서 mem_map 배열을 어떻게 초기화합니까?

Linux 커널은 64비트 시스템에서 mem_map 배열을 어떻게 초기화합니까?

나는 Linux 커널이 C 구조에 의존하여 각 물리적 페이지 프레임의 상태를 추적한다는 것을 알고 있습니다 struct page. 모든 페이지 프레임의 구조는 mem_map[]형식화된 배열을 형성하므로 struct page페이지 프레임 번호를 인덱스로 사용하여 특정 페이지 프레임의 구조를 쉽게 검색할 수 있습니다. 4GiB의 물리적 메모리를 갖춘 x86 32비트 시스템에서 배열은 2 20개의
항목으로 구성되며 페이지 크기가 4096바이트이므로 각 항목의 크기는 32바이트이므로 전체 배열은 32MiB를 소비합니다. 이제 이를 물리적 메모리가 4TiB인 x86 64비트 시스템으로 전송하면 배열은 각각 크기가 32바이트인 2개의 30개 항목으로 구성되므로 배열은 32GiB를 소비합니다. 물론 물리적 메모리가 증가함에 따라 플랫폼별 제한인 4PiB(amd64 아키텍처의 경우 252 바이트 )에 도달 하면 어레이를 최대 32TiB까지 늘릴 수 있습니다 . 커널은 실제로 부팅 시 많은 양의 데이터를 초기화해야 합니까, 아니면 뭔가 빠졌습니까?

답변1

세 가지가 있습니다.물리적 메모리 모델Linux 커널은 설명하는 평면 모델, 불연속 메모리 모델 및 희소 메모리 모델을 사용합니다.

전부는 아니지만 대부분의 Linux에서 지원되는 64비트 아키텍처는 기본적으로 후자를 사용합니다. 이는 메모리 부분과 대부분의 아키텍처에 가상으로 할당된 메모리 매핑에 의존합니다. 실제 물리적 메모리를 나타내는 데 필요한 항목은 필요에 따라 할당되고 초기화됩니다. 대규모 시스템에서는 시작이 지연되지 않도록 이 초기화를 연기하는 것도 가능합니다.

답변2

https://lwn.net/Articles/839737/(2020년 12월 11일) 여전히 "페이지 구조는 일반적으로 사용 가능한 메모리의 1.5% 이상을 차지합니다"라고 말합니다. 백분율은 64/4096 = 1.5625%에서 나온 것 같습니다.

5700GB 메모리가 있고 Azure에서 실행되는 M416s_v2 Ubuntu 20.04 VM에서 오버헤드는 1.5657%로, 이는 1.5625%에 더 가깝습니다.

"cat /proc/meminfo |grep MemTotal:" 표시: "MemTotal: 5882783592 kB"

(Linux kdump용으로 512MB 메모리를 예약했습니다.): "cat /proc/cmdline"은 "BOOT_IMAGE=/boot/vmlinuz-5.4.0-1010-azure root=PARTUUID=7327629e-2b41-4f48-893e-9ae930552551 ro console=tty1을 보여줍니다. console=ttyS0 Earlyprintk=ttyS0 crashkernel=512M 패닉=-1"

1 - (5882783592 / (5700.0 * 1024 *1024 - 512 * 1024)) = 0.015657580372575808

(5700 * 1024 * 1024) * (0.015657580372575808 - 64.0/4096) / 1024 = 190.16511865047505

페이지 구조 외에도 커널/드라이버 코드/데이터/BSS는 약 190MB를 사용합니다. 여기서는 펌웨어에 의해 예약된 메모리를 무시합니다.

관련 정보