요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
API
atomic_bitops.txt:9-32단일 bit API는 값을 읽기만 하는 non-RMW operation, bit를 읽고 수정하는 RMW operation, ordering을 보강하는 barrier로 나뉜다.
Non-RMW operation
test_bit()
test_bit()는 대상 bit를 읽지만 그 값을 변경하지 않는다. 따라서 read-modify-write가 아니며, 그 자체만으로 다른 memory access의 순서를 강제하지 않는다.
반환값이 없는 RMW atomic operation
{set,clear,change}_bit()
clear_bit_unlock()
set_bit(), clear_bit(), change_bit()는 각각 bit를 1로 설정하고, 0으로 지우고, 현재 값을 반전한다. clear_bit_unlock()은 bit를 지우는 동작에 RELEASE ordering을 결합한 unlock 전용 operation이다.
원래 값을 반환하는 RMW atomic operation
test_and_{set,clear,change}_bit()
test_and_set_bit_lock()
test_and_* 함수는 bit를 변경하면서 변경 전 값을 반환한다. 호출자는 반환값으로 자신이 처음 상태를 바꾼 CPU인지 판단할 수 있다. test_and_set_bit_lock()은 lock 획득에 맞춘 ACQUIRE operation이다.
Barrier
smp_mb__before_atomic()
smp_mb__after_atomic()
__ 접두사가 붙는 non-atomic variant
atomic_bitops.txt:34-35모든 RMW atomic bit operation에는 이름 앞에 __가 붙는 non-atomic variant가 있다. 예를 들어 set_bit()에 대응하는 __set_bit()가 있다. 이 함수들은 caller가 이미 lock이나 CPU-local 조건으로 동시 접근을 막았을 때만 사용해야 한다.
동작 의미
atomic_bitops.txt:38-50__clear_bit_unlock()에는 atomic_set()과 같은 종류의 문제가 있다. 다른 CPU의 atomic RMW와 경쟁할 때 단순 store가 RMW의 atomicity를 깨뜨려서는 안 된다. 그래서 generic implementation은 atomic한 clear_bit_unlock()으로 연결된다. 자세한 배경은 atomic_t.txt가 설명한다.
test_and_{}_bit() 계열의 반환값은 operation이 끝난 뒤의 값이 아니라 변경하기 전 bit 값이다. 예를 들어 test_and_set_bit()가 0을 반환했다면 이 호출이 0에서 1로 바꾼 호출이다.
Memory ordering
atomic_bitops.txt:53-72atomic_t와 같은 기본 규칙을 적용한다. 여기서 unordered는 대상 bit 자체의 atomicity가 없다는 뜻이 아니라, 다른 memory location에 대한 load/store 순서를 추가로 보장하지 않는다는 뜻이다.
| Operation | Ordering |
|---|---|
| non-RMW operation | unordered |
| 반환값이 없는 RMW operation | unordered |
| 반환값이 있는 RMW operation | fully ordered |
| 조건부 RMW operation | fully ordered |
예외가 세 가지 있다. 성공한 test_and_set_bit_lock()과 test_bit_acquire()는 ACQUIRE semantics를 가지며, clear_bit_unlock()은 RELEASE semantics를 가진다.
architecture는 보통 atomic operation을 구현하는 공통 하드웨어 수단을 사용하므로 atomic_t와 같은 smp_mb__before_atomic(), smp_mb__after_atomic() barrier를 사용한다.
Lock bit에서 ACQUIRE와 RELEASE가 필요한 이유
atomic_bitops.txt:53-72/* CPU 0: lock을 얻은 뒤 protected data를 읽는다. */
while (test_and_set_bit_lock(LOCKED, &state))
cpu_relax();
value = READ_ONCE(shared_data);
/* CPU 1: data 갱신을 먼저 공개하고 lock bit를 지운다. */
WRITE_ONCE(shared_data, new_value);
clear_bit_unlock(LOCKED, &state);
CPU 1의 RELEASE는 shared_data store가 lock 해제 뒤로 밀리지 않게 한다. CPU 0의 ACQUIRE는 lock 획득 뒤의 shared_data load가 lock 획득 앞으로 당겨지지 않게 한다. 이 쌍으로 임계 구역 안의 값이 다음 lock 소유자에게 전달된다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=============
Atomic bitops
=============
While our bitmap_{}() functions are non-atomic, we have a number of operations
operating on single bits in a bitmap that are atomic.
API
---
The single bit operations are:
Non-RMW ops:
test_bit()
RMW atomic operations without return value:
{set,clear,change}_bit()
clear_bit_unlock()
RMW atomic operations with return value:
test_and_{set,clear,change}_bit()
test_and_set_bit_lock()
Barriers:
smp_mb__{before,after}_atomic()
All RMW atomic operations have a '__' prefixed variant which is non-atomic.
SEMANTICS
---------
Non-atomic ops:
In particular __clear_bit_unlock() suffers the same issue as atomic_set(),
which is why the generic version maps to clear_bit_unlock(), see atomic_t.txt.
RMW ops:
The test_and_{}_bit() operations return the original value of the bit.
ORDERING
--------
Like with atomic_t, the rule of thumb is:
- non-RMW operations are unordered;
- RMW operations that have no return value are unordered;
- RMW operations that have a return value are fully ordered.
- RMW operations that are conditional are fully ordered.
Except for a successful test_and_set_bit_lock() which has ACQUIRE semantics,
clear_bit_unlock() which has RELEASE semantics and test_bit_acquire which has
ACQUIRE semantics.
Since a platform only has a single means of achieving atomic operations
the same barriers as for atomic_t are used, see atomic_t.txt.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Atomic bit operation API
1-31bitmap_{}() function은 non-atomic이지만 bitmap의 bit 하나를 대상으로 동작하는 여러 atomic operation도 제공한다.
- Non-RMW operation: test_bit()
- 반환값이 없는 RMW atomic operation: set_bit(), clear_bit(), change_bit(), clear_bit_unlock()
- 반환값이 있는 RMW atomic operation: test_and_set_bit(), test_and_clear_bit(), test_and_change_bit(), test_and_set_bit_lock()
- Barrier: smp_mb__before_atomic(), smp_mb__after_atomic()
모든 RMW atomic operation에는 이름 앞에 __가 붙는 non-atomic variant가 있다.
Semantics
33-45Non-atomic operation 가운데 특히 __clear_bit_unlock()은 atomic_set()과 같은 문제를 갖는다. 이 때문에 generic implementation은 clear_bit_unlock()으로 mapping된다. 자세한 내용은 atomic_t.txt를 참조한다.
test_and_{}_bit() RMW operation은 bit의 변경 전 원래 값을 반환한다.
Memory ordering
47-69atomic_t와 마찬가지로 기본 ordering 규칙은 다음과 같다.
- Non-RMW operation은 unordered다.
- 반환값이 없는 RMW operation은 unordered다.
- 반환값이 있는 RMW operation은 fully ordered다.
- Conditional RMW operation은 fully ordered다.
예외적으로 성공한 test_and_set_bit_lock()은 ACQUIRE semantics, clear_bit_unlock()은 RELEASE semantics, test_bit_acquire()는 ACQUIRE semantics를 갖는다.
Platform은 atomic operation을 달성하는 단일 mechanism을 사용하므로 atomic_t와 같은 barrier를 사용한다. 자세한 내용은 atomic_t.txt를 참조한다.
개요
atomic_bitops.txt:1-7일반적인 bitmap_{}() 함수는 atomic하지 않다. 반면 bitmap 안의 단일 bit를 대상으로 하는 일부 함수는 다른 CPU와 경쟁해도 갱신이 분리되지 않도록 atomic operation을 제공한다.
여기서 atomic은 단순히 compiler가 한 명령으로 만든다는 뜻이 아니다. 같은 memory location을 갱신하는 CPU 사이에서 read-modify-write가 하나의 분리 불가능한 동작으로 관측되어야 한다는 뜻이다.