Linux v6.18 · RCU

Tree RCU: CPU가 보고했다고 읽기 구간이 끝난 것은 아닙니다

한 CPU의 quiescent state, 선점된 reader, 유예기간 완료와 callback 실행을 구분합니다.

CPU 한 개의 보고로 끝나지 않습니다

공유 포인터를 교체해도 예전 포인터를 가진 reader는 남을 수 있습니다. synchronize_rcu()가 기다리는 것은 호출 전에 시작한 읽기 구간입니다. 그 뒤에 시작하는 모든 reader까지 사라져야 한다는 뜻은 아닙니다.

Tree RCU는 관측한 quiescent state가 현재 유예기간에 해당하는지 확인한 뒤 rcu_node 트리에 보고합니다. 필요한 자식의 보고가 모두 모여야 그 결과가 부모로 올라갑니다. CPU 하나가 쉬었거나 문맥을 전환했다는 로그가 있다고 해서 전체가 완료된 것은 아닙니다.

선점된 reader는 별도로 남습니다

선점 가능한 RCU에서 태스크가 읽기 구간 안에서 선점되면, CPU는 다른 태스크를 실행해도 해당 읽기는 아직 끝나지 않았습니다. Linux v6.18의 rcu_note_context_switch()는 그 태스크를 추적하도록 기록한 다음 CPU의 quiescent state를 보고할 수 있습니다.

blkd_tasks와 gp_tasks는 이 구분을 보여 주는 구현 단서입니다. 현재 유예기간을 막는 reader가 남아 있으면 CPU 보고만으로 기다림을 끝내지 않습니다. 이것은 일반 RCU 읽기 구간 안에서 임의로 잠들어도 된다는 허가가 아니며, 여러 writer의 충돌을 대신 직렬화하는 기능도 아닙니다.

유예기간과 callback을 따로 확인합니다

완료 정보가 트리를 거쳐 전달되고 callback이 실행되는 시점은 하나의 순간이 아닙니다. call_rcu()가 등록 직후 반환됐다고 해서 callback이 완료된 것은 아닙니다. 장애 기록에는 어떤 유예기간의 보고인지, 기다리는 reader가 무엇인지, callback이 실제로 실행됐는지를 나눠 남깁니다.

2015년 설명의 분리된 rcu_sched·rcu_bh 상태와 gpnum/completed 필드를 현행 구현으로 복사하지 않습니다. v6.18 문서와 소스를 기준으로 읽고, SRCU와 RCU Tasks의 별도 계약은 일반 RCU 설명에 섞지 않습니다. 이 글은 내부 상태를 바꾸는 실험이나 커널 실행 검증이 아닙니다.

CPU 보고만 모으면 충분한가?
  1. 현재 유예기간 확인

    이 보고가 어느 기다림에 속하는지 확인

  2. CPU와 reader를 분리

    CPU는 보고해도 선점된 읽기는 남을 수 있음

  3. 완료 전달과 실행

    유예기간 조건과 callback 실행을 각각 기록

출처와 연결

RCU 포인터 교체와 객체 수명