GPU 서브시스템 (DRM/KMS)

Linux GPU 서브시스템(DRM/KMS)을 디스플레이 파이프라인(Pipeline)과 연산 가속 경로를 함께 보는 관점에서 심층 분석합니다. DRM core와 KMS 객체 모델(CRTC/plane/encoder/connector), GEM/TTM 메모리 관리(Memory Management)자, DMA-BUF 기반 장치 간 버퍼(Buffer) 공유, atomic modesetting과 vblank 동기화, fence 기반 GPU 작업 순서 제어, 전원·클럭·열 관리(Thermal Management), userspace(Mesa/Wayland)와의 ioctl 계약, debugfs/tracepoint로 프레임 드롭과 hang을 진단하는 방법까지 GPU 드라이버 개발 핵심을 다룹니다.

전제 조건: 디바이스 드라이버DMA 문서를 먼저 읽으세요. 멀티미디어/가속기 경로는 대용량 버퍼 이동과 동기화가 성능의 핵심이므로, 메모리 경로와 큐 모델을 먼저 파악해야 합니다.
일상 비유: GPU 서브시스템은 공유 작업장을 예약제로 운영하는 설계 사무실과 비슷합니다. 여러 프로그램이 같은 가속기를 쓰므로 GEM/TTM 메모리, dma-buf 공유, DRM 스케줄러가 작업 공간과 순서를 조율해야 합니다.

핵심 요약

  • 노드 분리 — 화면 제어는 primary node, 비특권 렌더링은 render node, 비그래픽 연산은 accel node가 담당합니다.
  • 상태 모델 — KMS는 CRTC/plane/connector를 atomic state로 묶어 한 번에 검증하고 적용합니다.
  • 버퍼 수명주기 — BO 생성, 핸들 배정, mmap, DMA-BUF 공유, fence 동기화가 한 세트로 움직입니다.
  • 메모리 계층 — 단순 SoC GPU는 GEM shmem, 전용 VRAM GPU는 TTM/VRAM helper/자체 GPUVM을 주로 사용합니다.
  • 복구 설계 — hang 감지, fence 타임아웃, 엔진 리셋, 전원 재기동이 운영 안정성을 좌우합니다.

단계별 이해

  1. 어느 노드를 여는지부터 구분
    compositor는 primary node에서 KMS를 제어하고, 일반 앱은 render node에서 커맨드 제출을 시작합니다.
  2. 버퍼를 어떤 백엔드에 둘지 결정
    scanout 전용이면 dumb buffer, 일반 렌더링이면 드라이버 전용 BO, 장치 간 공유면 DMA-BUF까지 함께 봅니다.
  3. atomic 상태를 조립
    plane/CRTC/connector 속성을 새 상태 객체에 채운 뒤 atomic_check로 하드웨어 제약을 검증합니다.
  4. 렌더링과 표시를 동기화
    dma_resv, syncobj, IN_FENCE_FD/OUT_FENCE_PTR로 렌더 완료 시점을 맞춥니다.
  5. 운영 중 고장 경로를 준비
    GPU hang, hotplug, runtime suspend, reset recovery를 debugfs·tracepoint·drm_sched 타임아웃으로 추적합니다.
관련 표준: DisplayPort 2.1 (디스플레이 인터페이스), HDMI 2.1 (멀티미디어 인터페이스), E-EDID (디스플레이 정보 교환), PCIe 6.0 (GPU 인터커넥트) — DRM/KMS 서브시스템이 구현하는 디스플레이 및 GPU 규격입니다. 종합 목록은 참고자료 — 표준 & 규격 섹션을 참고하세요.

세부 문서 안내

GPU 서브시스템 문서는 주제별로 3개의 세부 문서로 나뉘어 있습니다. 각 문서에서 해당 영역을 심층적으로 다룹니다.

문서주요 내용핵심 키워드
DRM 코어 및 디스플레이 (KMS) DRM 코어 아키텍처, 디바이스 노드, KMS 객체 모델, atomic modesetting, DRM properties, VRR, format modifier, DRM bridge/panel, 디스플레이 프로토콜, HDCP, DRM lease, fbdev 에뮬레이션, 드라이버 골격, 주요 DRM 드라이버, ioctl 요약 DRM, KMS, CRTC, encoder, connector, plane, atomic, VRR, HDCP
GPU 메모리 관리 및 스케줄러(Scheduler) GEM 메모리 관리, TTM, DMA-BUF 버퍼 공유, GPU 커맨드 서브미션, drm_sched 스케줄러, GPUVM 가상 메모리(Virtual Memory), GPU 전원 관리(Power Management), GPU 리셋 및 복구, 커널 설정, DRM 디버깅(Debugging) GEM, TTM, DMA-BUF, dma_fence, drm_sched, GPUVM, GPU PM, GPU reset
GPU 컴퓨팅 (GPGPU) GPU 컴퓨트 개요, CUDA/NVIDIA 아키텍처, OpenCL 크로스 플랫폼 컴퓨트, Vulkan Compute 파이프라인, ROCm/HIP AMD 컴퓨트, Intel oneAPI/Level Zero GPGPU, CUDA, OpenCL, Vulkan Compute, ROCm, HIP, oneAPI

DRM 서브시스템 구조 개요

DRM은 Linux 커널의 GPU 접근을 관리하는 서브시스템입니다. 원래 3D 그래픽 가속을 위해 도입되었으나, 현재는 디스플레이 출력(KMS), GPU 메모리 관리(GEM/TTM), GPU 작업 스케줄링까지 포괄하는 핵심 프레임워크로 발전했습니다.

구성 요소역할상세 문서
DRM Core 드라이버 등록(Driver Registration), ioctl 디스패치(Dispatch), 파일 오퍼레이션 DRM 코어 및 디스플레이
KMS (Kernel Mode Setting) 디스플레이 모드 설정, CRTC/Encoder/Connector/Plane KMS 섹션
GEM / TTM GPU 메모리 버퍼 할당/관리, VRAM/시스템 메모리 간 이동 GEM 섹션
DMA-BUF 디바이스 간 버퍼 공유 (GPU↔카메라↔디스플레이) DMA-BUF 섹션
GPU Scheduler GPU 작업 큐(Workqueue) 관리, 우선순위(Priority), 타임아웃 처리 GPU 스케줄러 섹션
GPU 컴퓨트 CUDA, OpenCL, Vulkan Compute, ROCm/HIP, oneAPI GPU 컴퓨팅

디바이스 노드와 권한 모델 요약

현대 DRM UAPI는 GPU 하나를 단일 문자 디바이스로만 노출하지 않습니다. 같은 하드웨어라도 화면 제어, 비특권 렌더링, 비그래픽 연산을 서로 다른 노드로 나누어 권한 경계와 사용자 공간(User Space) 스택을 분리합니다.

노드 종류대표 경로주 용도
Primary /dev/dri/card0 KMS modeset, connector/plane/lease 제어
Render /dev/dri/renderD128 OpenGL/Vulkan/VA-API/OpenCL 등 비특권 렌더링과 GPGPU
Accel /dev/accel/accel0 NPU/AI/신호 처리 같은 비그래픽 compute

디바이스 노드의 상세 구조와 권한 모델, drm_file 구조체(Struct), DRM master 개념 등은 DRM 코어 및 디스플레이 — 디바이스 노드와 권한 모델 섹션을 참고하세요.

