ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SPDK] Concept - User Space Drivers
    논문 정리/Vertical optimization 2019. 9. 17. 04:26

    https://spdk.io/doc/userspace.html

    Driver 는 일반적으로 컴퓨터에 연결된 특정한 장치 (device) 를 직접 조종하는데 사용되는 소프트웨어를 의미한다. OS (리눅스 기준) 는 시스템의 메모리를 커널 스페이스와 유저 스페이스 두가지로 분리한다. 일반적으로 CPU 자체에서 이러한 기능을 지원하고, 메모리 분리를 가능토록 하는 기능을 protection ring이라고 한다. 드라이버는 일반적으로 ring level 0의 커널 스페이스에서 동작한다. SPDK는 이와 다르게 유저 스페이스에서 동작하는 드라이버들을 포함하고 있으며, 이러한 드라이버들을 통해 물리적 장치 (hardware device) 와 직접적으로 연결하고 조종하는 역할을 한다.

    유저스페이스의 드라이버가 직접 하드웨어를 조종하기 위해서는 일단 OS의 일부 권한을 양도받아야 한다. 이러한 작업은 일반적으로 (Linux 기준) sysfs에 존재하는 특정 파일에 원하는 명령을 수행하여, OS가 가지고 있는 디바이스 조종 권한을 해제하면서 획득 할 수 있다. 이후 SPDK는 리눅스에 포함되어 있는 두가지 드라이버 (ui, vfio) 중 하나에 unbind된 장치를 다시 bind 시킨다. 두 드라이버의 가장 큰 차이점은 vfio는 IOMMU를 사용할 수 있다는 점이다. SPDK DMA 설명에서 자세한 내용을 다루도록 한다.

    일단 OS 드라이버에서 unbind되고 나면 파일 시스템 등의 어떠한 커널 드라이버도 해당 장치를 접근할 수 없다. 이를 보완하기 위해서 SPDK에는 다양한 C 라이브러리가 포함되어 있다. 이 라이브러리 들에는 block device abstraction layer (bdev), block allocator(blob), 유사 파일시스템 (blobfs) 등이 있다.

    이러한 유저 스페이스 드라이버들은 PCI BAR를 원하는 프로세스에 매핑 하는 uio/fvio 기능을 이요하여, MMIO를 바로 수행할 수 있도록 한다. SPDK에 포함된 NVMe 드라이버 또한 PCI BAR mapping을 이용하여 NVMe 스펙에 맞는 초기화 과정을 수행한다.

    Interrupts

    SPDK는 인터럽트 시스템을 사용하지 않고 polling 방식을 사용한다. 이에는 여러가지 이유가 있는데 주된 이유는 아래와 같다.

    1. 현실적으로, 유저 스페이스로 하드웨어의 인터럽트를 라우팅 하는 것은 대부분의 하드웨어 설계에 적합하지 않다.
    2. 인터럽트 핸들링을 위해 필수적으로 발생해야 하는 컨텍스트 스위치는 상당한 오버헤드를 유발하고, 소프트웨어의 상태를 불안정하게 만들 수 있다.

    SPDK가 제공하는 대부분의 operation은 일반적으로 비동기로 동작하며, 사용자가 callback을 사용해서 completion 정보를 받을 수 있도록 한다. 사용가자 completion을 폴링하도록 하는 함수를 호출하면 완료 동작에 대해서 callback 함수를 호출하는 방식이다. 이러한 폴링 방식을 사용하는 NVMe는 호스트 인텔의 DDIO와 같은 기술들에 의해 자동으로 캐시내에 업데이트 되는 메모리의 completion bit정보만을 체크하게 되므로 매우 빠른 성능을 제공할 수 있다.

    Threading

    NVMe 스펙상 여러개의 큐를 사용할 수 있다. 각각의 큐는 서로간의 조정작업 없이 사용될 수 있으며 이를 이용하는 소프트웨어의 경우 여러 쓰레드에서 동시에 lock 없이 많은 명령을 보낼 수 있게 된다. 커널에서 이를 처리하는 경우에는 NVMe 장치에 대한 것 뿐만 아닌 다양한 장치에 대한 I/O를 처리해야 해서 NVMe 의 다중 큐를 처리하는데에 많은 쓰레드를 할 당 할 수 없는 경우들이 있다. 보통 커널 내부에서는 코어 1개당 큐 1개를 할당하는 방식으로 수행하여, 프로세스가 동작하는 코어가 무엇이냐에 따라서 lock이 필요하기도 하고, 해당하는 코어의 인터럽트를 중지하는 등의 비싼 작업을 수행하게 된다.

    SPDK가 제공하는 유저 스페이스 드라이버는 라이브러리 형태로 원하는 애플리케이션 마다 각각 사용할 수 있게 된다. 각 애플리케이션은 자신에게 필요한 쓰레드나 프로세스의 갯수를 정확히 알 수 있으므로, 원하는 큐의 갯수만큼 원하는 쓰레드에 할당하는 작업을 수행할 수 있다. 일반적으로 코어당 큐 한개가 할당되는 커널과 다르게, 쓰레드당 1개의 큐를 할당한다. 이 말은 각 쓰레드가 다른 쓰레드와 통신하거나 lock을 할 필요없이 자신만의 I/O를 단독적으로 수행할 수 있음을 의미한다.

Designed by Tistory.