요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===========================
InfiniBand Midlayer Locking
===========================
This guide is an attempt to make explicit the locking assumptions
made by the InfiniBand midlayer. It describes the requirements on
both low-level drivers that sit below the midlayer and upper level
protocols that use the midlayer.
Sleeping and interrupt context
==============================
With the following exceptions, a low-level driver implementation of
all of the methods in struct ib_device may sleep. The exceptions
are any methods from the list:
- create_ah
- modify_ah
- query_ah
- destroy_ah
- post_send
- post_recv
- poll_cq
- req_notify_cq
which may not sleep and must be callable from any context.
The corresponding functions exported to upper level protocol
consumers:
- rdma_create_ah
- rdma_modify_ah
- rdma_query_ah
- rdma_destroy_ah
- ib_post_send
- ib_post_recv
- ib_req_notify_cq
are therefore safe to call from any context.
In addition, the function
- ib_dispatch_event
used by low-level drivers to dispatch asynchronous events through
the midlayer is also safe to call from any context.
Reentrancy
----------
All of the methods in struct ib_device exported by a low-level
driver must be fully reentrant. The low-level driver is required to
perform all synchronization necessary to maintain consistency, even
if multiple function calls using the same object are run
simultaneously.
The IB midlayer does not perform any serialization of function calls.
Because low-level drivers are reentrant, upper level protocol
consumers are not required to perform any serialization. However,
some serialization may be required to get sensible results. For
example, a consumer may safely call ib_poll_cq() on multiple CPUs
simultaneously. However, the ordering of the work completion
information between different calls of ib_poll_cq() is not defined.
Callbacks
---------
A low-level driver must not perform a callback directly from the
same callchain as an ib_device method call. For example, it is not
allowed for a low-level driver to call a consumer's completion event
handler directly from its post_send method. Instead, the low-level
driver should defer this callback by, for example, scheduling a
tasklet to perform the callback.
The low-level driver is responsible for ensuring that multiple
completion event handlers for the same CQ are not called
simultaneously. The driver must guarantee that only one CQ event
handler for a given CQ is running at a time. In other words, the
following situation is not allowed::
CPU1 CPU2
low-level driver ->
consumer CQ event callback:
/* ... */
ib_req_notify_cq(cq, ...);
low-level driver ->
/* ... */ consumer CQ event callback:
/* ... */
return from CQ event handler
The context in which completion event and asynchronous event
callbacks run is not defined. Depending on the low-level driver, it
may be process context, softirq context, or interrupt context.
Upper level protocol consumers may not sleep in a callback.
Hot-plug
--------
A low-level driver announces that a device is ready for use by
consumers when it calls ib_register_device(), all initialization
must be complete before this call. The device must remain usable
until the driver's call to ib_unregister_device() has returned.
A low-level driver must call ib_register_device() and
ib_unregister_device() from process context. It must not hold any
semaphores that could cause deadlock if a consumer calls back into
the driver across these calls.
An upper level protocol consumer may begin using an IB device as
soon as the add method of its struct ib_client is called for that
device. A consumer must finish all cleanup and free all resources
relating to a device before returning from the remove method.
A consumer is permitted to sleep in its add and remove methods.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
InfiniBand midlayer 잠금 가정
1-9이 안내서는 InfiniBand midlayer가 전제로 하는 잠금 가정을 명시하려는 문서입니다.
Midlayer 아래에 위치한 low-level driver와 midlayer를 사용하는 upper-level protocol 양쪽에 대한 요구사항을 설명합니다.
Midlayer 위·아래 구성요소의 역할을 구분합니다.
===========================
InfiniBand Midlayer Locking
===========================
This guide is an attempt to make explicit the locking assumptions
made by the InfiniBand midlayer. It describes the requirements on
both low-level drivers that sit below the midlayer and upper level
protocols that use the midlayer.
Sleep 가능 여부와 호출 context
10-47아래 예외를 제외하면 low-level driver가 구현한 `struct ib_device`의 모든 method는 sleep할 수 있습니다.
어떤 context에서도 호출 가능해야 하는 여덟 method입니다.
이 여덟 method는 sleep하면 안 되며 어떤 context에서도 호출할 수 있어야 합니다.
이에 대응해 upper-level protocol consumer에 export되는 함수도 어떤 context에서나 안전하게 호출할 수 있습니다.
Low-level non-sleeping method에 대응하는 일곱 consumer API입니다.
Low-level driver가 midlayer를 통해 asynchronous event를 dispatch하는 데 사용하는 `ib_dispatch_event`도 어떤 context에서나 안전하게 호출할 수 있습니다.
Sleep 가능 여부를 method별로 판단하는 흐름입니다.
Sleeping and interrupt context
==============================
With the following exceptions, a low-level driver implementation of
all of the methods in struct ib_device may sleep. The exceptions
are any methods from the list:
- create_ah
- modify_ah
- query_ah
- destroy_ah
- post_send
- post_recv
- poll_cq
- req_notify_cq
which may not sleep and must be callable from any context.
The corresponding functions exported to upper level protocol
consumers:
- rdma_create_ah
- rdma_modify_ah
- rdma_query_ah
- rdma_destroy_ah
- ib_post_send
- ib_post_recv
- ib_req_notify_cq
are therefore safe to call from any context.
In addition, the function
- ib_dispatch_event
used by low-level drivers to dispatch asynchronous events through
the midlayer is also safe to call from any context.
완전한 재진입성과 호출 순서
48-65Low-level driver가 export하는 `struct ib_device`의 모든 method는 완전하게 reentrant해야 합니다.
같은 객체를 사용하는 여러 함수 호출이 동시에 실행되더라도 일관성을 유지하는 데 필요한 모든 synchronization은 low-level driver가 수행해야 합니다.
IB midlayer는 함수 호출을 전혀 직렬화하지 않습니다.
Low-level driver가 reentrant하므로 upper-level protocol consumer는 serialization을 수행할 의무가 없습니다. 다만 의미 있는 결과를 얻기 위해 일부 직렬화가 필요할 수 있습니다.
예를 들어 consumer는 여러 CPU에서 `ib_poll_cq()`를 동시에 호출해도 안전하지만, 서로 다른 `ib_poll_cq()` 호출이 반환하는 work completion 정보의 순서는 정의되어 있지 않습니다.
안전성 책임과 결과 순서 보장 여부를 구분합니다.
같은 객체에 대한 병렬 호출이 처리되는 원칙입니다.
Reentrancy
----------
All of the methods in struct ib_device exported by a low-level
driver must be fully reentrant. The low-level driver is required to
perform all synchronization necessary to maintain consistency, even
if multiple function calls using the same object are run
simultaneously.
The IB midlayer does not perform any serialization of function calls.
Because low-level drivers are reentrant, upper level protocol
consumers are not required to perform any serialization. However,
some serialization may be required to get sensible results. For
example, a consumer may safely call ib_poll_cq() on multiple CPUs
simultaneously. However, the ordering of the work completion
information between different calls of ib_poll_cq() is not defined.
Callback 지연·CQ 직렬화·실행 context
66-97Low-level driver는 `ib_device` method 호출과 같은 callchain에서 callback을 직접 실행하면 안 됩니다.
예를 들어 `post_send` method에서 consumer의 completion event handler를 직접 호출할 수 없습니다. 대신 tasklet을 schedule하는 등의 방법으로 callback을 지연해야 합니다.
같은 callchain의 직접 callback을 피하는 흐름입니다.
Low-level driver는 같은 CQ에 대한 여러 completion event handler가 동시에 호출되지 않도록 해야 합니다. 특정 CQ에서는 언제나 CQ event handler 하나만 실행 중이어야 합니다.
원문의 CPU1/CPU2 ASCII 타임라인을 단계별 병렬 표로 재구성했습니다.
위 표처럼 CPU1의 handler가 반환하기 전에 CPU2에서 같은 CQ의 handler가 시작되는 상황은 허용되지 않습니다.
Completion event와 asynchronous event callback이 실행되는 context는 정의되어 있지 않습니다. Low-level driver에 따라 process context, softirq context, interrupt context일 수 있습니다.
Upper-level protocol consumer는 callback 안에서 sleep하면 안 됩니다.
실행 가능한 context와 consumer 제약입니다.
Callbacks
---------
A low-level driver must not perform a callback directly from the
same callchain as an ib_device method call. For example, it is not
allowed for a low-level driver to call a consumer's completion event
handler directly from its post_send method. Instead, the low-level
driver should defer this callback by, for example, scheduling a
tasklet to perform the callback.
The low-level driver is responsible for ensuring that multiple
completion event handlers for the same CQ are not called
simultaneously. The driver must guarantee that only one CQ event
handler for a given CQ is running at a time. In other words, the
following situation is not allowed::
CPU1 CPU2
low-level driver ->
consumer CQ event callback:
/* ... */
ib_req_notify_cq(cq, ...);
low-level driver ->
/* ... */ consumer CQ event callback:
/* ... */
return from CQ event handler
The context in which completion event and asynchronous event
callbacks run is not defined. Depending on the low-level driver, it
may be process context, softirq context, or interrupt context.
Upper level protocol consumers may not sleep in a callback.
장치 등록·해제와 consumer 정리
98-116Low-level driver는 `ib_register_device()`를 호출할 때 consumer에게 장치 사용 준비가 끝났음을 알립니다. 이 호출 전에 모든 초기화를 완료해야 합니다.
장치는 driver의 `ib_unregister_device()` 호출이 반환할 때까지 계속 사용할 수 있어야 합니다.
Low-level driver는 `ib_register_device()`와 `ib_unregister_device()`를 process context에서 호출해야 합니다.
이 호출 구간에서 consumer가 driver로 callback할 때 deadlock을 일으킬 수 있는 semaphore를 잡고 있으면 안 됩니다.
Upper-level protocol consumer는 해당 장치에 대해 `struct ib_client`의 `add` method가 호출되는 즉시 IB 장치를 사용할 수 있습니다.
Consumer는 `remove` method에서 반환하기 전에 장치와 관련된 모든 정리를 끝내고 모든 resource를 해제해야 합니다.
Consumer는 `add`와 `remove` method 안에서 sleep할 수 있습니다.
Driver와 consumer의 수명 주기 책임을 비교합니다.
초기화부터 consumer 정리와 unregister 완료까지의 순서입니다.
Hot-plug
--------
A low-level driver announces that a device is ready for use by
consumers when it calls ib_register_device(), all initialization
must be complete before this call. The device must remain usable
until the driver's call to ib_unregister_device() has returned.
A low-level driver must call ib_register_device() and
ib_unregister_device() from process context. It must not hold any
semaphores that could cause deadlock if a consumer calls back into
the driver across these calls.
An upper level protocol consumer may begin using an IB device as
soon as the add method of its struct ib_client is called for that
device. A consumer must finish all cleanup and free all resources
relating to a device before returning from the remove method.
A consumer is permitted to sleep in its add and remove methods.
요약·해설
core_locking.rst:1-116InfiniBand midlayer는 호출을 직렬화하지 않으므로 low-level driver가 완전한 재진입성과 동기화를 보장해야 합니다. 일부 method는 어떤 context에서도 호출 가능해야 하고, 같은 CQ callback은 동시에 실행할 수 없으며, 등록·해제 경계에서 driver와 consumer의 resource 수명이 엄격히 이어져야 합니다.
원문 분량과 핵심 대상을 요약합니다.
적용 순서를 압축합니다.