DRM 아키텍처

User Space Mesa / Vulkan libdrm Wayland / X11 GPGPU (OpenCL) V4L2 / GBM ioctl / mmap DRM Core /dev/dri/card0 (Primary) & /dev/dri/renderD128 (Render) KMS (Mode Setting) CRTC · Encoder · Connector · Plane GEM / TTM 메모리 관리 GPU Scheduler Job Queue · Fence · Timeout DMA-BUF DRM Driver (i915 / amdgpu / nouveau / panfrost / virtio-gpu ...) 드라이버별 HW 초기화, 커맨드 서브미션, IRQ, 전원 관리 MMIO / DMA GPU Hardware

각 계층의 상세 내용은 다음 문서에서 확인할 수 있습니다:

DRM 코어 초기화 및 드라이버 등록

DRM 드라이버는 PCI 디바이스 탐지 → 리소스 할당 → 커널 등록 → 사용자 공간 노출의 단계를 거칩니다. 이 섹션에서는 drm_driver 구조체의 핵심 필드와 초기화 흐름을 실제 커널 소스 코드와 함께 설명합니다.

drm_driver 구조체 핵심 필드

struct drm_driver는 DRM 드라이버의 모든 동작을 정의하는 핵심 구조체입니다. 다음은 2025 년 기준 주요 필드입니다:

/* include/drm/drm_drv.h — drm_driver 구조체 (핵심 필드) */
struct drm_driver {
    /* 드라이버 메타데이터 */
    const char *name;              /* 드라이버 이름 (예: "i915", "amdgpu") */
    const char *desc;              /* 설명 문자열 */
    const char *date;              /* 버전/날짜 */
    const struct file_operations *fops; /* 파일 오퍼레이션 */

    /* 드라이버 기능 플래그 */
    u32 driver_features;         /* DRIVER_GEM, DRIVER_MODESET, DRIVER_RENDER 등 */

    /* IOCTL 테이블 — 사용자 공간 API 노출 */
    const struct drm_ioctl_desc *ioctls;
    int num_ioctls;

    /* PCI 디바이스 테이블 — 자동 탐지용 */
    const struct pci_device_id *pci_driver;

    /* 콜백 함수들 — 드라이버 수명주기 */
    int (*load)(struct drm_device *, unsigned long flags);
    void (*unload)(struct drm_device *);
    int (*open)(struct drm_device *, struct drm_file *);
    void (*postclose)(struct drm_device *, struct drm_file *);

    /* KMS 관련 함수 포인터 */
    const struct drm_mode_config_funcs *mode_config_funcs;
    const struct drm_mode_config_helper_funcs *mode_config_helpers;

    /* GEM/메모리 관리 함수 */
    const struct drm_gem_object_funcs *gem_object_funcs;
    const struct ttm_place *placements;  /* TTM 메모리 영역 */

    /* 동기화 및 스케줄링 */
    const struct drm_sched_driver *sched_driver;  /* drm_sched ops */

    /* 디버깅 및 정보 제공 */
    void (*debugfs_init)(struct drm_minor *);
    int (*gem_prime_pin)(struct drm_gem_object *obj);
};
driver_features 플래그:
  • DRIVER_GEM — GEM 메모리 관리 사용
  • DRIVER_MODESET — KMS (Kernel Mode Setting) 지원
  • DRIVER_RENDER — render node (/dev/dri/renderD*) 생성
  • DRIVER_COMPUTE_ACCEL — compute 가속기 기능 (비그래픽 작업)
  • DRIVER_GPU_SCHEDULER — drm_sched 사용

PCI Probe — 디바이스 탐지 및 초기화

대부분의 GPU 드라이버는 PCI 서브시스템을 통해 탐지됩니다. 다음은 amdgpu 드라이버의 실제 probe 함수입니다:

/* drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c — PCI probe 함수 */
static int
amdgpu_pci_probe(struct pci_dev *pdev,
                 const struct pci_device_id *ent)
{
    struct drm_device *ddev;
    struct amdgpu_device *adev;
    int ret;

    /* 1. DRM 디바이스 할당 */
    ddev = devm_drm_dev_alloc(&pdev->dev, &amdgpu_kms_driver,
                               struct amdgpu_device, ddev);
    if (IS_ERR(ddev))
        return PTR_ERR(ddev);

    adev = drm_to_adev(ddev);
    adev->ddev = ddev;
    adev->pdev = pdev;
    pci_set_drvdata(pdev, adev);

    /* 2. PCI 리소스 활성화 */
    ret = pci_enable_device(pdev);
    if (ret < 0) {
        dev_err(&pdev->dev, "Cannot enable PCI device\n");
        return ret;
    }

    /* 3. MMIO 리소스 매핑 */
    adev->rmmio = pci_iomap(pdev, 0, 0);
    if (!adev->rmmio) {
        dev_err(&pdev->dev, "Cannot map MMIO region\n");
        ret = -ENOMEM;
        goto err_disable_pci;
    }

    /* 4. DRM 디바이스 등록 (사용자 공간에 /dev/dri/cardN 노출) */
    ret = drm_dev_register(ddev, 0);
    if (ret)
        goto err_unmap_mmio;

    /* 5. 추가 초기화 (펌웨어 로드, 파워 관리 등) */
    ret = amdgpu_device_init(adev);
    if (ret)
        goto err_unregister;

    return 0;

err_unregister:
    drm_dev_unregister(ddev);
err_unmap_mmio:
    pci_iounmap(pdev, adev->rmmio);
err_disable_pci:
    pci_disable_device(pdev);
    return ret;
}
코드 설명
  • 12-17 행 devm_drm_dev_alloc()은 DRM 디바이스와 드라이버 전용 구조체 (amdgpu_device) 를 한 번에 할당합니다. 리소스 관리는 device-managed 함수로 자동 정리됩니다.
  • 23-28 행 PCI 디바이스를 활성화하고 MMIO(Memory-Mapped I/O) 영역을 매핑합니다. GPU 레지스터 접근에 필수적입니다.
  • 34-38 행 drm_dev_register()는 DRM 코어에 디바이스를 등록하고 /dev/dri/card0, /dev/dri/renderD128 노드를 생성합니다.
  • 41-44 행 드라이버 전용 초기화 (펌웨어 로드, IP 블록 탐지, 파워 관리 초기화) 를 수행합니다.

drm_device 구조체와 수명주기

struct drm_device는 DRM 코어가 관리하는 디바이스 컨텍스트입니다:

/* include/drm/drm_device.h — drm_device 구조체 (핵심 필드) */
struct drm_device {
    /* 디바이스 식별 */
    struct device *dev;           /* Linux device 모델 */
    struct drm_driver *driver;    /* 드라이버 ops */

    /* KMS 객체 관리 */
    struct drm_mode_config mode_config;  /* CRTC/encoder/connector/plane 목록 */

    /* 메모리 관리 */
    struct drm_gem_object *gem_object_list;
    struct mutex gem_mutex;

    /* 파일/클라이언트 관리 */
    struct list_head filelist;
    struct drm_file *file_idr;

    /* 마스터 권한 — 인증된 클라이언트만 KMS 제어 */
    struct drm_master *master;

