← Documents Documentation/core-api/dma-attributes.rst GitHub 원문 ↗

Linux 6.18.37 · Core API

DMA attributes

DMA mapping의 ordering, write combining, CPU synchronization, physical continuity, warning, privilege 및 MMIO 동작을 제어하는 attribute의 의미를 설명합니다.

Source pathDocumentation/core-api/dma-attributes.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

dma-attributes.rst:1-150

DMA attribute는 generic DMA API의 기본 계약에 선택적인 platform별 의미를 더합니다. 구현하지 않은 optional attribute는 무시될 수 있으므로 driver는 attribute 없이도 정확성이 유지되는지 구분해야 합니다.

`DMA_ATTR_SKIP_CPU_SYNC`는 여러 device가 buffer를 공유할 때 중복 cache synchronization을 피하지만 ownership을 정확히 추적해야 합니다. `DMA_ATTR_FORCE_CONTIGUOUS`와 `DMA_ATTR_ALLOC_SINGLE_PAGES`는 서로 다른 allocation 목적을 나타냅니다.

`DMA_ATTR_MMIO`는 normal RAM이 아닌 peer device address를 위한 것으로 CPU cacheable mapping과 일반 page 변환 API를 금지합니다. PCI에서는 `p2pdma` API로 적합성을 확인해야 합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ==============
2 DMA attributes
3 ==============
4
5 This document describes the semantics of the DMA attributes that are
6 defined in linux/dma-mapping.h.
7
8 DMA_ATTR_WEAK_ORDERING
9 ----------------------
10
11 DMA_ATTR_WEAK_ORDERING specifies that reads and writes to the mapping
12 may be weakly ordered, that is that reads and writes may pass each other.
13
14 Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING,
15 those that do not will simply ignore the attribute and exhibit default
16 behavior.
17
18 DMA_ATTR_WRITE_COMBINE
19 ----------------------
20
21 DMA_ATTR_WRITE_COMBINE specifies that writes to the mapping may be
22 buffered to improve performance.
23
24 Since it is optional for platforms to implement DMA_ATTR_WRITE_COMBINE,
25 those that do not will simply ignore the attribute and exhibit default
26 behavior.
27
28 DMA_ATTR_NO_KERNEL_MAPPING
29 --------------------------
30
31 DMA_ATTR_NO_KERNEL_MAPPING lets the platform to avoid creating a kernel
32 virtual mapping for the allocated buffer. On some architectures creating
33 such mapping is non-trivial task and consumes very limited resources
34 (like kernel virtual address space or dma consistent address space).
35 Buffers allocated with this attribute can be only passed to user space
36 by calling dma_mmap_attrs(). By using this API, you are guaranteeing
37 that you won't dereference the pointer returned by dma_alloc_attr(). You
38 can treat it as a cookie that must be passed to dma_mmap_attrs() and
39 dma_free_attrs(). Make sure that both of these also get this attribute
40 set on each call.
41
42 Since it is optional for platforms to implement
43 DMA_ATTR_NO_KERNEL_MAPPING, those that do not will simply ignore the
44 attribute and exhibit default behavior.
45
46 DMA_ATTR_SKIP_CPU_SYNC
47 ----------------------
48
49 By default dma_map_{single,page,sg} functions family transfer a given
50 buffer from CPU domain to device domain. Some advanced use cases might
51 require sharing a buffer between more than one device. This requires
52 having a mapping created separately for each device and is usually
53 performed by calling dma_map_{single,page,sg} function more than once
54 for the given buffer with device pointer to each device taking part in
55 the buffer sharing. The first call transfers a buffer from 'CPU' domain
56 to 'device' domain, what synchronizes CPU caches for the given region
57 (usually it means that the cache has been flushed or invalidated
58 depending on the dma direction). However, next calls to
59 dma_map_{single,page,sg}() for other devices will perform exactly the
60 same synchronization operation on the CPU cache. CPU cache synchronization
61 might be a time consuming operation, especially if the buffers are
62 large, so it is highly recommended to avoid it if possible.
63 DMA_ATTR_SKIP_CPU_SYNC allows platform code to skip synchronization of
64 the CPU cache for the given buffer assuming that it has been already
65 transferred to 'device' domain. This attribute can be also used for
66 dma_unmap_{single,page,sg} functions family to force buffer to stay in
67 device domain after releasing a mapping for it. Use this attribute with
68 care!
69
70 DMA_ATTR_FORCE_CONTIGUOUS
71 -------------------------
72
73 By default DMA-mapping subsystem is allowed to assemble the buffer
74 allocated by dma_alloc_attrs() function from individual pages if it can
75 be mapped as contiguous chunk into device dma address space. By
76 specifying this attribute the allocated buffer is forced to be contiguous
77 also in physical memory.
78
79 DMA_ATTR_ALLOC_SINGLE_PAGES
80 ---------------------------
81
82 This is a hint to the DMA-mapping subsystem that it's probably not worth
83 the time to try to allocate memory to in a way that gives better TLB
84 efficiency (AKA it's not worth trying to build the mapping out of larger
85 pages). You might want to specify this if:
86
87 - You know that the accesses to this memory won't thrash the TLB.
88 You might know that the accesses are likely to be sequential or
89 that they aren't sequential but it's unlikely you'll ping-pong
90 between many addresses that are likely to be in different physical
91 pages.
92 - You know that the penalty of TLB misses while accessing the
93 memory will be small enough to be inconsequential. If you are
94 doing a heavy operation like decryption or decompression this
95 might be the case.
96 - You know that the DMA mapping is fairly transitory. If you expect
97 the mapping to have a short lifetime then it may be worth it to
98 optimize allocation (avoid coming up with large pages) instead of
99 getting the slight performance win of larger pages.
100
101 Setting this hint doesn't guarantee that you won't get huge pages, but it
102 means that we won't try quite as hard to get them.
103
104 .. note:: At the moment DMA_ATTR_ALLOC_SINGLE_PAGES is only implemented on ARM,
105 though ARM64 patches will likely be posted soon.
106
107 DMA_ATTR_NO_WARN
108 ----------------
109
110 This tells the DMA-mapping subsystem to suppress allocation failure reports
111 (similarly to __GFP_NOWARN).
112
113 On some architectures allocation failures are reported with error messages
114 to the system logs. Although this can help to identify and debug problems,
115 drivers which handle failures (eg, retry later) have no problems with them,
116 and can actually flood the system logs with error messages that aren't any
117 problem at all, depending on the implementation of the retry mechanism.
118
119 So, this provides a way for drivers to avoid those error messages on calls
120 where allocation failures are not a problem, and shouldn't bother the logs.
121
122 .. note:: At the moment DMA_ATTR_NO_WARN is only implemented on PowerPC.
123
124 DMA_ATTR_PRIVILEGED
125 -------------------
126
127 Some advanced peripherals such as remote processors and GPUs perform
128 accesses to DMA buffers in both privileged "supervisor" and unprivileged
129 "user" modes. This attribute is used to indicate to the DMA-mapping
130 subsystem that the buffer is fully accessible at the elevated privilege
131 level (and ideally inaccessible or at least read-only at the
132 lesser-privileged levels).
133
134 DMA_ATTR_MMIO
135 -------------
136
137 This attribute indicates the physical address is not normal system
138 memory. It may not be used with kmap*()/phys_to_virt()/phys_to_page()
139 functions, it may not be cacheable, and access using CPU load/store
140 instructions may not be allowed.
141
142 Usually this will be used to describe MMIO addresses, or other non-cacheable
143 register addresses. When DMA mapping this sort of address we call
144 the operation Peer to Peer as a one device is DMA'ing to another device.
145 For PCI devices the p2pdma APIs must be used to determine if
146 DMA_ATTR_MMIO is appropriate.
147
148 For architectures that require cache flushing for DMA coherence
149 DMA_ATTR_MMIO will not perform any cache flushing. The address
150 provided must never be mapped cacheable into the CPU.
151

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

