요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
==================================
Long running workloads and compute
==================================
Long running workloads (compute) are workloads that will not complete in 10
seconds. (The time let the user wait before he reaches for the power button).
This means that other techniques need to be used to manage those workloads,
that cannot use fences.
Some hardware may schedule compute jobs, and have no way to pre-empt them, or
have their memory swapped out from them. Or they simply want their workload
not to be preempted or swapped out at all.
This means that it differs from what is described in driver-api/dma-buf.rst.
As with normal compute jobs, dma-fence may not be used at all. In this case,
not even to force preemption. The driver with is simply forced to unmap a BO
from the long compute job's address space on unbind immediately, not even
waiting for the workload to complete. Effectively this terminates the workload
when there is no hardware support to recover.
Since this is undesirable, there need to be mitigations to prevent a workload
from being terminated. There are several possible approach, all with their
advantages and drawbacks.
The first approach you will likely try is to pin all buffers used by compute.
This guarantees that the job will run uninterrupted, but also allows a very
denial of service attack by pinning as much memory as possible, hogging the
all GPU memory, and possibly a huge chunk of CPU memory.
A second approach that will work slightly better on its own is adding an option
not to evict when creating a new job (any kind). If all of userspace opts in
to this flag, it would prevent cooperating userspace from forced terminating
older compute jobs to start a new one.
If job preemption and recoverable pagefaults are not available, those are the
only approaches possible. So even with those, you want a separate way of
controlling resources. The standard kernel way of doing so is cgroups.
This creates a third option, using cgroups to prevent eviction. Both GPU and
driver-allocated CPU memory would be accounted to the correct cgroup, and
eviction would be made cgroup aware. This allows the GPU to be partitioned
into cgroups, that will allow jobs to run next to each other without
interference.
The interface to the cgroup would be similar to the current CPU memory
interface, with similar semantics for min/low/high/max, if eviction can
be made cgroup aware.
What should be noted is that each memory region (tiled memory for example)
should have its own accounting.
The key is set to the regionid set by the driver, for example "tile0".
For the value of $card, we use drmGetUnique().
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
장시간 실행 workload와 hardware 제약
1-15장시간 실행 workload(compute)는 10초 안에 완료되지 않는 workload를 말합니다. 10초는 사용자가 기다리다가 전원 버튼에 손을 뻗기까지의 시간을 빗댄 기준입니다. 이런 workload에는 fence를 사용할 수 없으므로 다른 관리 기법이 필요합니다.
일부 hardware는 compute job을 schedule할 수는 있지만 실행 중인 job을 preempt하거나 그 job의 memory를 swap out할 방법이 없습니다. 또는 workload 자체가 preempt되거나 swap out되는 것을 전혀 원하지 않을 수도 있습니다.
따라서 이 경우의 동작은 `driver-api/dma-buf.rst`에 설명된 방식과 다릅니다.
원문 5–15줄에서 일반 workload와 달라지는 조건을 정리합니다.
==================================
Long running workloads and compute
==================================
Long running workloads (compute) are workloads that will not complete in 10
seconds. (The time let the user wait before he reaches for the power button).
This means that other techniques need to be used to manage those workloads,
that cannot use fences.
Some hardware may schedule compute jobs, and have no way to pre-empt them, or
have their memory swapped out from them. Or they simply want their workload
not to be preempted or swapped out at all.
This means that it differs from what is described in driver-api/dma-buf.rst.
Unbind 시 BO 회수와 workload 종료
16-27일반 compute job과 마찬가지로 `dma-fence`를 전혀 사용하지 않을 수 있으며, 이 경우에는 preemption을 강제하기 위한 용도로도 사용할 수 없습니다. 그러면 unbind 시 driver는 장시간 compute job의 address space에서 BO를 즉시 unmap해야 하고 workload가 끝날 때까지 기다릴 수도 없습니다. 복구를 지원하는 hardware가 없다면 이 동작은 사실상 workload를 종료합니다.
Workload 종료는 바람직하지 않으므로 이를 막을 완화책이 필요합니다. 가능한 접근법은 여러 가지이며 각각 장점과 단점이 있습니다.
Fence와 hardware 복구가 없는 경우의 연쇄 동작입니다.
As with normal compute jobs, dma-fence may not be used at all. In this case,
not even to force preemption. The driver with is simply forced to unmap a BO
from the long compute job's address space on unbind immediately, not even
waiting for the workload to complete. Effectively this terminates the workload
when there is no hardware support to recover.
Since this is undesirable, there need to be mitigations to prevent a workload
from being terminated. There are several possible approach, all with their
advantages and drawbacks.
The first approach you will likely try is to pin all buffers used by compute.
This guarantees that the job will run uninterrupted, but also allows a very
Buffer pinning과 no-evict 선택지
28-40가장 먼저 시도할 가능성이 높은 방법은 compute가 사용하는 모든 buffer를 pin하는 것입니다. 이렇게 하면 job이 중단 없이 실행되는 것은 보장하지만, 가능한 한 많은 memory를 pin해 모든 GPU memory와 CPU memory의 큰 부분까지 독점하는 심각한 denial-of-service 공격을 허용할 수 있습니다.
두 번째 방법은 새 job을 만들 때, job 종류와 관계없이 기존 allocation을 evict하지 않도록 하는 option을 추가하는 것입니다. 모든 userspace가 이 flag 사용에 동의하면 서로 협력하는 userspace가 새 job을 시작하려고 오래된 compute job을 강제로 종료하는 일을 막을 수 있습니다.
두 접근법이 제공하는 보호와 남는 위험을 비교합니다.
denial of service attack by pinning as much memory as possible, hogging the
all GPU memory, and possibly a huge chunk of CPU memory.
A second approach that will work slightly better on its own is adding an option
not to evict when creating a new job (any kind). If all of userspace opts in
to this flag, it would prevent cooperating userspace from forced terminating
older compute jobs to start a new one.
If job preemption and recoverable pagefaults are not available, those are the
only approaches possible. So even with those, you want a separate way of
controlling resources. The standard kernel way of doing so is cgroups.
This creates a third option, using cgroups to prevent eviction. Both GPU and
Cgroup 기반 eviction과 region별 accounting
41-54Job preemption과 복구 가능한 page fault를 사용할 수 없다면 앞의 두 방법이 가능한 유일한 로컬 접근법입니다. 그러나 이 방법들을 사용하더라도 별도의 resource control이 필요하며, kernel의 표준 수단은 `cgroups`입니다.
세 번째 선택지는 cgroup을 사용해 eviction을 막는 것입니다. GPU memory와 driver가 할당한 CPU memory를 올바른 cgroup에 account하고 eviction이 cgroup을 인식하도록 만듭니다. 그러면 GPU를 cgroup 단위로 분할해 job들이 서로 방해하지 않고 나란히 실행되게 할 수 있습니다.
Cgroup interface는 현재 CPU memory interface와 비슷하며, eviction을 cgroup-aware하게 만들 수 있다면 `min/low/high/max`와 유사한 의미 체계를 사용합니다.
각 memory region, 예를 들어 tiled memory는 자체 accounting을 가져야 한다는 점에 유의해야 합니다.
Key에는 driver가 설정한 `regionid`를 사용하며 예시는 `"tile0"`입니다. `$card` 값에는 `drmGetUnique()`의 반환값을 사용합니다.
원문이 요구하는 accounting 단위와 식별값입니다.
driver-allocated CPU memory would be accounted to the correct cgroup, and
eviction would be made cgroup aware. This allows the GPU to be partitioned
into cgroups, that will allow jobs to run next to each other without
interference.
The interface to the cgroup would be similar to the current CPU memory
interface, with similar semantics for min/low/high/max, if eviction can
be made cgroup aware.
What should be noted is that each memory region (tiled memory for example)
should have its own accounting.
The key is set to the regionid set by the driver, for example "tile0".
For the value of $card, we use drmGetUnique().
요약·해설
drm-compute.rst:1-5410초 이상 실행되는 GPU compute workload가 preemption·swap-out·fence를 사용할 수 없을 때 BO unbind가 workload 종료로 이어지는 이유와 세 가지 완화 방향을 설명합니다. Buffer pinning과 no-evict option의 한계를 짚고, 장기적으로는 GPU·CPU memory를 region별로 account하는 cgroup-aware eviction을 제안합니다.
Workload 종료를 방지하는 접근법의 역할을 요약합니다.