요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
============================
Subsystem Trace Points: kmem
============================
The kmem tracing system captures events related to object and page allocation
within the kernel. Broadly speaking there are five major subheadings.
- Slab allocation of small objects of unknown type (kmalloc)
- Slab allocation of small objects of known type
- Page allocation
- Per-CPU Allocator Activity
- External Fragmentation
This document describes what each of the tracepoints is and why they
might be useful.
1. Slab allocation of small objects of unknown type
===================================================
::
kmalloc call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s
kmalloc_node call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d
kfree call_site=%lx ptr=%p
Heavy activity for these events may indicate that a specific cache is
justified, particularly if kmalloc slab pages are getting significantly
internal fragmented as a result of the allocation pattern. By correlating
kmalloc with kfree, it may be possible to identify memory leaks and where
the allocation sites were.
2. Slab allocation of small objects of known type
=================================================
::
kmem_cache_alloc call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s
kmem_cache_alloc_node call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d
kmem_cache_free call_site=%lx ptr=%p
These events are similar in usage to the kmalloc-related events except that
it is likely easier to pin the event down to a specific cache. At the time
of writing, no information is available on what slab is being allocated from,
but the call_site can usually be used to extrapolate that information.
3. Page allocation
==================
::
mm_page_alloc page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s
mm_page_alloc_zone_locked page=%p pfn=%lu order=%u migratetype=%d cpu=%d percpu_refill=%d
mm_page_free page=%p pfn=%lu order=%d
mm_page_free_batched page=%p pfn=%lu order=%d cold=%d
These four events deal with page allocation and freeing. mm_page_alloc is
a simple indicator of page allocator activity. Pages may be allocated from
the per-CPU allocator (high performance) or the buddy allocator.
If pages are allocated directly from the buddy allocator, the
mm_page_alloc_zone_locked event is triggered. This event is important as high
amounts of activity imply high activity on the zone->lock. Taking this lock
impairs performance by disabling interrupts, dirtying cache lines between
CPUs and serialising many CPUs.
When a page is freed directly by the caller, the only mm_page_free event
is triggered. Significant amounts of activity here could indicate that the
callers should be batching their activities.
When pages are freed in batch, the also mm_page_free_batched is triggered.
Broadly speaking, pages are taken off the LRU lock in bulk and
freed in batch with a page list. Significant amounts of activity here could
indicate that the system is under memory pressure and can also indicate
contention on the lruvec->lru_lock.
4. Per-CPU Allocator Activity
=============================
::
mm_page_alloc_zone_locked page=%p pfn=%lu order=%u migratetype=%d cpu=%d percpu_refill=%d
mm_page_pcpu_drain page=%p pfn=%lu order=%d cpu=%d migratetype=%d
In front of the page allocator is a per-cpu page allocator. It exists only
for order-0 pages, reduces contention on the zone->lock and reduces the
amount of writing on struct page.
When a per-CPU list is empty or pages of the wrong type are allocated,
the zone->lock will be taken once and the per-CPU list refilled. The event
triggered is mm_page_alloc_zone_locked for each page allocated with the
event indicating whether it is for a percpu_refill or not.
When the per-CPU list is too full, a number of pages are freed, each one
which triggers a mm_page_pcpu_drain event.
The individual nature of the events is so that pages can be tracked
between allocation and freeing. A number of drain or refill pages that occur
consecutively imply the zone->lock being taken once. Large amounts of per-CPU
refills and drains could imply an imbalance between CPUs where too much work
is being concentrated in one place. It could also indicate that the per-CPU
lists should be a larger size. Finally, large amounts of refills on one CPU
and drains on another could be a factor in causing large amounts of cache
line bounces due to writes between CPUs and worth investigating if pages
can be allocated and freed on the same CPU through some algorithm change.
5. External Fragmentation
=========================
::
mm_page_alloc_extfrag page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d
External fragmentation affects whether a high-order allocation will be
successful or not. For some types of hardware, this is important although
it is avoided where possible. If the system is using huge pages and needs
to be able to resize the pool over the lifetime of the system, this value
is important.
Large numbers of this event implies that memory is fragmenting and
high-order allocations will start failing at some time in the future. One
means of reducing the occurrence of this event is to increase the size of
min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
pageblock_size is usually the size of the default hugepage size.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
kmem tracepoint의 다섯 범주
1-16kmem tracing system은 kernel 내부의 object와 page allocation 관련 event를 캡처한다. 이 문서는 각 tracepoint가 무엇이며 왜 유용한지 설명한다.
범주는 type을 알 수 없는 작은 object의 slab allocation인 kmalloc, type을 아는 작은 object의 slab allocation, page allocation, per-CPU allocator activity, external fragmentation의 다섯 가지다.
allocation 계층과 분석 목적에 따라 다섯 종류로 나뉜다.
object allocation에서 page allocator까지의 관계를 보여 준다.
============================
Subsystem Trace Points: kmem
============================
The kmem tracing system captures events related to object and page allocation
within the kernel. Broadly speaking there are five major subheadings.
- Slab allocation of small objects of unknown type (kmalloc)
- Slab allocation of small objects of known type
- Page allocation
- Per-CPU Allocator Activity
- External Fragmentation
This document describes what each of the tracepoints is and why they
might be useful.
알 수 없는 type과 알려진 type의 slab allocation
17-44type을 알 수 없는 작은 object에는 `kmalloc`, `kmalloc_node`, `kfree` tracepoint를 사용한다. field에는 call site, pointer, 요청 byte, 실제 할당 byte, GFP flag가 있고 node variant에는 NUMA node도 있다.
이 event가 매우 활발하면 allocation pattern 때문에 kmalloc slab page의 internal fragmentation이 커지고 있어 전용 cache가 타당할 수 있다. `kmalloc`과 `kfree`를 연계하면 memory leak과 allocation site를 찾을 가능성이 있다.
type을 아는 object에는 `kmem_cache_alloc`, `kmem_cache_alloc_node`, `kmem_cache_free`를 사용한다. 용도는 kmalloc event와 비슷하지만 특정 cache로 범위를 좁히기 더 쉽다.
문서 작성 시점에는 어느 slab에서 할당했는지 직접 나타내는 정보가 없지만 `call_site`로 대개 추론할 수 있다.
generic kmalloc과 named cache 계열을 비교한다.
allocation과 free를 pointer 및 call site로 연계한다.
1. Slab allocation of small objects of unknown type
===================================================
::
kmalloc call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s
kmalloc_node call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d
kfree call_site=%lx ptr=%p
Heavy activity for these events may indicate that a specific cache is
justified, particularly if kmalloc slab pages are getting significantly
internal fragmented as a result of the allocation pattern. By correlating
kmalloc with kfree, it may be possible to identify memory leaks and where
the allocation sites were.
2. Slab allocation of small objects of known type
=================================================
::
kmem_cache_alloc call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s
kmem_cache_alloc_node call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d
kmem_cache_free call_site=%lx ptr=%p
These events are similar in usage to the kmalloc-related events except that
it is likely easier to pin the event down to a specific cache. At the time
of writing, no information is available on what slab is being allocated from,
but the call_site can usually be used to extrapolate that information.
Page allocation과 free
45-73page allocation과 free에는 `mm_page_alloc`, `mm_page_alloc_zone_locked`, `mm_page_free`, `mm_page_free_batched` 네 event가 있다. `mm_page_alloc`은 page allocator activity의 단순 지표이며 page는 고성능 per-CPU allocator 또는 buddy allocator에서 올 수 있다.
buddy allocator에서 직접 page를 할당하면 `mm_page_alloc_zone_locked`가 발생한다. 이 event가 많으면 `zone->lock` activity가 높다는 뜻이다. 이 lock은 interrupt를 비활성화하고 CPU 사이 cache line을 dirty하게 만들며 여러 CPU를 직렬화해 성능을 낮춘다.
호출자가 page를 직접 free하면 `mm_page_free`만 발생한다. 이 activity가 많으면 호출자가 작업을 batch해야 할 수 있다.
page를 batch로 free하면 `mm_page_free_batched`도 발생한다. page를 LRU lock 아래에서 대량으로 꺼낸 뒤 page list로 한꺼번에 free한다. 이 activity가 많으면 memory pressure나 `lruvec->lru_lock` contention을 뜻할 수 있다.
allocation source와 free 방식에 따른 진단 신호다.
per-CPU fast path와 buddy slow path를 구분한다.
직접 free와 batch free가 서로 다른 event를 만든다.
3. Page allocation
==================
::
mm_page_alloc page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s
mm_page_alloc_zone_locked page=%p pfn=%lu order=%u migratetype=%d cpu=%d percpu_refill=%d
mm_page_free page=%p pfn=%lu order=%d
mm_page_free_batched page=%p pfn=%lu order=%d cold=%d
These four events deal with page allocation and freeing. mm_page_alloc is
a simple indicator of page allocator activity. Pages may be allocated from
the per-CPU allocator (high performance) or the buddy allocator.
If pages are allocated directly from the buddy allocator, the
mm_page_alloc_zone_locked event is triggered. This event is important as high
amounts of activity imply high activity on the zone->lock. Taking this lock
impairs performance by disabling interrupts, dirtying cache lines between
CPUs and serialising many CPUs.
When a page is freed directly by the caller, the only mm_page_free event
is triggered. Significant amounts of activity here could indicate that the
callers should be batching their activities.
When pages are freed in batch, the also mm_page_free_batched is triggered.
Broadly speaking, pages are taken off the LRU lock in bulk and
freed in batch with a page list. Significant amounts of activity here could
indicate that the system is under memory pressure and can also indicate
contention on the lruvec->lru_lock.
Per-CPU allocator activity
74-102page allocator 앞에는 per-CPU page allocator가 있다. order-0 page에만 존재하며 `zone->lock` contention과 `struct page`에 대한 write 양을 줄인다.
per-CPU list가 비었거나 잘못된 type의 page가 요청되면 `zone->lock`을 한 번 잡고 list를 refill한다. 할당한 각 page마다 `mm_page_alloc_zone_locked`가 발생하고 `percpu_refill` field가 refill용인지 표시한다.
per-CPU list가 너무 가득 차면 여러 page를 free하고 각 page마다 `mm_page_pcpu_drain` event가 발생한다.
event를 page별로 남기는 이유는 allocation부터 free까지 page를 추적하기 위해서다. 연속된 여러 drain 또는 refill page는 `zone->lock`을 한 번 획득했다는 뜻이다.
refill과 drain이 많으면 work가 한 CPU에 몰린 imbalance이거나 per-CPU list를 더 크게 해야 한다는 신호일 수 있다. 한 CPU에서 refill이 많고 다른 CPU에서 drain이 많으면 CPU 사이 write로 cache line bounce가 커질 수 있다. algorithm을 바꿔 같은 CPU에서 page를 할당하고 free할 수 있는지 조사할 가치가 있다.
refill과 drain이 만드는 event를 정리한다.
list 수위에 따라 zone lock을 거쳐 page를 이동한다.
event 빈도와 CPU 분포로 allocator 문제를 추론한다.
4. Per-CPU Allocator Activity
=============================
::
mm_page_alloc_zone_locked page=%p pfn=%lu order=%u migratetype=%d cpu=%d percpu_refill=%d
mm_page_pcpu_drain page=%p pfn=%lu order=%d cpu=%d migratetype=%d
In front of the page allocator is a per-cpu page allocator. It exists only
for order-0 pages, reduces contention on the zone->lock and reduces the
amount of writing on struct page.
When a per-CPU list is empty or pages of the wrong type are allocated,
the zone->lock will be taken once and the per-CPU list refilled. The event
triggered is mm_page_alloc_zone_locked for each page allocated with the
event indicating whether it is for a percpu_refill or not.
When the per-CPU list is too full, a number of pages are freed, each one
which triggers a mm_page_pcpu_drain event.
The individual nature of the events is so that pages can be tracked
between allocation and freeing. A number of drain or refill pages that occur
consecutively imply the zone->lock being taken once. Large amounts of per-CPU
refills and drains could imply an imbalance between CPUs where too much work
is being concentrated in one place. It could also indicate that the per-CPU
lists should be a larger size. Finally, large amounts of refills on one CPU
and drains on another could be a factor in causing large amounts of cache
line bounces due to writes between CPUs and worth investigating if pages
can be allocated and freed on the same CPU through some algorithm change.
External fragmentation
103-119`mm_page_alloc_extfrag`는 요청 order, fallback order, pageblock order, 요청·fallback migratetype, fragmentation과 ownership change 여부를 기록한다.
external fragmentation은 high-order allocation 성공 여부에 영향을 준다. 일부 hardware에서 중요하며, huge page를 사용하면서 system 수명 동안 pool size를 바꿔야 할 때 특히 중요하다.
이 event가 많이 발생하면 memory가 조각나고 있어 앞으로 high-order allocation이 실패하기 시작할 수 있다는 뜻이다.
발생을 줄이는 한 방법은 `min_free_kbytes`를 `3*pageblock_size*nr_online_nodes` 단위로 늘리는 것이다. `pageblock_size`는 대개 기본 hugepage size다.
tracepoint field와 운영상 의미를 연결한다.
fragmentation event 증가가 미래 실패로 이어질 수 있다.
5. External Fragmentation
=========================
::
mm_page_alloc_extfrag page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d
External fragmentation affects whether a high-order allocation will be
successful or not. For some types of hardware, this is important although
it is avoided where possible. If the system is using huge pages and needs
to be able to resize the pool over the lifetime of the system, this value
is important.
Large numbers of this event implies that memory is fragmenting and
high-order allocations will start failing at some time in the future. One
means of reducing the occurrence of this event is to increase the size of
min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
pageblock_size is usually the size of the default hugepage size.
요약·해설
events-kmem.rst:1-119slab, page, per-CPU allocator와 external fragmentation을 관찰하는 kmem subsystem tracepoint의 의미와 진단 방법입니다.