DPAS 실습 가이드

NVMe I/O Completion 모드별 성능 비교 실습

2026-1 시스템최신기술
English

사전 준비

플랫폼별 QEMU 설치 및 Ubuntu VM 구축이 완료된 상태여야 합니다.

필수 환경 Ubuntu 22.04 VM + mainline 커널 5.18 (uname -r5.18.0-051800-generic)
왜 커널 5.18인가? 이 실습에서는 preadv2(RWF_HIPRI)를 통한 동기식 Direct I/O polling을 사용합니다. 이 기능은 Linux 커널 5.19부터 제거되었기 때문에, 5.18이 이 기능을 지원하는 마지막 커널입니다. QEMU Guest VM 안에서 커널 5.18을 사용하므로, 호스트 OS의 커널 버전과는 무관하게 polling 실습이 가능합니다.

I/O Completion 배경 읽기 자료 → — Interrupt/Polling의 역사, FAST '26 최신 연구, io_uring과 polling의 미래

Part 1: DPAS 커널 설치

제공된 deb 패키지로 DPAS 패치가 적용된 커널을 설치합니다.

deb 패키지란? .deb 파일은 Ubuntu/Debian 계열 Linux에서 사용하는 소프트웨어 설치 패키지입니다. Windows의 .msi 설치 파일, macOS의 .pkg와 같은 역할입니다. sudo dpkg -i 파일.deb 명령으로 설치하며, 커널 이미지·헤더 등 시스템 파일을 자동으로 올바른 위치에 배치해 줍니다.
아키텍처 선택 — 호스트 OS가 아닌 CPU 아키텍처 기준 커널 패키지는 호스트 운영체제(macOS/Windows/Linux)와 무관하게, VM이 실행되는 CPU 아키텍처에 따라 선택합니다. Guest VM 안에서 uname -m을 실행하면 아키텍처를 확인할 수 있습니다.
호스트 환경uname -m 결과필요한 패키지
Apple Silicon Mac (M1/M2/M3/M4)aarch64ARM64
Intel Mac / Linux PC / Windows (WSL2)x86_64x86_64

커널 패키지 다운로드

VM의 CPU 아키텍처에 맞는 패키지를 다운로드하세요.

ARM64 커널 이미지 (23MB) ARM64 헤더 (8MB)
x86_64 커널 이미지 (12MB) x86_64 헤더 (8MB)

1-1. 패키지 전송

다운로드한 deb 파일을 호스트에서 VM으로 전송합니다.

# 호스트 터미널에서 실행
scp -P 2222 linux-image-5.18.0-dpas_*.deb <username>@localhost:~/
scp -P 2222 linux-headers-5.18.0-dpas_*.deb <username>@localhost:~/

1-2. 설치 및 재부팅

# VM 내부에서 실행
sudo dpkg -i ~/linux-image-5.18.0-dpas_*.deb ~/linux-headers-5.18.0-dpas_*.deb
sudo reboot

1-3. 설치 확인

uname -r
# 5.18.0-dpas
부팅 커널이 변경되지 않은 경우 GRUB이 이전 커널로 부팅할 수 있습니다. 아래 명령으로 DPAS 커널을 선택 후 재부팅하세요:
sudo grub-reboot "Advanced options for Ubuntu>Ubuntu, with Linux 5.18.0-dpas"
sudo reboot

Part 2: 실습 — 모드별 성능 비교

2-1. 벤치마크 스크립트

VM 내부에서 아래 4개 스크립트를 생성합니다. 사용법: ./script.sh <device> <cpu> <numjobs>

fioint.sh — Interrupt 모드

#!/bin/bash
sudo modprobe -r nvme; sudo modprobe nvme poll_queues=0
fio --filename=/dev/$1 --size=100m --direct=1 --bs=4k --ioengine=pvsync2 \
    --iodepth=1 --rw=randread --runtime=10 --numjobs=$3 --time_based \
    --group_reporting --name=test --eta-newline=1 --cpus_allowed=$2 \
    --nice=-10 --prioclass=2 --prio=0

fiocp.sh — Continuous Polling 모드

#!/bin/bash
sudo modprobe -r nvme; sudo modprobe nvme poll_queues=2
fio --filename=/dev/$1 --ramp_time=3 --size=100m --direct=1 --bs=4k \
    --ioengine=pvsync2 --iodepth=1 --rw=randread --runtime=10 \
    --numjobs=$3 --time_based --group_reporting --name=test \
    --eta-newline=1 --cpus_allowed=$2 --nice=-10 --prioclass=2 \
    --prio=0 --hipri

fiopas.sh — PAS (Polling after Sleep) 모드

#!/bin/bash
sudo modprobe -r nvme; sudo modprobe nvme poll_queues=2
echo 0 > /sys/block/$1/queue/io_poll_delay
echo 1 > /sys/block/$1/queue/pas_enabled
echo 1 > /sys/block/$1/queue/pas_adaptive_enabled
fio --filename=/dev/$1 --direct=1 --bs=4k --ioengine=pvsync2 \
    --iodepth=1 --rw=randread --runtime=10 --numjobs=$3 --time_based \
    --group_reporting --name=test --eta-newline=1 --cpus_allowed=$2 \
    --nice=-10 --prioclass=2 --prio=0 --hipri

fiodpas.sh — DPAS (Dynamic PAS) 모드

#!/bin/bash
sudo modprobe -r nvme; sudo modprobe nvme poll_queues=2
echo 0 > /sys/block/$1/queue/io_poll_delay
echo 1 > /sys/block/$1/queue/pas_enabled
echo 1 > /sys/block/$1/queue/pas_adaptive_enabled
echo 1 > /sys/block/$1/queue/switch_enabled
echo 10 > /sys/block/$1/queue/switch_param1
echo 10 > /sys/block/$1/queue/switch_param2
echo 10 > /sys/block/$1/queue/switch_param3
echo 1 > /sys/block/$1/queue/switch_param4
fio --filename=/dev/$1 --ramp_time=3 --size=100m --direct=1 --bs=4k \
    --ioengine=pvsync2 --iodepth=1 --rw=randread --runtime=10 \
    --numjobs=$3 --time_based --group_reporting --name=test \
    --eta-newline=1 --cpus_allowed=$2 --nice=-10 --prioclass=2 \
    --prio=0 --hipri
cat /sys/block/$1/queue/switch_stat
dmesg | tail -10

실행 권한 부여:

chmod +x fioint.sh fiocp.sh fiopas.sh fiodpas.sh

2-2. 실험 실행

CPU 0에 고정하여 job 수를 변경하며 4가지 모드를 비교합니다.

# 예시: INT 모드, job 1개
./fioint.sh nvme0n1 0 1

# 각 모드별로 jobs = 1, 2, 4, 8 반복
# INT:  ./fioint.sh nvme0n1 0 {1,2,4,8}
# CP:   ./fiocp.sh  nvme0n1 0 {1,2,4,8}
# PAS:  ./fiopas.sh nvme0n1 0 {1,2,4,8}
# DPAS: ./fiodpas.sh nvme0n1 0 {1,2,4,8}

2-3. 결과 기록

각 실행에서 fio 출력의 IOPSavg latency를 기록합니다.

ModeJobs=1Jobs=2Jobs=4Jobs=8
INT
CP
PAS
DPAS

2-4. DPAS mode transition 확인

DPAS 실행 후 switch_statdmesg 출력에서 확인:

MODE 값의미
0INT (Interrupt)
1CP (Continuous Polling)
2PAS (초기 상태)
3OL (Overloaded)

기대 동작

Jobs기대 최종 모드이유
1CP (MODE 1)QD=1 → PAS→CP 전환, polling으로 최저 latency
2+INT (MODE 0)QD>1 → PAS→OL→INT 전환, 인터럽트로 CPU 양보