    /* 스케줄러 */
    struct drm_gpu_scheduler *sched[DRM_GPU_SCHED_MAX_ENTITIES];

    /* 디버깅 */
    struct drm_minor *primary;
    struct drm_minor *render;
};
DRM 드라이버 초기화 흐름 (PCI Probe) PCI 디바이스 탐지 pci_driver.probe() 호출 DRM 디바이스 할당 devm_drm_dev_alloc() PCI 리소스 활성화 pci_enable_device(), MMIO 매핑 DRM 코어 등록 drm_dev_register() 사용자 공간 노출 /dev/dri/card0, renderD128 1 단계 2 단계 3 단계 4 단계 5 단계
DRM 드라이버는 PCI probe 에서 디바이스를 탐지하고, drm_dev_register() 로 사용자 공간에 노출됩니다.

커맨드 서브미션 (Command Submission)

GPU 에 작업을 지시하려면 사용자 공간이 커맨드 버퍼 (Command Buffer) 를 작성하여 커널에 제출 (Submit) 합니다. 커널은 이를 검증 후 GPU 의 링 버퍼 (Ring Buffer) 에 기록하고, GPU 가 자동으로 처리합니다.

링 버퍼 아키텍처

링 버퍼는 순환 큐 (Circular Queue) 구조로, CPU(프로듀서) 가 커맨드를 쓰고 GPU(컨슈머) 가 읽어서 실행합니다.

/* drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h — 링 버퍼 구조체 */
struct amdgpu_ring {
    struct amdgpu_device *adev;
    unsigned enum amd_ip_block_type type;  /* GFX, SDMA, Compute 등 */
    const struct amdgpu_ring_funcs *funcs;

    u32 *ring;                    /* 링 버퍼 포인터 (VRAM/GTT 매핑) */
    unsigned long gpu_addr;         /* GPU 가 보는 주소 */
    u32 wptr;                     /* Write Pointer — CPU 가 쓴 위치 */
    u32 rptr;                     /* Read Pointer — GPU 가 읽은 위치 */
    u32 count_dw;                 /* 현재 커맨드 DW (DWORD) 수 */
    u32 max_dw;                   /* 최대 커맨드 크기 */
    u32 ring_size;                /* 링 버퍼 크기 (바이트) */

    struct mutex mutex;           /* 직렬화용 뮤텍스 */
    bool ready;                   /* 링 사용 가능 여부 */

    /* 스케줄러 연동 */
    struct drm_sched_rq *sched_rq;
    struct drm_gpu_scheduler *sched;
};
링 버퍼 크기: 일반적으로 256KB~2MB 입니다. 너무 작으면 자주 오버플로우가 발생하고, 너무 크면 GPU 가 커맨드를 늦게 발견하여 레이턴시가 증가합니다.

Indirect Buffer (IB) — 간접 커맨드 버퍼

복잡한 워크로드는 여러 개의 Indirect Buffer(IB) 로 구성됩니다. 각 IB 는 GPU 가 실행할 커맨드 시퀀스를 담으며, 메인 링 버퍼는 IB 를 체이닝합니다.

GPU 커맨드 서브미션 흐름 (Producer-Consumer) User Space (Mesa/Vulkan) 커맨드 버퍼 작성 → IOCTL 제출 DRM_IOCTL_SCHED_JOB Kernel DRM Scheduler 검증·우선순위·스케줄링 Ring Buffer (VRAM/GTT) CPU Write · GPU Read GPU Hardware Execution Engine GFX Ring · Compute Ring · SDMA Ring DMA Fence 생성 동기화·완료 알림용 Fence Wait / Signal 유저스페이스 대기 또는 Polling 작업 완료 Interrupt 또는 Polling 으로 알림 Producer-Consumer 모델: CPU 는 링 버퍼에 커맨드를 쓰고 (Producer), GPU 는 읽어서 실행합니다 (Consumer). WPtr (Write Pointer) 는 CPU 가, RPtr (Read Pointer) 는 GPU 가 관리합니다.
커맨드 서브미션은 Producer-Consumer 모델로 동작하며, Fence 로 동기화합니다.

Fence 와 동기화

Fence 는 GPU 작업의 완료를 나타내는 동기화 프리미티브입니다. DMA Fence 는 커널 내부에서, Sync File 은 사용자 공간에서 사용됩니다.

/* include/linux/dma-fence.h — DMA Fence 구조체 */
struct dma_fence {
    refcount_t refcount;         /* 참조 카운트 */
    spinlock_t lock;             /* 상태 보호용 스핀락 */
    unsigned long flags;         /* FLAG_SIGNALED 등 */
    int status;                  /* 0: 성공, -errno: 실패 */

    /* Fence 식별자 */
    u64 seqno;                   /* 시퀀스 번호 */
    u32 context;                 /* 컨텍스트 ID */

    /* 콜백 */
    struct rcu_head rcu;
    const struct dma_fence_ops *ops;
};

