Corruption with O_DIRECT and unaligned user buffers Dec 4, 2008

좀 지난 얘기이긴 하지만..
현재 multiple thread의 O_DIRECT의 사용에 문제가 있다.
좀더 정확하게, multiple thread가 page 단위의 unaligned된 user buffer를 사용하게 되면
fork와 엉켜 발생하게 되는 문제이다.

예를 들어, 2개 이상의 쓰레드중 첫번째 쓰레드는 unaligned buffer의 512 offset부터 4096 byte만큼 데이터를 읽고, 2번째 쓰레드는 그 다음 4096 byte 만큼의 데이터를, 그 다음 쓰레드는 ... 차례데로 이렇게 읽어들이는 쓰레드들이 있다고 가정하자.

모든 buffer들이 512byte 만큼씩 bias되어 있다.

다음과 같은 sequence를 고려해보자.

  1. Thread 1이 get_user_pages를 호출했고 I/O를 issue했다.
  2. Fork가 발생, 해당 페이지를 COW로 mark
  3. Thread 2 get_user_pages 호출, I/O issue. 그러므로 이 mapping은 physical page의 사본을 얻게 된다.
  4. Thread 2가 issue한 I/O complete되고 새로운 데이터는 3에서 얻은 새로운 physical page에 복사
  5. Thread 1이 issue한 I/O complete되고 데이터는 데이터는 old phsyical page에 복사

그래서 결국 페이지의 첫 512byte의 내용은 old data를 갖게 되어 data는 사라지게 된다. -_-;
안전하게 user buffer 주소와 크기를 page boundary를 cross하게 만들지 않는 것이 좋을 것이다.

0 개의 덧글: