← All reports

[libpas] Support compact reservations >=128MiB

Component: libpas / bmalloc allocator | 5b0cfbc

libpas는 bmalloc, TZone, isoheap의 기반이 되는 allocator입니다. 내부 pointer 상당수를 고정된 virtual reservation 하나의 base 기준 3바이트 "compact" offset으로 저장합니다. 최소 alignment가 8B이므로, 24비트를 3만큼 shift해도 표현 범위는 128MiB에 그칩니다. 그래서 compact 주소로 참조되는 객체(view, directory, heap, size class, tree node)는 모두 이 영역 안에서 할당되어야 합니다. 이때 영역 내부의 할당은 위쪽으로만 증가하는 bump pointer 하나로 처리되어 왔습니다.

한편 pointer type마다 alignment와 decode shift가 고정되어 있습니다. decode된 compact pointer는 유효한 metadata 주소로 그대로 신뢰되기 때문에, layout과 alignment invariant는 보안과 직결됩니다. heap enumerator 역시 reservation의 bump 범위를 알아야 정상적으로 동작합니다. 이 enumerator는 out-of-process 도구와 crash reporter가 heap을 읽을 수 있도록 지원하는 구성요소입니다.

이 commit은 compact reservation을 128MiB에서 256MiB로 확장하고, 두 개의 bump allocation front로 나눴습니다. 먼저 bottom front는 위쪽으로 증가하며, alignment가 16B 미만인 객체를 최대 128MiB까지 담당합니다. 반대로 top front는 아래쪽으로 증가하며, 16B-aligned 객체만 전체 256MiB 범위 안에서 담당합니다.

이를 위해 PAS_DEFINE_OVERALIGNED_COMPACT_PTR type이 새로 추가되었습니다. pointer 크기는 3B 그대로지만 shift를 3이 아닌 4로 적용하므로 256MiB까지 주소 지정이 가능합니다. 이 type은 directory, heap, cartesian tree node, size directory pointer type에 적용되었습니다. 그 밖에 enumerator, immortal heap, crash-report 코드가 함께 수정되었고, reservation과 enumeration에 대한 테스트가 새로 추가되었습니다. 사용되지 않던 ptr header 두 개도 제거되었습니다.

Compact reservation layout (offsets from reservation base)

256MiB ┬───────────────────────────────┐
       │  top front (bumps DOWN)       │
       │  only >=16B-aligned objects   │
       │  addressed via overaligned    │
       │  compact ptr (idx << 4)       │
       ├───────────────────────────────┤ <- pas_compact_heap_reservation_top_bump
       │  (free gap shared by fronts)  │
128MiB ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤  limit of bottom front
       │                               │
       ├───────────────────────────────┤ <- pas_compact_heap_reservation_bump
       │  bottom front (bumps UP)      │
       │  any alignment <16B allowed   │
       │  standard compact ptr (idx<<3)│
  0MiB ┴───────────────────────────────┘

Both pointer kinds decode relative to the reservation BASE,
even for objects living in the top front.

50GiB가 넘는 대용량 메모리 process에서는 128MiB compact reservation이 고갈되어 crash하는 사례가 나타나기 시작했습니다. 이번 변경으로 segregated view나 thread별 TLC 같은 hot metadata를 키우지 않고도 이 failure mode가 제거되었습니다. 다만 그 결과 reservation 내부에서 libpas metadata와 객체가 놓이는 위치도 달라졌습니다.

이 commit은 compact pointer의 주소 지정 모델을 바꿨습니다. 동시에 allocator에서 가장 신뢰도가 높은 metadata 경로에 아래쪽으로 증가하는 두 번째 allocation front를 추가했습니다.