14장 블록 입출력 계층_수정.

Download Report

Transcript 14장 블록 입출력 계층_수정.

14장 블록 입출력 계층
Sang-Bok, Heo
Contents
블록 장치 구조
버퍼와 버퍼 헤드
bio 구조체
요청 큐
입출력 스케줄러
2
블록 장치 구조
섹터(sector)
•
•
•
•
가장 작은 단위
2의 거듭제곱 값의 크기 (일반적으로 512 Byte)
섹터보다 작은 단위로 접근/동작하는 장치는 없음
하드 섹터 / 장치 블록
블록(block)
• 논리적으로 접근할 수 있는 별도의 최소 단위
• 파일시스템 추상화 개념
- 파일 시스템 생성(mkfs) 시 블록 크기 결정
- 일반적으로 512B, 1KB, 2KB, 4KB
• 하나의 블록은 디스크 상에서 연속된 섹터
• 블록의 크기는 페이지 크기를 넘을 수 없음
• 파일시스템 블록 / 입출력 블록
3
버퍼와 버퍼 헤드
버퍼
• 각 버퍼는 하나의 블록에 대응
• 블록이 메모리상에 존재할 때 블록은 버퍼에 저장
- 블록 읽고 난 후 / 블록 쓰기를 준비할 때
• 어느 블록 디바이스의 어느 위치의 블록인지를 관리 해야 함
- 버퍼헤드(buffer_head)로 관리
버퍼 헤드
• 커널이 버퍼를 다루는 데 필요한 모든 정보를 보유
• 디스크 상의 블록과 메모리 상의 물리적인 버퍼의 연결 관계
4
버퍼와 버퍼 헤드
bh_state 플래그
상태 플래그
설명
BH_Uptodate
버퍼에 유효한 데이터가 들어 있음
BH_Dirty
버퍼가 변경되었음
BH_Lock
현재 버퍼에 대한 입출력 작업이 진행 – 동시 접근 금지
BH_Req
현재 버퍼가 입출력 요청을 처리 중
BH_Uptodate_Lock
페이지의 첫 번째 BH에 의해 사용
BH_Mapped
디스크상의 블록이 할당된 유효한 버퍼
BH_New
get_block() 함수를 통해 새로 할당만 된 버퍼
BH_Async_Read
end_buffer_async_read() 통해 비동기식 읽기 작업 진행
BH_Async_Write
end_buffer_async_write() 통해 비동기식 읽기 작업 진행
BH_Delay
아직 버퍼에 해당하는 디스크상의 블록이 없다(지연 할당)
BH_Boundary
버퍼가 연속된 블록의 경계에 해당. 다음 블록은 연속 x
BH_Write_EIO
버퍼 쓰기 작업 중 입출력 오류 발생
BH_Unwritten
디스크상에 버퍼를 위한 공간이 할당, 실제 데이터 미기록
BH_Queit
버퍼에서 발생하는 오류를 무시
BH_Meta
메타 데이터를 포함
BH_Pri
REQ_PRIO와 함께
BH_Defer_Completion
작업큐에 AIO 완료를 지연
BH_PrivateStart
유효한 상태 플래그가 아님, 코드에서 사용할 수 있는 첫 번째 비트를 표시하는데 사용
5
버퍼와 버퍼 헤드
타입
필드
설명
struct buffer_head
*b_this_page
다음 버퍼헤드를 가르킴
struct page
*b_page
bh와 연결된 page를 가르킴
sector_t
b_blocknr
b_bdev의 블록 디바이스의 블록 시작번호
size_t
b_size
블록의 크기
char
*b_data
페이지에 존재하는 블록의 위치
struct block_device
*b_bdev
블록 디바이스
bh_end_io_t
*b_end_io
I/O 완료 처리를 위한 함수
void
*b_private
완료 처리 함수를 위한 데이터
struct list_head
b_assoc_buffers
연관된 버퍼들의 매핑 리스트
atomic_t
b_count
버퍼 사용 빈도수
6
버퍼와 버퍼 헤드
문제점
• 버퍼 헤드는 크고 다루기 힘든 자료구조
- 버퍼 헤드 관점에서 데이터를 조작하는 것은 간단/깔끔하지 않음
- 버퍼 대신 페이지와 주소 공간을 직접 다루는 방식
· address_space 구조체와 pdflush 데몬 (16장-페이지 캐시와 페이지 지연 기록)
• 버퍼 헤드는 하나의 버퍼만 기술
- 모든 입출력 작업의 전달자로 버퍼 헤드를 사용
· 커널은 큰 블록 입출력 작업을 여러 개의 buffer_head 구조체로 분할 처리
· 불필요한 공간 소모가 발생
개선
• bio 구조체
7
bio 구조체
bio
• I/O를 수행할 디스크 영역의 정보와 I/O를 수행할 데이터를
저장하기 위한 메모리 영역의 정보를 포함
- read, write
• 진행 중인 입출력 작업을 표현 하는 것
- 대부분 항목은 이와 관련된 정보를 저장하기 위한 것
8
bio 구조체
bio
• 현재 진행 중인 블록 입출력 동작을 세그먼트 리스트로 표현
- 세그먼트(bio_vec 구조체 통해 저장)
· 장치와의 I/O연산을 위한 데이터를 저장하는 메모리 영역
· 일반적으로 페이지 캐시 내의 일부 영역
· 하나의 블록은 메모리 상에서 동일한 페이지 내에 저장
· 하나의 I/O 연산은 여러 블록으로 구성될 수 있음
· 하나의 세그먼트는 (개념적으로) 여러 페이지에 걸칠 수 있음
• 하나의 bio는 디스크 상에서 연속된 영역 만을 나타낼 수 있음
- 연속된 파일 데이터가 디스크 상에서 3부분
-> 세 개의 bio가 각각 할당되어 submit_bio() 함수를 통해 각각 전달
9
bio 구조체
bio
10
bio 구조체
11
버퍼와 버퍼 헤드
Linux/fs/buffer.c
Linux/block/blk-core.c
Linux/fs/buffer.c
Linux/fs/ext4/inode.c
12
bio 구조체
정리
• 블록 입출력 요청은 bio 구조체로 표현
• 각 요청은 하나 이상의 블록으로 구성(bio_vec 구조체 배열에 저장)
• 포인터를 다루지 않고 물리적 페이지만 다루므로 상위 메모리를
쉽게 표현 가능
• 최소한의 정보만 들어 있어서 버퍼헤드에 비해 훨씬 더 가벼움
13
요청 큐
요청 큐
• request_queue 구조체로 표현
• 입출력 요청의 이중 연결 리스트와 관련 정보 포함
• 큐에 들어 있는 항목은 하나의 입출력 요청을 의미함
입출력 요청
• struct request 구조체로 표현
• 한 요청에는 여러 개의 bio 구조체가 들어 있을 수 있음
- 하나 이상의 bio 구조체를 가지고 있음
· 연속된 여러 개의 세그먼트로 표현될 수 있음
• 인접한 블록이라도 메모리는 인접하지 않을 수 있음
14
입출력 스케줄러
입출력 스케줄러
• 요청이 발생하자마자 순서 그대로 전달 시 성능이 좋지 않음
- 느린 디스크 탐색을 최소화하는 것은 시스템 성능에 중요함
• 디스크 입출력 자원을 시스템의 대기 중인 블록 입출력 요청에 분배
• 커널은 요청 큐에 대기 중인 요청들을 병합하고 정렬
• 대기 중인 여러 블록 입출력 요청에 대해 블록 장치를 가상화
- 디스크 탐색 시간을 최소화 하기 위해
15
입출력 스케줄러
하는 일
• 블록 장치의 요청 큐를 관리
- 큐에 들어 있는 요청의 순서 결정
- 각 요청을 언제 블록 장치로 보낼 것인지 결정
• 전체 성능을 얻는 다는 목적
- 전체 성능을 개선 시키기 위해 불공정하게 처리 할 수 있음
• 병합
- 둘 이상의 요청을 하나로 합침
• 개별 탐색 시간을 최소화하는 것이 아닌 전체 탐색 시간을 최소화
• 디스크 헤드의 이동 방향을 일정하게 유지
- 엘리베이터 알고리즘
16
입출력 스케줄러
리누스 엘리베이터
• 병합과 정렬 모두를 수행
• 요청이 추가될 때, 병합이 가능한 후보가 있는 지 확인
• 병합 : 전방/후방 병합 방식. 후방병합이 많이 발생
- 전방 병합 : 새 요청이 기존 요청의 바로 앞
- 후방 병합 : 새 요청이 기존 요청의 바로 뒤
• 병합 실패 시 큐의 삽입 가능한 위치를 찾음
- 찾으면 새 요청을 그 곳에 추가
- 못 찾으면 큐의 끝 부분에 추가
- 오래된 요청이라면 끝에 추가
· 다른 오래된 요청이 미처리 상태에 머무르는 것(starvation)을 방지
» Starvation 관찰하는 작업이 비 효율적
• 주어진 시간 내에 요청이 처리됨을 보장할 수 없음
• Starvation의 I/O요청이 발생되면 병합, 정렬을 중지 시킬 뿐
17
입출력 스케줄러
데드라인 입출력
• 요청이 미처리 상태에 머무는 현상을 막는 방법을 찾음
- 리누스 엘리베이터 스케줄러
• 탐색 시간 최소화에 대한 집중은 미처리 현상을 발생 시킴
• 요청을 항상 섹터 위치에 따라 큐에 추가
• 요청에 대한 만료시간이 존재
- 읽기요청 0.5s, 쓰기요청 5s
• 정렬 큐
- 디스크의 물리적 위치에 따른 정렬 상태를 유지하는 요청 큐
• 특별 큐
- 특별 읽기 FIFO 큐, 특별 쓰기 FIFO 큐
• 정렬 큐의 앞에 있는 요청 -> 처리 큐에 넣음 -> 디스크 드라이브에
보냄
18
입출력 스케줄러
데드라인 입출력
• 스케줄러 요청이 지연되는 시간을 보장하지 않음
• 쓰기 요청으로 인해 읽기 요청이 미처리 상태를 방지
- 읽기 요청의 만료 시간이 쓰기 요청의 만료 시간보다 작음
읽기 FIFO 큐
디스크
쓰기 FIFO 큐
정렬 큐
19
입출력 스케줄러
예측 입출력 스케줄러
• 읽기 지연 시간을 계속 제공, 훌륭한 전체 성능을 제공
• 데드라인 입출력 스케줄러의 동작을 기본으로 함
- 세 개의 큐, 처리 큐, 각 요청의 만료 시간
• 예측 휴리스틱(anticipation heuristic) 추가
• 요청을 전달한 다음 바로 다른 요청을 처리하러 돌아가지 않음
- 수 밀리 초 동안 아무 일도 하지 않음(기본 값 : 6ms)
- 다른 읽기 요청을 받을 수 있음
- 인접 영역에 해당하는 요청은 바로 처리
- 탐색 횟수와 기간을 최소화, 읽기 지연 시간 최소화
- 서버에 이상적인 스케줄러
20
입출력 스케줄러
완전 공정 큐(Complete Fair Queuing) 입출력 스케줄러
• 특별한 부하 조건을 위해 설계된 입출력 스케줄러
- 멀티미디어를 다루는 경우
• 입출력 요청을 프로세서에 따라 특정 큐에 할당
• 각 큐 내부에서 인접한 요청은 병합/정렬
- 섹터 위치에 따른 정렬 상태를 유지
• 순차 방식(round robin)으로 큐의 요청을 처리
- 설정된 개수(기본 값 : 4)의 요청을 꺼냄
• 다양한 상황에서 좋은 성능을 보임
- 데스크탑 환경에서 추천, 리눅스의 기본 입출력 스케줄러
21
입출력 스케줄러
무동작 입출력 스케줄러(noop I/O scheduler)
• 별다른 동작을 하지 않음(noop)
• 병합 동작만 수행
- 큐에 새로운 요청이 추가될 때 인접한 요청이 있으면 병합
• 플래시 메모리와 같은 블록 장치를 위한 것
- 탐색을 위해 치러야 하는 대가가 없는
- 임의 접근이 가능한 장치 전용
22
입출력 스케줄러
입출력 스케줄러 선택
• 2.6 커널에 들어 있는 네 가지 입출력 스케줄러
• 기본적으로 완전 공정 큐 입출력 스케줄러 사용
• 커널 명령행 옵션으로 elevator=‘ ‘
인자
입출력 스케줄러
as
예측 입출력 스케줄러
cfq
완전 공정 큐 입출력 스케줄러
deadline
데드라인 입출력 스케줄러
noop
무동작 입출력 스케줄러
23