# Dockerfile
FROM scratch
RUN ~~
CMD ["", ""]

# image 
# 생성, 조회, 삭제
docker build -t {image_name} .
docker images
docker rmi {image id}

# container 생성, 조회, 삭제, 시작
docker create -i --name {container_name} {image_name}
docker container ls 
docker rm {container id}
docker start {container_name}

# container 생성 + 시작
docker run -d -it --name {container_name} {image_name}

# cgroup 설정
docker run --cgroup-parent={cgroup_path} {image_name}

# 명령어 전달
docker exec -it {container_id} {command}
# 쉘 접속
docker attach -it {container_id}
docker run --attach stdout {image_name}
# 포트 포워딩 
docker run -p <host_port>:<container_port> {image_name}

 

'컴퓨터 과학 > 운영체제' 카테고리의 다른 글

Cgroups (Control Groups)  (0) 2024.05.17
Kernel DMA API  (0) 2024.04.24

#1 개념

1-1. 배경

  Cgroups는 2006년 Google의 "Process Containers" 프로젝트를 통해 만들어졌으며, 프로젝트는 다음과 같은 목적으로 시작되었다.

  • 리소스 격리: 다수의 프로세스가 동시에 실행되는 환경에서 각 프로세스가 시스템 자원을 공유하고 사용할 때 발생하는 리소스 경합으로 인한 성능 저하를 방지하기 위한 프로세스 격리 및 자원 사용량 제한
  • 보안: 악성 코드나 악의적인 프로그램이 시스템에 액세스 하여 피해를 입히는 것을 방지하기 위해, 프로세스를 격리된 환경에서 실행
  • 자원 관리의 최적화: 프로세스 간의 자원 사용을 효율적으로 관리하고 최적화하기 위해 자원 모니터링 및 사용량 제한

1-2. 정의

  Cgroups는 작업셋의 집약/파티셔닝을 제공하는 메커니즘으로 하나 또는 그 이상의 서브 시스템을 파라미터 셋으로 연관시키는 역할을 한다. 서브 시스템은 작업 그룹의 사용을 효과적으로 만들어주는 모듈로, 일반적으로 자원을 스케쥴링하고 그룹 별 제한을 적용하는 등의 작업을 수행하는 "resource controller"이다. 계층은 트리에 배열된 cgroup의 집합으로, 시스템의 모든 작업이 cgroup의 집합 중 하나에 포함되도록 한다. 각 서브 시스템은 해당 cgroup의 system-specific state와 cgroup 가상 파일 시스템의 인스턴스를 가지고 있다.

그림 1. 서브 시스템의 종류

#2 사용법

2-1. Basic Usage

  Cgroup과 서브시스템은 기본적으로 쉘 명령어를 사용하여 조작할 수 있으며, 가상 파일시스템을 통해 동작한다.

# To mount a cgroup hierarchy with all available subsystems
mount -t cgroup {group_name} /sys/fs/cgroup

# mount tmpfs on /sys/fs/cgroup
# create direcotries for each cgroup resource
mount -t tmpfs cgroup_root /sys/fs/cgroup
mkdir /sys/fs/cgroup/rg1

# mount a hierarchy with cpuset and memory subsystem
mount -t cgroup -o cpuset,memory hier1 /sys/fs/cgroup/rg1

2-2. Attaching process

echo PID > tasks

 

 

참고 자료

 

 

 

'컴퓨터 과학 > 운영체제' 카테고리의 다른 글

Docker Script  (0) 2024.05.17
Kernel DMA API  (0) 2024.04.24

Direct Memory Access

#1 CPU and DMA addresses

  DMA API에서 사용되는 주소 공간은 3가지가 있다. 각각의 주소 공간들은 모두 CPU, 메모리, 디바이스의 관점에서 주소 공간을 정의하여 메모리의 주소를 나타내기 위해 사용한다. 

  • Bus Address Space
    • 디바이스가 메모리에 접근하기 위해 사용하는 주소 공간
    • MMIO나 DMA를 사용할 때 주로 사용
    • IOMMU에 의해 메모리 주소에 매핑되거나 오프셋이 직접 매핑되어 사용
  • Physical Address Space
    • CPU가 접근하는 메모리의 물리 주소를 나타내는 주소 공간
    • 일반적으로 virtual address space와 매핑되어 사용
  • Virtual Address Space
    • CPU가 가상 메모리를 위해 사용하는 주소 공간
    • kmalloc(), vmalloc()과 같은 인터페이스로 반환되는 void * 형식의 주소