/* Fence 시그널 (완료 알림) */
static inline void
dma_fence_signal(struct dma_fence *fence)
{
    if (!test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
        __dma_fence_signal(fence);
}
Fence 타임아웃: GPU 가 hung 되면 Fence 가 시그널(Signal)되지 않아 사용자 공간이 영원히 대기할 수 있습니다. drm_sched 는 timeout_msec 파라미터로 타임아웃을 감지하고 GPU 리셋을 트리거합니다.

GPU 인터럽트 처리

GPU 는 작업 완료, 오류, VBlank(수직 귀선 소거), thermal 이벤트 등을 커널에 알리기 위해 인터럽트 (Interrupt) 를 사용합니다. 현대 GPU 는 수백 개의 인터럽트 소스를 가지며, 이를 효율적으로 처리하기 위해 MSI-X(Message Signaled Interrupts)인터럽트 도메인을 활용합니다.

GPU 인터럽트 종류

인터럽트 종류소스처리 우선순위용도
Graphics IRQ GFX 링, Compute 링 높음 3D 렌더링/컴퓨트 작업 완료 알림
Display IRQ CRTC, VBlank, Page Flip 매우 높음 디스플레이 타이밍, 페이지 플립 완료
DMA/SDMA IRQ SDMA 엔진 중간 DMA 전송 완료, 버퍼 복사
Error IRQ PARITY, ECC, Hang 즉시 처리 하드웨어 오류, GPU Hang 감지
Power/Thermal IRQ PMFW, Thermal 센서 낮음 전원 상태 변경, 과열 경고

인터럽트 핸들러(Handler) 아키텍처

GPU 인터럽트 처리는 Top Half(하드 IRQ)Bottom Half(스레디드 IRQ) 로 나뉩니다:

/* drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c — AMDGPU 인터럽트 핸들러 */
static irqreturn_t
amdgpu_irq_handler(int irq, void *dev_id)
{
    struct amdgpu_device *adev = dev_id;
    u32 status;

    /* 1. 인터럽트 소스 식별 (MMIO 레지스터 읽기) */
    status = RREG32_SOC15(GC, 0, mmGC_INT_CNTL);

    /* 2. 처리할 인터럽트가 없으면 IRQ_NONE 반환 */
    if (!(status & GC_INT_MASK))
        return IRQ_NONE;

    /* 3. 인터럽트 소스 클리어 (Ack) */
    WREG32_SOC15(GC, 0, mmGC_INT_ACK, status);

    /* 4. 스레디드 IRQ 깨우기 (Bottom Half) */
    wake_up_interruptible(&adev->irq_thread_wq);

    return IRQ_WAKE_THREAD;
}

/* 스레디드 인터럽트 핸들러 (Bottom Half) */
static irqreturn_t
amdgpu_irq_thread(int irq, void *dev_id)
{
    struct amdgpu_device *adev = dev_id;

    /* 5. Fence 시그널, 에러 처리, 스케줄러 알림 등 */
    amdgpu_fence_process(adev);
    amdgpu_dm_irq_process(adev);  /* 디스플레이 IRQ */
    amdgpu_ras_process(adev);     /* 오류 처리 */

    return IRQ_HANDLED;
}
코드 설명
  • 8-11 행 MMIO 레지스터를 읽어 어떤 인터럽트가 발생했는지 식별합니다. IRQ_NONE 을 반환하면 커널은 이 디바이스가 인터럽트를 발생시키지 않았다고 판단합니다.
  • 14-15 행 인터럽트 레지스터를 클리어하여 다음 인터럽트를 받을 준비를 합니다. 이를 "Ack" 라고 합니다.
  • 18-19 행 IRQ_WAKE_THREAD 를 반환하면 커널이 스레디드 핸들러를 깨웁니다. 이렇게 하면 Top Half 는 빠르게 종료되고, 무거운 작업은 Bottom Half 에서 처리됩니다.
  • 25-31 행 스레디드 컨텍스트에서 실제 처리를 수행합니다. Fence 시그널, 디스플레이 업데이트, 에러 로깅 등이 이루어집니다.
GPU 인터럽트 처리 흐름 (Top Half + Bottom Half) GPU Hardware 인터럽트 발생 IRQ 라인 Top Half (Hard IRQ Context) irq_handler() — IRQ 소스 식별 + Ack IRQ_WAKE_THREAD Bottom Half (Thread Context) irq_thread() — Fence 시그널, 에러 처리 Error Handling RAS, Hang 복구 Display Update VBlank, Page Flip Fence Signal dma_fence_signal() Scheduler Wakeup drm_sched_wakeup() fence_wait_timeout() 깨움 User Space (대기 중인 프로세스) fence_wait_timeout() glFinish(), vkQueuePresent()
Top Half 는 인터럽트를 빠르게 Ack 하고, Bottom Half 에서 실제 처리를 수행합니다.

MSI-X (Message Signaled Interrupts Extended)

현대 GPU 는 MSI-X 를 사용하여 여러 개의 인터럽트 벡터를 할당받습니다. 각 엔진 (GFX, Compute, SDMA, Display) 이 독립적인 IRQ 라인을 가지므로, 한 엔진의 인터럽트 처리가 다른 엔진을 블로킹하지 않습니다.

/* drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c — MSI-X 초기화 */
int
amdgpu_irq_init(struct amdgpu_device *adev)
{
    int ret;

    /* 1. MSI-X 지원 여부 확인 */
    if (pci_enable_msix_range(adev->pdev, NULL, 1, 32) < 0) {
        dev_warn(adev->dev, "MSI-X failed, fallback to INTx\n");
        goto use_intx;
    }

    /* 2. 각 IRQ 벡터에 핸들러 등록 */
    ret = request_threaded_irq(adev->irq.irq, amdgpu_irq_handler,
                               amdgpu_irq_thread, IRQF_ONESHOT,
                               "amdgpu", adev);
    if (ret)
        goto err_disable_msix;

    return 0;

err_disable_msix:
    pci_disable_msix(adev->pdev);
use_intx:
    /* 레거시 INTx 모드 fallback */
    return -EINVAL;
}
IRQF_ONESHOT 플래그: 스레디드 IRQ 에서 사용하며, Top Half 가 끝난 후 Bottom Half 가 완료될 때까지 동일 IRQ 를 마스크합니다. 이는 중첩 인터럽트를 방지하고 처리 순서를 보장합니다.

VBlank 인터럽트와 페이지(Page) 플립

VBlank(Vertical Blanking Interval) 는 디스플레이의 수직 귀선 소거 기간으로, 이 시점에 프레임버퍼를 교체해야 화면이 찢어지지 않습니다 (Tearing-free).

/* drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c — VBlank IRQ */
static void
dm_dce_crtc_high_irq(struct amdgpu_crtc *acrtc)
{
    struct drm_crtc *crtc = &acrtc->base;
    struct drm_device *dev = crtc->dev;

    /* VBlank 이벤트 발생 — DRM 코어에 알림 */
    drm_crtc_handle_vblank(crtc);

    /* 대기 중인 페이지 플립 완료 처리 */
    amdgpu_dm_complete_flip(crtc);
}

GPU 전원 관리 (Power Management)

현대 GPU 는 높은 성능과 전력 효율을 동시에 달성하기 위해 동적 전원 관리 (Dynamic Power Management, DPM) 를 사용합니다. 리눅스 커널 GPU 드라이버는 runtime PM, 클럭 게이팅 (Clock Gating), 전원 게이팅 (Power Gating), DVFS(Dynamic Voltage and Frequency Scaling) 등을 구현합니다.

전원 관리 계층

계층구성 요소역할
시스템 레벨 ACPI, P-State, S-State 전체 시스템 전원 상태 (S0~S5), CPU-GPU 협조
디바이스 레벨 Runtime PM, PCI ASPM GPU 디바이스 활성/유휴 상태 전환
블록 레벨 Clock/Power Gating GFX, SDMA, UVD, VCE 등 개별 IP 블록 전원 제어
코어 레벨 CU/Shutter Gating individual Compute Unit 전원 차단

Runtime PM — 자동 유휴 진입

Runtime PM 은 디바이스가 유휴 상태(Idle State)일 때 자동으로 전원을 차단하고, 접근 시 복구하는 메커니즘입니다. 사용자 공간은 /sys/bus/pci/devices/<BDF>/power/control 에서 제어할 수 있습니다.

/* drivers/gpu/drm/amd/pm/amdgpu_pm.c — Runtime PM 콜백 */
static int
amdgpu_runtime_suspend(struct device *dev)
{
    struct drm_device *drm_dev = dev_get_drvdata(dev);
    struct amdgpu_device *adev = drm_to_adev(drm_dev);

    /* 1. 모든 엔진이 유휴인지 확인 */
    if (!amdgpu_device_is_idle(adev))
        return -EBUSY;

    /* 2. 디스플레이가 모두 꺼졌는지 확인 (노트북 D3cold 진입 조건) */
    if (amdgpu_device_has_dc_support(adev) &&
        amdgpu_dm_has_display_in_use(adev))
        return -EBUSY;

    /* 3. VRAM 콘텐츠 백업 (필요시) */
    amdgpu_device_evict_resources(adev);

    /* 4. GPU 전원 차단 */
    amdgpu_device_ip_suspend(adev);
    amdgpu_device_fini_hw(adev);

    pci_save_state(adev->pdev);
    return 0;
}

static int
amdgpu_runtime_resume(struct device *dev)
{
    struct drm_device *drm_dev = dev_get_drvdata(dev);
    struct amdgpu_device *adev = drm_to_adev(drm_dev);

    /* 1. PCI 상태 복구 */
    pci_restore_state(adev->pdev);

    /* 2. GPU 전원 온 및 IP 블록 재초기화 */
    amdgpu_device_init_hw(adev);
    amdgpu_device_ip_resume(adev);

    /* 3. VRAM 콘텐츠 복구 (필요시) */
    amdgpu_device_recover_vram(adev);

    return 0;
}
코드 설명
  • 9-11 행 GPU 가 실제로 유휴 상태인지 확인합니다. 실행 중인 작업이 있으면 서스펜드를 거부합니다.
  • 14-17 행 디스플레이가 사용 중이면 (노트북 외부 모니터 연결 등) D3cold 진입을 막습니다. 이는 화면 깨짐을 방지합니다.
  • 20-24 행 VRAM 의 중요한 콘텐츠를 시스템 메모리로 대피시킵니다. D3cold 에서 VRAM 은 전원 차단으로 내용이 소실됩니다.
  • 33-39 행 재개 시 PCI 상태를 복원하고, GPU 를 다시 초기화합니다. 이 과정은 수백 밀리초가 소요될 수 있습니다.

클럭 게이팅 & 전원 게이팅

클럭 게이팅 은 사용하지 않는 블록의 클럭을 차단하여 동적 전력 소비를 줄이고, 전원 게이팅 은 블록 자체의 전원을 차단하여 누설 전력을 제거합니다.

게이팅 종류적용 블록전력 절감 효과복구 지연(Latency)
Clock GatingGFX, SDMA, UVD, VCE10-30%< 1ms
Power GatingGFX, VCE, UVD20-50%1-10ms
CU GatingCompute Unit 개별5-15%< 1ms
Memory GatingVRAM 채널5-10%1-5ms
/* drivers/gpu/drm/amd/pm/amdgpu_pm.c — 클럭/전원 게이팅 제어 */
static void
amdgpu_update_clock_gating(struct amdgpu_device *adev, bool enable)
{
    u32 mask = AMD_CG_SUPPORT_GFX_MGCG |      /* GFX Medium Grain Clock Gating */
               AMD_CG_SUPPORT_GFX_CGCG |      /* GFX Coarse Grain Clock Gating */
               AMD_CG_SUPPORT_SDMA_MGCG |     /* SDMA Clock Gating */
               AMD_CG_SUPPORT_UVD_MGCG;       /* UVD Clock Gating */

    if (enable)
        amdgpu_device_ip_set_clockgating_state(adev, AMD_CG_STATE_GATE);
    else
        amdgpu_device_ip_set_clockgating_state(adev, AMD_CG_STATE_UNGATE);
}

static void
amdgpu_update_power_gating(struct amdgpu_device *adev, bool enable)
{
    if (enable) {
        /* GFX 블록 전원 차단 */
        amdgpu_device_ip_set_powergating_state(adev, AMD_PG_STATE_GATE);
    } else {
        /* GFX 블록 전원 온 */
        amdgpu_device_ip_set_powergating_state(adev, AMD_PG_STATE_UNGATE);
    }
}

DVFS (Dynamic Voltage and Frequency Scaling)

PPTable(PowerPlay Table) 는 GPU 의 전압 - 주파수 곡선을 정의하며, 드라이버는 워크로드에 따라 최적의 P-State 를 선택합니다.

GPU DVFS 상태 전이 (P-State) P0 (Max Perf) 2.5 GHz / 1.2V 게임, 렌더링 전력: 300W P1 (Balanced) 1.8 GHz / 1.0V 웹 브라우징 전력: 150W P2 (Power Save) 800 MHz / 0.8V 비디오 재생 전력: 50W P3 (Ultra Low) 200 MHz / 0.6V 유휴 전력: 10W 부하 ↓ 부하 ↑ 워크로드 임계값에 따라 상태 자동 전이 사용자 공간 프로파일 제어 (sysfs) performance balanced power_saving auto (default) P0 고정 P0-P2 P2-P3 자동 조정
GPU 는 워크로드에 따라 P-State 를 자동 전이하며, 사용자 공간에서 프로파일을 제어할 수 있습니다.

열 관리 (Thermal Management)

GPU 는 열 스로틀링 (Thermal Throttling) 으로 온도를 제한하며, 임계치를 초과하면 강제 셧다운됩니다.

/* drivers/gpu/drm/amd/pm/amdgpu_thermal.c — 열 관리 */
struct amdgpu_thermal_controller {
    int min_temp;         /* 팬 최소 동작 온도 (°C × 1000) */
    int max_temp;         /* 팬 최대 동작 온도 */
    int shutdown_temp;    /* 강제 셧다운 임계치 (보통 110-120°C) */
    int throttle_temp;    /* 스로틀링 시작 온도 (보통 85-95°C) */
    int current_temp;     /* 현재 온도 (센서 읽기) */
};

static void
amdgpu_thermal_update(struct amdgpu_device *adev)
{
    int temp = amdgpu_thermal_get_temperature(adev);

    if (temp >= adev->thermal.shutdown_temp) {
        dev_crit(adev->dev, "GPU temperature (%d°C) exceeds shutdown limit!\n", temp / 1000);
        amdgpu_device_shutdown(adev);
    } else if (temp >= adev->thermal.throttle_temp) {
        dev_warn(adev->dev, "GPU thermal throttling activated (%d°C)\n", temp / 1000);
        amdgpu_dpm_force_performance_level(adev, AMD_DPM_FORCED_LEVEL_LOW);
    }
}
열 스로틀링 증상: 게임 중 프레임이 갑자기 떨어지면 GPU 가 열 스로틀링 중일 수 있습니다. cat /sys/class/drm/card0/device/hwmon/hwmon*/temp*_input 로 온도를 모니터링할 수 있습니다.

GPU 리셋 및 복구 (Reset & Recovery)

GPU 는 복잡한 병렬 처리 장치이므로 hangs(정지), timeouts(타임아웃), errors(오류) 가 빈번하게 발생합니다. 리눅스 커널은 이러한 상황에서 GPU 리셋 을 통해 시스템을 복구하며, 가능한 한 사용자 공간의 작업을 계속 이어나갈 수 있도록 합니다.

리셋 트리거 (Reset Triggers)

트리거 유형감지 방법리셋 범위
Ring Timeout Fence 시그널 미발생 (10 초 기준) 관련 링 단위 리셋
VM Fault IOMMU 페이지 폴트(Page Fault), ECC 오류 개별 CU/Shader 단위
RAS Error ECC Uncorrectable Error, parity error 관련 IP 블록 리셋
Full GPU Reset 복구 실패 및 최종 수단 GPU 전체 콜드 리셋

GPU 리셋 플로우

/* drivers/gpu/drm/amd/amdgpu/amdgpu_device.c — GPU 리셋 */
bool
amdgpu_device_reset_sriov(struct amdgpu_device *adev, bool from_full_gpu)
{
    int ret;

    /* 1. 모든 IP 블록 프리즌 (작업 중단) */
    ret = amdgpu_device_ip_freeze(adev);
    if (ret)
        return false;

    /* 2. RAS 에러 클리어 (ECC 등) */
    amdgpu_ras_reset_all_error_count(adev);

    /* 3. BACO 리셋 (Board Active Chip Off) — 전력 완전 차단 */
    ret = amdgpu_device_baco_reset(adev);
    if (ret)
        goto unfreeze;

    /* 4. 모든 IP 블록 재초기화 */
    ret = amdgpu_device_ip_resume(adev);
    if (ret)
        goto error;

    /* 5. VRAM 테스트 — 메모리 손상 여부 확인 */
    ret = amdgpu_vram_test(adev);
    if (ret) {
        dev_err(adev->dev, "VRAM test failed after reset!\n");
        goto error;
    }

    return true;

error:
    amdgpu_device_fini_hw(adev);
unfreeze:
    amdgpu_device_ip_unfreeze(adev);
    return false;
}
코드 설명
  • 8-11 행 모든 IP 블록을 "freezing"하여 새로운 작업 제출을 막습니다. 이는 리셋 중 추가적인 커맨드가 들어가는 것을 방지합니다.
  • 14-15 행 RAS(Reliability, Availability, Serviceability) 에러 카운터를 초기화합니다. ECC 오류 기록을 클리어합니다.
  • 18-22 행 BACO 리셋은 GPU 의 전력을 완전히 차단했다가 켜는 "hard reset"입니다. PCIe 링크도 재협상됩니다.
  • 26-30 행 리셋 후 모든 IP 블록을 다시 초기화합니다. 이 과정에서 펌웨어도 재로드됩니다.
  • 33-38 행 VRAM 테스트로 메모리 손상 여부를 확인합니다. 실패 시 드라이버는 더 이상 복구를 시도하지 않습니다.
GPU 리셋 상태 전이 (State Machine) Normal 작업 처리 중 Fence 신호 정상 Timeout Detected Fence 미시그널 (10 초) drm_sched_timeout() 타임아웃 GPU Reset BACO / IP Reset 강제 리셋 리셋 시작 VRAM Test 메모리 손상 검사 amdgpu_vram_test() 검사 Recovery Success 등록된 작업 재개 게임 재개 가능 Recovery Failed VRAM 손상 / 리셋 실패 강제 종료 PASS FAIL 다시 Normal 전이
GPU 리셋은 타임아웃 감지 부터 VRAM 테스트까지 여러 단계를 거치며, 성공 시 작업을 재개합니다.

리셋의 영향

리셋 범위소요 시간데이터 손실재개 가능성
Ring Reset10-50ms트랜지션 잃음높음 (게임 재개)
Engine Reset50-200ms트랜지션 및 컨텍스트 손실중간 (앱 재기동)
Full GPU Reset200-1000ms모든 컨텍스트 손실낮음 (화면 꺼짐)
PCIe Reset1-5 초시스템 전체 영향최소 (호스트 리붓 필요)
리셋 횟수 확인: cat /sys/kernel/debug/dri/0/amdgpu_reset_history로 과거 GPU 리셋 이력을 확인할 수 있습니다. 리셋이 자주 발생한다면 드라이버 버그 또는 하드웨어 고장을 의심해야 합니다.

DRM Accel 서브시스템 (비그래픽 가속기)

전통적으로 DRM(Direct Rendering Manager)은 그래픽 출력을 담당하는 GPU만을 관리했으나, 현대 SoC와 x86 플랫폼에는 그래픽 파이프라인 없이 연산만 수행하는 가속기(Accelerator)가 늘어나면서 커널 6.2에서 drivers/accel/ 트리와 /dev/accel/accel* 노드가 도입되었습니다. DRM의 버퍼·fence·스케줄러 인프라를 재사용하되, 디스플레이와 관련된 KMS 경로를 완전히 제거한 경량 경로입니다.

분리 이유: NPU(Neural Processing Unit)와 AI 가속기는 화면 출력이 없으므로 connector/CRTC/plane을 가질 수 없고, /dev/dri/cardN의 master 권한 모델도 맞지 않습니다. Accel 노드는 render node와 유사한 비특권 접근을 기본으로 삼아 사용자 공간(User Space) 컨테이너(Container)·세션 관리자와 잘 어울립니다.

커널 트리에 상주하는 주요 Accel 드라이버

드라이버하드웨어머지 커널특징
drivers/accel/habanalabs Intel(구 Habana) Gaudi / Gaudi2 / Gaudi3 5.18 이전(이전은 misc) 데이터센터 AI 학습 가속기. Accel 서브시스템 1호 드라이버
drivers/accel/ivpu Intel Core Ultra 내장 NPU (Meteor Lake 이후) 6.3 저전력 클라이언트 NPU. MTL/ARL/LNL/PTL 순차 확장
drivers/accel/qaic Qualcomm Cloud AI 100 6.5 AI Core(AIC) PCIe 카드. 데이터센터 추론 가속
drivers/accel/amdxdna AMD Ryzen AI NPU (XDNA/Phoenix 이후) 6.14 2025년 3월 머지. Ryzen 7040/8040 Phoenix·Hawk·Strix
drivers/accel/rocket Rockchip RK3588 NPU (RKNN) 6.18 (2025년 12월) Tomeu Vizoso 가 리버스 엔지니어링한 벤더 의존 없는 오픈 드라이버. Mesa 25.3 사용자 공간 코드와 연동

각 Accel 드라이버의 상세 아키텍처, 컴파일러 스택, DMA-BUF 연계는 NPU 문서에서 다룹니다. 최근 몇 년간 Accel 드라이버가 꾸준히 추가되면서, NPU 하드웨어 다변화가 본격화되고 있습니다. 다만 개별 드라이버의 정확한 공개 시점과 머지 여부는 메인라인 릴리스 노트를 다시 확인하는 편이 안전합니다.

Accel UAPI와 일반 DRM UAPI의 공통·차이점

항목DRM (GPU)Accel (NPU 등)
노드/dev/dri/card*, /dev/dri/renderD*/dev/accel/accel*
KMS 객체CRTC/plane/encoder/connector 있음없음 (디스플레이 경로 제거)
Master/권한primary는 capability 기반 master 필요기본이 비특권 render 모델
BO(Buffer Object)GEM shmem / TTM / VRAM helperGEM shmem 또는 드라이버 고유 BO
스케줄러drm_sched 또는 펌웨어(Firmware) 스케줄러(GuC 등)드라이버 자체 워크 큐 또는 drm_sched 재사용
공유 UAPIDMA-BUF, dma_fence, sync_file, syncobj(Sync Object)

Rust GPU 드라이버 생태계

2025년은 Rust 언어가 리눅스 커널 GPU 서브시스템에 본격 도입된 분기점입니다. 메모리 안전 언어로 GPU 드라이버를 작성하려는 흐름은 Apple Silicon에서 시작되어, NVIDIA GSP 드라이버(Nova)가 메인라인에 합류하면서 가속됐습니다. 기존 C 기반 DRM 인프라는 그대로 유지하면서, 새 드라이버가 DRM 바인딩을 Rust로 감싸는 방식으로 확장됩니다.

Nova — NVIDIA GSP 기반 Rust DRM 드라이버 (커널 6.15+)

Nova는 NVIDIA GeForce RTX 20(Turing) 이후 세대의 GPU System Processor(GSP) 기반 GPU를 위한 새 드라이버로, Red Hat의 Danilo Krummrich가 주도하여 2025년 5월 커널 6.15에 drivers/gpu/drm/nova/가 머지됐습니다. 기존 Nouveau를 대체하는 후속 드라이버를 목표로 하며, 현재는 초기 코어 컴포넌트와 프로젝트 문서만 머지된 실험 단계입니다. 2025년 하반기에는 NVIDIA 소속 엔지니어가 공동 메인테이너로 합류했습니다.

Nova 설계 원칙:
  • GSP 우선 — GPU 내부 RISC-V 기반 마이크로컨트롤러에 펌웨어(Firmware)로 초기화·스케줄링을 위임하므로, 드라이버는 주로 RPC 래퍼가 됩니다.
  • Rust 추상화kernel::drm 크레이트로 device/file/gem 래퍼를 제공하며, unsafe 경계는 최소화합니다.
  • Nouveau와 공존 — 당분간 Nouveau가 실사용 드라이버로 남고, Nova는 대체 준비가 완료될 때까지 개발 브랜치로 병행합니다.
  • 문서 경로Documentation/gpu/nova/https://docs.kernel.org/gpu/nova/에 공식 설명이 존재합니다.

Asahi AGX — Apple Silicon GPU 드라이버

Apple M1/M2/M3/M4 시리즈의 내장 GPU인 AGX는 Asahi Linux 프로젝트에서 Rust로 작성한 드라이버로 리눅스에서 구동됩니다. AGX 드라이버는 DRM 서브시스템용 Rust 바인딩을 실제 production-level로 처음 도입한 사례로, Mesa의 Honeykrisp(Vulkan) / Gallium AGX(OpenGL 4.6, ES 3.2) 드라이버와 짝을 이룹니다. 현재 업스트림 머지 목표로 AsahiLinux/linuxgpu/rust-wip 브랜치에서 재작성이 진행 중입니다.

Rust DRM 바인딩의 공통 기반

두 드라이버는 공통으로 다음 Rust 추상화에 의존합니다:

이들 크레이트는 기존 C API를 그대로 호출하므로 ABI 변경 없이 공존하며, unsafe 블록은 FFI 경계에만 남겨 안전성을 확보합니다.

drm_panic — 커널 패닉(Kernel Panic) 화면 인프라

드라이버가 Wayland·compositor 없이 DRM 프레임버퍼만 보유한 상태에서도 커널 패닉(Kernel Panic) 시 사용자에게 읽을 수 있는 메시지를 남기는 구조가 2024년 커널 6.10에서 추가되었습니다. fbcon(Frame Buffer Console)이 없거나 VT가 꺼진 환경에서도 화면에 패닉 내용을 그려주며, Fedora와 Arch 계열처럼 이를 적극 도입한 배포판이 있습니다. 다만 2026년 4월 기준으로 배포판별 기본 활성 범위와 사용자 노출 방식은 릴리스별로 다를 수 있으므로 해당 배포판 문서를 함께 확인하는 편이 안전합니다.

동작 원리

패닉 시 드라이버가 등록한 drm_panic 콜백(Callback)이 호출되어, fence·mutex 없이 MMIO만으로 프레임버퍼를 직접 갱신합니다. 따라서 패닉 루틴은 일반 드라이버 경로와 완전히 분리된 lock-free·interrupt-safe 구현이어야 합니다.

/* include/drm/drm_panic.h */
struct drm_panic_scanout {
    void        *vaddr;      /* 직접 접근 가능한 프레임버퍼 포인터 */
    unsigned int pitch;      /* 라인 당 바이트 */
    unsigned int width, height;
    u32          format;     /* DRM_FORMAT_* */
};

struct drm_plane_helper_funcs {
    ...
    int (*get_scanout_buffer)(struct drm_plane *, struct drm_panic_scanout *);
    void (*panic_flush)(struct drm_plane *);
};

지원 드라이버 현황 (2026년 기준)

드라이버지원 시작 커널비고
simpledrm, mgag200, ast6.10최초 지원. 간단한 라이너 프레임버퍼 드라이버
i915, xe6.12~6.14Intel 클라이언트 GPU 지원. Panic 시 Intel CSE와 협조
amdgpu6.14DCN 기반 디스플레이에서 panic 플러시(Flush) 지원
nouveau진행 중Jocelyn Falempe가 작업 중
주의: 드라이버가 get_scanout_buffer를 구현하지 않으면 패닉 화면이 뜨지 않고 이전 화면이 얼어붙은 상태로 남습니다. 또한 일부 AMD GPU에서는 DCN 상태에 따라 panic 화면이 깨져 보일 수 있는 이슈가 보고되어 지속 개선 중입니다.

GPU 가상화 (Virtualization)

가상 머신(VM)과 컨테이너에서 GPU 를 활용하려는 수요가 커지면서, 리눅스는 여러 계층의 GPU 가상화 방식을 지원합니다. 각 방식은 성능 · 격리(Isolation) · 공유 밀도의 균형점이 다릅니다. 크게 API 포워딩, DRM native context(vDRM), 하드웨어 분할(SR-IOV), 전체 패스스루(Passthrough)로 나뉩니다.

방식매개 계층대표 구현특징
API 포워딩 고수준 GL/Vulkan API Virgl(OpenGL), Venus(Vulkan) — virtio-gpu + virglrenderer 호스트가 API 호출을 번역. 이식성 높으나 CPU 오버헤드(Overhead)와 코드 복잡도 큼
DRM native context (vDRM) 커널 드라이버 UAPI(저수준) virtio-gpu drm_native_context=on 게스트가 호스트 GPU 를 네이티브처럼 인식. API 포워딩보다 CPU 오버헤드·코드량 적음
SR-IOV 분할 PCIe 하드웨어 VF(Virtual Function) AMD MxGPU, Intel Xe SR-IOV 하드웨어가 직접 다중 VF 로 분할. 높은 성능과 격리, 단 지원 GPU 한정
전체 패스스루 PCI 디바이스 전체 VFIO-PCI GPU 한 장을 VM 하나에 독점 할당. 최고 성능이나 공유 불가

DRM native context (vDRM)

vDRM(virtual DRM)은 Virgl/Venus 처럼 고수준 그래픽 API 를 매개하는 대신, 리눅스 커널 드라이버의 UAPI(ioctl) 수준에서 매개합니다. 따라서 게스트 안의 GL/Vulkan 애플리케이션은 가상 GPU 를 실제 호스트 GPU 처럼 직접 다루며, 중간 번역 단계가 줄어 CPU 오버헤드와 구현 복잡도가 모두 낮아집니다. QEMU 에서는 -device virtio-gpu-gl,drm_native_context=on 옵션으로 활성화합니다.

vDRM 컨텍스트는 GPU 드라이버마다 호스트·게스트 양쪽 구현이 필요합니다. 2025년 기준 업스트림 현황은 다음과 같습니다:

드라이버하드웨어상태
FreedrenoQualcomm Adreno (SoC GPU)완전 업스트림
AMDGPUAMD Radeon완전 업스트림
Intel (i915)Intel GPU머지 리퀘스트(Merge Request) 진행 중
AsahiApple Silicon GPU부분 머지

SR-IOV 와 하드웨어 분할

SR-IOV(Single Root I/O Virtualization)는 PCIe 표준 기능으로, 하나의 물리 GPU(PF, Physical Function)를 여러 개의 VF(Virtual Function)로 분할하여 각 VM 에 거의 네이티브에 가까운 성능으로 할당합니다.

레거시 mediated passthrough: 과거 Intel GVT-g(i915 기반 vfio-mdev 매개 패스스루)는 중간 세대 Intel GPU 에서 VF 없이 가상 GPU 를 나누던 방식이었으나, 현재는 deprecated 되어 신규 플랫폼에서는 Xe SR-IOV 로 대체되었습니다. GPU 가상화 경로는 하드웨어 세대마다 빠르게 바뀌므로 대상 GPU 의 최신 드라이버 문서를 확인하는 편이 안전합니다.

2025년부터 2026년 상반기까지 GPU·가속기 서브시스템에 머지된 주요 기능을 커널 버전별로 요약합니다. 배포판 선택·드라이버 포팅 계획에 참고할 수 있습니다.

관련 연혁: GPU / DRM 변경 이력

3대 하이라이트

  1. Rust의 본격 도입 — Nova(NVIDIA)·Asahi AGX(Apple)·Tyr(Arm) 등 Rust 기반 DRM 드라이버가 잇따라 제안되고, kernel::drm 바인딩이 안정화 경로에 들어섰습니다.
  2. 가속기 생태계 확장 — AMDXDNA(Ryzen AI)·Rockchip Rocket(RK3588)에 이어, 2026년에도 최소 2종의 새 NPU 드라이버가 예정되어 Accel 서브시스템이 GPU 못지 않은 규모로 성장 중입니다.
  3. 색 파이프라인·동기화 현대화 — KMS Color Pipeline API(HDR), linux_drm_syncobj_v1(Wayland explicit sync), DMEM cgroup(VRAM 제한), Fair DRM Scheduler 등으로 게임·HDR·컨테이너 워크로드에서의 체감 품질이 크게 개선됐습니다.

커널 버전별 주요 변경사항 (2025~2026)

커널 버전출시 시기주요 변경사항
6.15 2025년 3~4월
  • Intel Xe SVM — Shared Virtual Memory 메인라인 지원. CPU-GPU 메모리 공유 성능 향상
  • NOVA 초기 코드 — Rust 기반 NVIDIA 오픈소스 커널 드라이버 초기 코드 머지
  • Intel Xe EU Stall Sampling — EU 스톨 샘플링 지원
  • appletbdrm — Apple Touch Bar 지원 (M1/M2 MacBook)
  • survivability mode — Intel Xe GPU 생존 모드 도입
  • Intel Battlemage/Arc GPU 온도/hwmon 지원
6.16 2025년 5~6월
  • NVIDIA Blackwell/Hopper Nouveau — 초기 GSP 펌웨어 기반 지원
  • Asahi UAPI 헤더 — Apple Silicon 드라이버 UAPI 헤더 커널 트리 추가
  • Rust 추상화 확장 — nova, Asahi 등 Rust 기반 드라이버를 위한 DRM 추상화 추가
  • Intel Xe Fan Speed 지원, Panther Lake Xe3 준비
6.17 2025년 8~9월
  • Intel Xe DP MST DSC — DisplayPort Multi-Stream Transport fractional link BPP 지원
  • Panel Replay + Adaptive Sync — 동시 지원
  • Double-buffered LUT — Panther Lake용 레지스터 지원
  • Flip-queue 준비 — 플립 큐 지원 준비
  • xe_migrate_access_memory 수정 — 메모리 접근 수정
  • amdgpu VRAM 예약 수정, SRIOV-PF VF LMEM BAR 크기 설정
6.18 2025년 12월 (LTS)
  • Nouveau GSP 기본화 — Turing/Ampere GPU 에서 GSP 펌웨어(Firmware)를 기본 사용하여 안정성·전원 관리(Power Management) 개선
  • Rocket · Tyr 드라이버 메인라인 — Rockchip RK3588 NPU(Rocket)와 Arm Mali(Tyr, Rust) 가속기 드라이버 합류
  • amdgpu — GEM 객체 checkpoint/restore, VCN/VPE per-queue 리셋, eDP ALPM 지원
  • Intel Xe — 지원 플랫폼에서 SR-IOV PF 기본 활성, GPU SVM madvise, power_profile sysfs 인터페이스
6.19 2026년 2월 8일 (6.x 마지막)
  • KMS Color Pipeline API — HDR·색 변환을 위한 표준 컬러 파이프라인(Pipeline) UAPI 메인라인 진입
  • 초기 Intel Xe3P — Nova Lake 내장 GPU 및 Crescent Island AI 가속기 초기 enablement
  • AMD GCN 1.0/1.1 amdgpu 기본화 — Southern Islands·Sea Islands 구형 GPU 가 레거시 radeon 대신 amdgpu 를 기본 사용
7.0 2026년 4월 12일
  • 버전 점프 — 6.19 다음으로 메이저 번호가 7.0 으로 올라간 첫 릴리스(기능적 단절 아님)
  • AMD — GFX 11.5.4(RDNA 3.5 refresh), 초기 GFX 12.1, AMDKFD per-context 지원
  • Intel Xe — SR-IOV PF MERT, VF 마이그레이션, multi-device SVM, Battlemage FBC(프레임버퍼 압축), Nova Lake 디스플레이
  • Nova — NVIDIA Turing GPU 지원을 향한 준비 지속
7.1 병합 창 진행 중 (2026년 6월 출시 예정)
  • Intel Xe — Xe3P_LPG·Nova Lake P 초기 enablement, VM_BIND DECOMPRESS, vRAM OOM 동작 개선
  • AMD — Sea Islands/GCN 1.1 APU(Kaveri)에서 Display Core(DC) 활성으로 GCN 1.0/1.1 전환 마무리, DCN 4.2 디스플레이
  • Nouveau — NVIDIA GA100 가속기 초기 지원
  • MSM — Snapdragon X2 노트북의 Adreno 840·X2-85 GPU 선점(Preemption) 지원
  • Rust DRM 추상화와 Nova 기능 대폭 추가 (Turing 지원이 이 사이클에 준비될 가능성)
커널 버전 번호: 6.19(2026-02-08)가 6.x 시리즈의 마지막이며, Linus Torvalds 가 다음 릴리스를 7.0 으로 올렸습니다. 7.0(2026-04-12)은 버전 번호만 큰 릴리스일 뿐 기능적 단절이나 ABI 변경을 의미하지 않습니다. 7.1 은 본 문서 작성 시점(2026년 5월) 기준 병합 창이 진행 중이므로, 정확한 기능 목록은 출시 후 릴리스 노트로 재확인하는 편이 안전합니다.

참고자료

커널 소스 참고 경로:
  • drivers/gpu/drm/ — DRM 코어 + 모든 GPU 드라이버
  • drivers/accel/ — compute accelerator 드라이버
  • include/drm/ — DRM 헤더 파일
  • include/uapi/drm/ — 유저 공간 API (ioctl, 구조체)
  • drivers/dma-buf/ — DMA-BUF 프레임워크
  • Documentation/gpu/ — 커널 공식 GPU 문서
  • Documentation/accel/ — 커널 공식 accelerator 문서
우선적으로 볼 1차 문서:

이 주제와 관련된 다른 문서를 더 깊이 이해하고 싶다면 다음을 참고하세요.