2-5. 분석 질문

  1. INT와 CP 모드에서 jobs=1일 때 IOPS 차이의 원인은 무엇인가?
  2. CP 모드에서 job 수를 늘려도 IOPS가 크게 증가하지 않는 이유는?
  3. DPAS가 jobs=1에서 CP에 근접하고, jobs=4 이상에서 INT에 근접하는 이유를 mode transition 관점에서 설명하시오.
  4. switch_stat에서 pas io 수가 polled io보다 항상 적은 이유는?

Part 3: DPAS sysfs 인터페이스

DPAS 커널은 /sys/block/nvme0n1/queue/ 아래에 다음 파라미터를 제공합니다.

파라미터설명기본값
switch_enabledDPAS mode switching 활성화0
switch_statCPU별 모드 통계 출력 (읽기 전용)
pas_enabledPAS 모드 활성화0
pas_adaptive_enabledAdaptive sleep 활성화0
switch_param1PAS→OL 임계치 (tf > param1)0
switch_param2OL→PAS 임계치 (avg QD ≤ param2)10
switch_param3OL→INT 임계치 (avg QD > param3)10
switch_param4PAS→CP 전환 활성화 (0/1)1
QD 10x multiplier QD 관련 파라미터는 10배 스케일을 사용합니다. param2=10은 average QD ≤ 1.0을 의미합니다. 이는 정수 연산으로 소수점 정밀도를 확보하기 위한 설계입니다.

Part 4: 커널 소스 컴파일 도전과제

deb 패키지 대신 직접 커널 소스에 DPAS 패치를 적용하고 빌드합니다.

4-1. 빌드 의존성 설치

sudo apt install -y build-essential libncurses-dev bison flex libssl-dev \
    libelf-dev bc pahole dwarves zstd

4-2. 커널 소스 다운로드

cd ~
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.18.tar.xz
tar xf linux-5.18.tar.xz
cd linux-5.18

4-3. DPAS 패치 적용

# 호스트에서 VM으로 패치 전송 후
patch -p1 < ~/dpas.patch
Makefile hunk 실패 패치가 5.18-rc6 기준이라 Makefile hunk 하나가 실패합니다. 무시해도 됩니다.
대신 localversion을 수동 설정: echo "-dpas" > localversion

4-4. 커널 설정 (최소화)

cp /boot/config-$(uname -r) .config
yes '' | make localmodconfig
왜 localmodconfig? 기본 config로 빌드하면 수천 개 모듈이 포함되어 디스크 부족(No space left on device)이 발생합니다. localmodconfig는 현재 로드된 모듈만 포함하여 빌드 시간과 디스크 사용량을 대폭 줄입니다.

4-5. 빌드

make -j$(nproc) bindeb-pkg

빌드 완료 시 홈 디렉토리에 linux-image-*.deb, linux-headers-*.deb 파일이 생성됩니다.

4-6. 설치

sudo dpkg -i ~/linux-image-5.18.0-dpas_*.deb ~/linux-headers-5.18.0-dpas_*.deb
sudo reboot

트러블슈팅

증상원인해결
No space left on device빌드 산출물이 디스크 초과make clean, tarball 삭제, localmodconfig 사용
Makefile Hunk #1 FAILED패치 버전 차이무시, localversion으로 대체
부팅 후 커널 미변경GRUB 기본 부팅 커널grub-reboot으로 DPAS 커널 선택
다수 hunk 실패이미 패치 적용된 소스에 재적용소스를 다시 풀고 재시도
빌드 15GB+ 필요디스크 여유 부족df -h / 확인, LVM 확장 또는 파일 정리

참고: QEMU 환경의 제약

항목QEMU실제 하드웨어
CP vs INT 비교유효 (1.7-1.8x IOPS 차이)유효
PAS adaptive sleep타이머 부정확, tf 노이즈정확
DPAS mode transition동작, 절대 성능은 참고용기본 파라미터로 동작
Multi-core 스케일링에뮬레이션 오버헤드로 왜곡Linear에 근접
실습 핵심 절대 성능 수치보다 모드 간 상대적 차이와 전환 동작에 집중하세요. I/O completion 메커니즘의 원리를 이해하는 것이 목표입니다.