그림 1. Address Mapping 예

   

  각각의 주소 공간이 서로 매핑이 되어야 CPU가 디바이스의 메모리에 접근하고, 디바이스가 메모리에 접근할 수 있게 된다. 주소 공간을 매핑하는 방법은 크게 2가지가 있다. 먼저, PCIe 디바이스가 BAR를 가지고 있는 경우 커널은 BAR의 주소(A)를 읽어 호스트 브릿지를 통해 물리 메모리 주소(B)로 변환한다. 물리 메모리 주소(B)는 /proc/iomem 파일에 구조체 형식으로 정의되어 저장된다. 드라이버가 디바이스에게 요청할 때는 ioremap() 함수를 통해 물리 메모리 주소 (B)를 가상 메모리 주소(C)로 치환하여 사용한다.

  만약 디바이스가 DMA를 지원하는 경우, 드라이버는 먼저 kmalloc()과 같은 함수를 통해 물리 메모리에 버퍼를 할당(Y)하고 가상 주소를 매핑하여 해당 주소(X)를 반환한다. 그리고 버스 주소 공간과 매핑하기 위해 IOMMU를 통해 버스 주소(Z)를 물리 메모리 주소(Y)로 변환한다. 예를 들어 dma_map_single()과 같은 함수로 가상 주소(X)를 IOMMU 매핑을 통해 버스 주소(Z)와 매핑 후 반환할 수 있다. 

  DMA API는 microprocessor와 독립적으로 동작하기 때문에 DMA API를 사용할 때는 특정 버스의 DMA API보다 일반 DMA API를 사용하기를 커널 공식 문서에서는 권장한다.

#2 DMA'able memory

  일반적인 페이지 할당자(__get_free_page*(), kmalloc(), kmem_cache_alloc())을 이용하여 반환받은 가상 주소는 DMA 메모리 영역으로 사용할 수 있다. 하지만 vmalloc()으로 메모리를 할당한 경우, 가상 주소는 연속적이나 물리 메모리 주소가 연속적이지 않을 수 있기 때문에 이를 맞춰주어야 하는 번거로움이 있다. 그리고 이런 메모리 영역은 DMA와 물리적으로 작동할 수 있더라도, I/O 버퍼가 캐시 라인으로 정렬되어 있음을 보장하여야 한다. 그렇지 않으면 CPU와 DMA-incoherent 캐시의 캐시라인 공유 문제가 발생한다. (CPU는 한 word를 기준으로 I/O가 이루어지고 DMA는 하나의 캐시라인을 기준으로 I/O가 이루어지기 때문에 다른 캐시 라인이 덮어쓰일 수 있다.)

#3 DMA address capacity

  디바이스의 관점에서 DMA는 버스 주소 공간을 사용하지만 이 주소는 시스템의 주소 체계에 의해 제한될 수 있다. 예를 들어, 디바이스가 64비트 체계를 사용하더라도, 32비트 체계의 시스템을 사용함으로써 주소 공간의 크기가 32비트로 제한될 수 있다. 따라서 아래 함수를 통해 DMA mask를 설정하여 DMA 주소 체계를 매핑할 필요가 있다.

int dma_set_mask_and_coherent(struct device *dev, u64 mask); // set up streaming mask & coherent mask
int dma_set_mask(struct device *dev, u64 mask); // set up streaming mask
int dma_set_coherent_mask(struct device *dev, u64 mask); // set up coherent mask

#4 DMA direction

  DMA 방향은 아래와 같으며, 방향을 알면 성능 최적화를 위해 최대한 맞춰 설정하기를 권장한다. 또한, 특정 플랫폼에서는 page protection와 같은 write 권한 이슈가 있기 때문에 방향을 구체적으로 설정하기를 권장한다.

DMA_BIDIRECTIONAL // memory <-> device
DMA_TO_DEVICE // memory -> device
DMA_FROM_DEVICE // memory <- device
DMA_NONE // used for debugging

 

  DMA_NONE의 경우 디버깅의 용도로 많이 사용하며, 구체적인 DMA 방향을 모를 때 사용하면 어느 방향으로 DMA가 이루어지는 지 알 수 있도록 도와준다.

#5 Types of DMA mappings

내용 추가 예정

  • Consistent DMA mappings
  • Streaming DMA mapping

 

 

참조: https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt

'컴퓨터 과학 > 운영체제' 카테고리의 다른 글

Docker Script  (0) 2024.05.17
Cgroups (Control Groups)  (0) 2024.05.17

+ Recent posts