Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

Ion ABI 변경사항

커널 4.14 이상이 설치된 기기는 다수의 공급업체 그래픽 메모리 할당자(gralloc) HAL(하드웨어 추상화 레이어) 구현이 공유 메모리 버퍼를 할당하기 위해 호출하는 Ion 커널 모듈의 주요 리팩터링의 영향을 받습니다. 이 문서에서는 기존 공급업체 코드를 새 버전의 Ion으로 이전하는 방법을 안내하고 향후 가능한 Application Binary Interface(ABI) 위반에 관해 설명합니다.

Ion 소개

Ion은 업스트림 커널의 work-in-progress 스테이징 트리의 일부입니다. 스테이징 중에는 Ion의 userspace-to-kernel ABI가 주요 커널 버전 간에 위반될 수 있습니다. Ion ABI 위반이 일반 애플리케이션이나 이미 출시된 기기에 직접 영향을 미치지는 않지만 새로운 주요 커널 버전으로 이전하는 공급업체는 Ion에 호출되는 공급업체 코드에 영향을 미치는 변경사항이 발생할 수 있습니다. 또한 Android 시스템 팀이 스테이징 트리 밖으로 Ion을 이동하기 위해 업스트림을 사용하기 때문에 향후 ABI 위반이 발생할 수 있습니다.

android-4.14의 변경사항

Kernel 4.12는 Ion 커널 코드를 크게 리팩터링하여 다른 커널 프레임워크와 겹치는 Ion 부분을 정리 및 삭제했습니다. 따라서 기존의 많은 Ion ioctl이 더 이상 관련이 없어져 삭제되었습니다.

Ion 클라이언트 및 핸들 삭제

커널 4.12 이전에는 /dev/ion을 열면 Ion 클라이언트가 할당되었습니다. IOC_ION_ALLOC ioctl은 새로운 버퍼를 할당하고 이 버퍼를 Ion 핸들(버퍼를 할당한 Ion 클라이언트에만 의미 있는 불투명 정수)로 사용자 공간에 반환했습니다. 버퍼를 사용자 공간으로 매핑하거나 다른 프로세스와 공유할 수 있도록 IOC_ION_SHARE ioctl을 사용해 Ion 핸들을 dma-buf fds로 다시 내보냈습니다.

커널 4.12에서 IOC_ION_ALLOC ioctl은 dma-buf fds를 직접 출력합니다. Ion 핸들을 사용하거나 생성하는 모든 ioctl과 함께 중간 Ion 핸들 상태가 삭제되었습니다. dma-buf fds는 특정 Ion 클라이언트에 연결되지 않으므로 IOC_ION_SHARE ioctl은 더 이상 필요하지 않고 모든 Ion 클라이언트 인프라가 삭제되었습니다.

캐시 일관성 ioctl 추가

커널 4.12 이전에 Ion은 파일 설명자를 메모리와 동기화하기 위해 ION_IOC_SYNC ioctl을 제공했습니다. 이 ioctl은 제대로 설명되지 않았으며 유연성이 부족했습니다. 따라서 많은 공급업체에서 캐시 유지 관리를 실행하기 위한 맞춤 ioctl을 구현했습니다.

커널 4.12는 ION_IOC_SYNClinux/dma-buf.h에 정의된 DMA_BUF_IOCTL_SYNC ioctl로 교체했습니다. 모든 CPU 액세스의 시작과 끝에서 이러한 액세스가 읽기 또는 쓰기인지 지정하는 플래그로 DMA_BUF_IOCTL_SYNC를 호출합니다. DMA_BUF_IOCTL_SYNCION_IOC_SYNC보다 더 상세하지만 사용자 공간에서 기본 캐시 유지 관리 작업을 더 세부적으로 관리할 수 있게 합니다.

DMA_BUF_IOCTL_SYNC는 커널의 안정적인 ABI의 일부이며 모든 dma-buf fds와 함께 사용할 수 있습니다. 이때 dma-buf fds를 Ion이 할당했는지는 상관없습니다.

공급업체 코드를 android-4.12 +로 마이그레이션

userspace 클라이언트의 경우 Android 시스템 팀에서는 ioctl() 호출을 개방 코딩하는 대신 libion을 사용하는 것을 적극 권장합니다. Android 9부터 libion은 런타임 시 Ion ABI를 자동으로 감지하고 커널 간의 차이점을 마스크하려고 합니다. 그러나 ion_user_handle_t 핸들을 생성하거나 사용했던 모든 libion 함수는 커널 4.12 이후에 더 이상 작동하지 않습니다. 이러한 함수는 dma-buf fds에 관해 동등한 다음 작업으로 교체할 수 있으며 이 작업은 지금까지 커널의 모든 버전에서 작동합니다.

기존 ion_user_handle_t 통화 상응하는 dma-buf fd 호출
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) 해당 사항 없음(dma-buf fds에는 이 호출이 필요하지 않음)
ion_map(ion_fd, buf_handle, ...) mmap(buf_fd, ...)
ion_free(ion_fd, buf_handle) close(buf_fd)
ion_import(ion_fd, buf_fd, &buf_handle) 해당 사항 없음(dma-buf fds에는 이 호출이 필요하지 않음)
ion_sync_fd(ion_fd, buf_fd) If (ion_is_legacy(ion_fd))

ion_sync_fd(ion_fd, buf_fd);

else

ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

in-kernel 클라이언트의 경우 Ion이 더 이상 커널 연결 API를 내보내지 않기 때문에 이전에 ion_import_dma_buf_fd()와 함께 in-kernel Ion 커널 API를 사용한 드라이버가 dma_buf_get()과 함께 in-kernel dma-buf API를 사용하도록 변환되어야 합니다.

향후 Ion ABI 위반

Ion이 스테이징 트리 밖으로 이동하기 전에 향후 커널 버전에서 Ion ABI를 다시 위반해야 할 수도 있습니다. Android 시스템 팀은 이러한 변경사항이 다음 Android 버전이 설치되어 출시되는 기기에는 영향을 미치지 않을 것으로 예상하지만 이러한 변경이 후속 Android 버전에서 출시되는 기기에 영향을 줄 수 있습니다.

예를 들어 업스트림 커뮤니티에서는 단일 /dev/ion 노드를 힙당 여러 노드(예: /dev/ion/heap0)로 분할하여 기기에서 각 힙에 다른 SELinux 정책을 적용할 수 있도록 합니다. 이러한 변경사항이 향후 커널 버전에서 구현되면 Ion ABI를 위반합니다.