안녕하세요? 15기 코딩의 노예입니다.
RCU lock에 관해서 여쭙고 싶은 것이, multi writer가 존재할 때 어떻게 동작하는 지 알고싶어서 글을 쓰게 되었습니다.
찾아봐도 multi reader와 single writer의 관계의 설명밖에 잘 나오지 않는 것 같아서 여쭤봅니다.
Reader가 lock해제를 안 했을 때, writer가 data를 write하게 되면 copy해놨다가 GP(Grace period) 이후에 Reclaim한다고 알고 있습니다.
그런데 GP 기간동안 writer가 둘, 셋 이상 write를 하게 되면 어떻게 동작하는 지 알고 싶습니다.
예를 들어,
1st writer의 write가 끝나서 original을 copy 후, GP구간에 돌입합니다. 이 때, 모든 Reader의 QS(Quiescent State)가 발동하기 전에 2nd writer가 write를 수행할 때, 1st writer의 copied data를 또 copy 하게 되는 건가요?
두번 째 예는,
1st write가 write를 시작하고, write가 끝나기 전에 2nd writer가 write를 시작하게 된다면, 두 writer가 모두 original data를 copy하였을 텐데, 이 경우 reclaim 구간에서 update가 어떻게 진행되는 지 궁금합니다.
일단은 보장해주는 매커니즘이 없어서 writer간의 동기화는 안 하는 것으로 이해하고 있습니다. 맞을까요?
감사합니다.
댓글 2
.
안녕하세요? 문c 블로그(http://jake.dothome.co.kr)의 문영일입니다.
rcu를 통해 object를 읽거나 갱신하는 것에 대해,
write 동작의 사용 빈도가 극히 적고,
read 동작 사용 빈도가 매우 큰 경우에 rcu를 사용하잖아요?
multi wirter를 해야하는 경우에는 일반적인 동기화 api를 사용해야 합니다.
전용 rcu_write_lock()이 없는 이유입니다.
즉, rcu를 사용 시 2번째 write 동작이 1번째 write 동작과 충돌할 가능성이 있는 경우,
각 write 동작에 spin_lock, mutex 또는 semaphore 등
별도의 동기화 api를 사용하여 보호해야 합니다. (MUST)
또한 rcu write 완료를 보장해야 하는 경우에는
블럭 api인 synchronize_rcu() 함수를 사용합니다.
rcu를 사용하여 리스트 object를 추가하는 예를 생각해보죠.
리스트에 이미 3개의 A-B-C object들이 연결되어 있다고 가정하죠.
0번 cpu가 B object 다음에 X를 추가하고,
1번 cpu도 동시에 B object 다음에 Y를 추가하는 경우 입니다.
-> 두 개의 cpu간에 write 동작이 겹칠 수 있으므로
write 동작 전에 cpu간에 사용하는 동기화 api인 spin_lock()을 사용합니다.
cpu 0번이 먼저 spin_lock을 소유하게 되면 X를 추가하여 A-B-X-C와 같이 변하고,
그 다음 cpu 1번이 동작하여 A-B-Y-X-C와 같이 변경됩니다.
두 번째 질문의 경우 위의 대답을 통해 어느 정도 이해하셨으리라 봅니다.
rcu reclaimer에서는 update 이후 gp 기간동안 주로 old 데이터의 폐기 목적으로 사용합니다.
감사합니다.