page cache는 . disk access에대한 오버헤드를 줄이고자 'temporal locality'를 활용하기 위함으로 알고 있습니다.
제생각은 buffer_head 구조체의 리스트를 통해서 충분히 page cache를 구현할수 있지 않나 생각이 되지만.
커널 내에서는 address_space 구조체를 통해서 page cache를 구현했습니다. 이것의 강점은 radix tree를 이용해서
page cache내부의 특정 데이터 search시간을 빠르게하고자 함으로 이해했습니다.
(여기까지 잘 이해한 것인가요??)
근데 리눅스 커널 심층분석 책을 읽던 도중에. 15챕터에 있는 page cache 부분에서
" it is not possible to index the data in the page cache using only a device name and block number "
라는 구절이 있는데,
저는 buffer_head구조체를 원형으로 연결해서 페이지 캐시를 구현하지 않은 이유가..빠른 search가 안되서
address_space 구조체를 고안했구나 하고 생각을 했는데..
device name 과 block number로 특정 데이터를 찾는게 불가능하다고 언급이 되어있네요.
왜 불가능하다고 표현을 했을가요?
댓글 9
-
김남형
2010.07.28 01:37
-
노서영
2010.07.28 10:10
page cache를 분할한것이 buffer cache라고 보면되고 한 page frame은 여러개의 buffer로 구성됩니다. buffer_head라는 구조체를 통해서 page frame내의 buffer에 대한 pointer를 가지고 있습니다. 말씀하신 buffer_head 구조체는 page에 속한 buffer들에 대한 pointer로 사용되는 구조체입니다. 따라서, 한 page frame에는 비연속적인 buffer (block)들이 올 수 있습니다. 더군다나, 자주 access되는 block일 수록 page frame을 block size로 분할했을 때, 0번째 block에 위치를 시켜서 block의 위치도 page frame 내에서 가변적이 됩니다.
Memory에서 관리되는 page와 다르게 disk I/O의 기본단위인 block은 block device별로 가변적입니다. page보다는 block을 access하는 것이 효과적일 경우가 있습니다. 예를 들어 filesystem의 superblock을 읽을 경우는 page보다는 block을 access하는 것이 효과적이지요. page cache와 buffer cache를 분할하는 것이 효과적인 경우가 있을 수 있다는 것입니다. -
김남형
2010.07.29 00:17
말씀은 감사드립니다만..
아직 많이 부족하다보니 이렇다 할 노하우라는 것도 없습니다.. ^^;;
-
노서영
2010.07.28 16:54
말씀하신대로 그 부분이 잘 못 표현되었습니다. 정확한 지적 감사드립니다. Page 상에서 buffer들의 위치는 바뀌지 않겠지요. 이를 바꾸려면 많은 오버헤드가 발생할테니까요. 단지 page를 균등하게 분할하여 관리하는 buffer에 대한 entry들이 조정되어야지요. 늘 좋은 답변해주신 점 감사드립니다. 저희 스터디에 언제 한번 초대하고 싶습니다. 그때 노하우 좀 전수 부탁드리고 싶습니다 ^^;
-
송원준
2010.08.12 06:05
안녕하세요 ^^
또한, FS의 논리적 처리 단위인 block과 Block Device Driver에서 처리단위인 sector와의 granularity 가 달라서
submit_bh()에 가보면. bh->b_blocknr * (bh->b_size >> 9) 를 통해서 sector를 구하는 코드도 보이는군요 :))
요새 형자리에 제가 앉고 있습니다. ㅋㅋ 형 사진 제 서랍에 있던데..필요하시면 말씀하세요 :)
-
박은병
2010.08.05 19:48
얼마전 잠깐 이부분 소스를 봐서 참고 사항으로..^^..
현재 linux에서 buffer cache는 page cache에 통합되어 있습니다. (크게 버퍼캐시(디스크) + 힙 + 스택) 과거에는 버퍼캐시와 그외의 것들이 서로 분리되어 관리되었지만, 현재는 page cache로 모두 하나로 관리합니다.
현재 buffer_head(과거 버퍼캐시로 사용하던)는 page를 블록 단위로 쪼개는데 사용되는데, 현재 대부분의 파일 시스템이 4KB block size로 포멧되어 지므로 사실상 대부분의 I/O가 4KB 단위로 발생합니다. 물론 파일 시스템에 따라서 metadata는 4KB단위가 아닐 수 있습니다. 만약 4KB로 디스크를 읽고 쓴다면 사실buffer_head는 필요 없습니다.
하지만 이전 커널 소스와의 호환을 위해( submit_bh() 등) 인터페이스가 buffer_head를 인자로 받도록 되어 있는 경우가 많으므로
실제로 4KB 단위로 읽고 쓸 때에도 buffer_head를 page 에 할당해야 할 필요가 있습니다. 1. 이렇게 호환성을 유지하기위해 buffer_head가 사용되고요, 2. block단위(4KB보다 작은 경우)를 위해 buffer_head는 필요합니다.
-
김남형
2010.07.28 15:55
PLKA 좋은 책이죠.. ^^
약간 오해하고 계신 부분이 있는 듯 하여 추가합니다.
본문에 나와있듯이 buffer cache는 page cache와 전혀 별개의 것이기 때문에
(물론 bdev fs까지 내려가면 연관되어 있습니다만..;; )
page cache가 사용되는 상황에서는 buffer cache가 사용되지 않습니다.
해당 page에 대한 디스크 접근이 필요할 때는 page cache에 buffer_head를 추가하여
buffer cache인 것처럼 (혹은 buffer cache로 변환하여) 사용하기는 합니다.
따라서(?) 특정 block이 자주 접근된다고 해서 page 상의 위치가 바뀌지는 않습니다.
file offset과 block number의 매핑은 inode 상에 고정되어 있기 때문에 동적으로 변경할 수도 없습니다.
위에서 얘기한 상황은 page cache와는 별도로 buffer cache가 사용되는 경우
각 buffer cache들은 해당 cpu의 lru 리스트(bh_lrus)로 관리하므로
접근이 일어나는 buffer cache가 lru 상의 0번 위치로 이동된다는 것입니다.
-
노서영
2010.07.28 14:19
제가 참고한 서적에서 발췌한 내용입니다.
"Professional Linux Kernel Architecture", page 955
"There are, of course, applications that access block devices using blocks rather than pages — reading the superblock of a filesystem is one such example. A separate buffer cache is used to speed access of this kind. The buffer cache operates independently of the page cache, not in addition to it. To this end, buffer heads — the data structure is the same in buffer caches and page caches — are grouped together in an array of constant size whose individual entries are managed on a least recently used basis. After an entry has been used, it is placed at position 0 and the other entries are moved down accordingly; this means that the entries most frequently used are located at the beginning of the array and those less frequently used are pushed further back until they finally ‘‘drop‘‘off the array if they have not been used for a lengthy period."
-
김남형
2010.07.28 12:09
자주 access되는 block일 수록 page frame을 block size로 분할했을 때, 0번째 block에 위치를 시켜서 block의 위치도 page frame 내에서 가변적이 됩니다.
몰랐던 내용이 있네요.. ^^
죄송하지만 이 부분에 대한 reference를 알려주실 수 있을까요?
.
KLDP에도 동일한 질문을 올리신 것 같군요.. ^^
제가 알고있기론 buffer cache 대신 page cache를 이용하는 것은
단지 관리 상의 문제이지 검색 시간 때문은 아닌 것으로 알고 있습니다.
(buffer cache로 radix tree를 구현한다면 되겠지요..)
언급하신 책의 내용은 저도 확인해 보았는데 (1판의 번역본입니다..;; )
저자의 의도를 정확히 파악하지는 못하겠지만.. 아마도
"페이지 캐시가 페이지 크기 만큼의 디스크의 내용을 유지하지만
한 페이지 캐시 내의 데이터가 디스크 상에서 연속된 블록으로 이루어지지 않을 수도 있기 때문에
연속된 두 개의 블록이 있을 때 뒤쪽의 블록이 앞쪽의 블록과 동일한 페이지 캐시 내에 (블록 크기 만큼 떨어져서)
존재한다고 판단할 수 없다"는 정도의 의미를 전달하려는 것이 아닐까 생각됩니다.