DMA attribute 개요

1-7

DMA attributes (DMA 속성)

이 문서는 `linux/dma-mapping.h`에 정의된 DMA attribute의 의미를 설명합니다.

DMA_ATTR_WEAK_ORDERING

8-17

`DMA_ATTR_WEAK_ORDERING`

`DMA_ATTR_WEAK_ORDERING`은 mapping에 대한 read와 write가 weakly ordered일 수 있음을 지정합니다. 즉 read와 write가 서로 앞질러 실행될 수 있습니다.

Platform의 `DMA_ATTR_WEAK_ORDERING` 구현은 optional입니다. 구현하지 않은 platform은 attribute를 무시하고 기본 동작을 보입니다.

DMA_ATTR_WRITE_COMBINE

18-27

`DMA_ATTR_WRITE_COMBINE`

`DMA_ATTR_WRITE_COMBINE`은 성능 향상을 위해 mapping으로 향하는 write를 buffer에 모을 수 있음을 지정합니다.

Platform의 `DMA_ATTR_WRITE_COMBINE` 구현은 optional입니다. 구현하지 않은 platform은 attribute를 무시하고 기본 동작을 보입니다.

DMA_ATTR_NO_KERNEL_MAPPING

28-45

`DMA_ATTR_NO_KERNEL_MAPPING`

`DMA_ATTR_NO_KERNEL_MAPPING`은 allocate한 buffer에 대한 kernel virtual mapping 생성을 platform이 피할 수 있게 합니다. 일부 architecture에서 이런 mapping은 간단하지 않고 kernel virtual address space나 DMA consistent address space 같은 매우 제한적인 resource를 소비합니다.

이 attribute로 allocate한 buffer는 `dma_mmap_attrs()`를 호출해야만 user space에 전달할 수 있습니다. 이 API를 사용하면 `dma_alloc_attr()`가 반환한 pointer를 dereference하지 않겠다고 보장하는 것입니다. Pointer는 `dma_mmap_attrs()`와 `dma_free_attrs()`에 전달해야 하는 cookie로 취급하고 두 호출에도 항상 이 attribute를 설정해야 합니다.

이 attribute 역시 optional이므로 구현하지 않은 platform은 무시하고 기본 동작을 사용합니다.

DMA_ATTR_SKIP_CPU_SYNC

46-69

`DMA_ATTR_SKIP_CPU_SYNC`

기본적으로 `dma_map_{single,page,sg}` 함수군은 주어진 buffer를 CPU domain에서 device domain으로 이전합니다. 여러 device가 한 buffer를 공유하는 고급 용도에서는 참여 device마다 별도 mapping을 만들어 같은 buffer에 각 device pointer로 mapping 함수를 여러 번 호출합니다.

첫 호출은 buffer를 CPU domain에서 device domain으로 옮기며 DMA direction에 따라 해당 region의 CPU cache를 flush 또는 invalidate합니다. 다른 device를 위한 다음 호출도 같은 CPU cache synchronization을 반복합니다. 큰 buffer에서는 시간이 많이 들 수 있으므로 가능하면 피하는 것이 좋습니다.

`DMA_ATTR_SKIP_CPU_SYNC`는 buffer가 이미 device domain으로 이전되었다고 가정하고 platform code가 CPU cache synchronization을 생략하도록 합니다. `dma_unmap_{single,page,sg}` 함수군에도 사용하여 mapping 해제 뒤 buffer가 device domain에 남도록 강제할 수 있습니다. 매우 주의해서 사용해야 합니다.

DMA_ATTR_FORCE_CONTIGUOUS

70-78

`DMA_ATTR_FORCE_CONTIGUOUS`

기본적으로 DMA-mapping subsystem은 `dma_alloc_attrs()`가 allocate하는 buffer를 device DMA address space에서 contiguous chunk로 mapping할 수 있다면 개별 page를 조립해 만들 수 있습니다. 이 attribute를 지정하면 allocate한 buffer가 physical memory에서도 연속되도록 강제합니다.

DMA_ATTR_ALLOC_SINGLE_PAGES

79-106

`DMA_ATTR_ALLOC_SINGLE_PAGES`

이 attribute는 더 나은 TLB 효율을 위해 큰 page로 mapping을 구성하려고 시간을 들이는 것이 가치 없을 가능성이 높다는 hint입니다. 다음 상황에서 지정할 수 있습니다.

  • 이 memory 접근이 TLB thrashing을 일으키지 않음을 알고 있는 경우입니다. 접근이 sequential하거나, 비순차적이어도 서로 다른 physical page에 있을 법한 많은 address 사이를 오갈 가능성이 낮을 수 있습니다.
  • Memory 접근 중 TLB miss penalty가 무시할 만큼 작음을 아는 경우입니다. Decryption이나 decompression 같은 무거운 operation이 이에 해당할 수 있습니다.
  • DMA mapping 수명이 상당히 짧다고 아는 경우입니다. 큰 page의 소폭 성능 향상보다 큰 page를 만들지 않아 allocation을 최적화하는 편이 나을 수 있습니다.

이 hint를 설정해도 huge page를 절대 받지 않는다는 보장은 없지만, subsystem이 이를 얻기 위해 큰 노력을 기울이지 않게 합니다.

현재 `DMA_ATTR_ALLOC_SINGLE_PAGES`는 ARM에서만 구현되어 있으며 ARM64 patch도 곧 제출될 가능성이 있습니다.

DMA_ATTR_NO_WARN

107-123

`DMA_ATTR_NO_WARN`

`DMA_ATTR_NO_WARN`은 `__GFP_NOWARN`과 비슷하게 DMA-mapping subsystem이 allocation failure report를 억제하도록 합니다.

일부 architecture는 allocation failure를 system log의 error message로 보고합니다. 문제 식별에는 도움이 되지만 실패를 나중에 재시도하는 등 정상 처리하는 driver에서는 retry 구현에 따라 실제 문제가 아닌 message로 log를 가득 채울 수 있습니다.

따라서 allocation failure가 문제가 아니고 log를 방해할 필요가 없는 호출에서 driver가 error message를 피할 수 있게 합니다.

현재 `DMA_ATTR_NO_WARN`은 PowerPC에서만 구현되어 있습니다.

DMA_ATTR_PRIVILEGED

124-133

`DMA_ATTR_PRIVILEGED`

Remote processor와 GPU 같은 일부 고급 peripheral은 privileged `supervisor` mode와 unprivileged `user` mode 모두에서 DMA buffer에 접근합니다. 이 attribute는 높은 privilege level에서 buffer 전체에 접근할 수 있고, 낮은 privilege level에서는 이상적으로 접근 불가이거나 최소한 read-only임을 DMA-mapping subsystem에 알립니다.

DMA_ATTR_MMIO

134-150

`DMA_ATTR_MMIO`

이 attribute는 physical address가 normal system memory가 아님을 나타냅니다. `kmap*()`, `phys_to_virt()`, `phys_to_page()`와 함께 사용할 수 없고 cacheable하지 않을 수 있으며 CPU load/store instruction 접근이 허용되지 않을 수도 있습니다.

보통 MMIO address나 그 밖의 non-cacheable register address를 설명할 때 사용합니다. 한 device가 다른 device로 DMA하는 이런 address mapping을 Peer to Peer operation이라 합니다. PCI device는 `DMA_ATTR_MMIO`가 적절한지 판단할 때 `p2pdma` API를 사용해야 합니다.

DMA coherency를 위해 cache flush가 필요한 architecture에서도 `DMA_ATTR_MMIO`는 cache flush를 수행하지 않습니다. 제공된 address를 CPU에 cacheable하게 mapping해서는 절대 안 됩니다.