Zmiany w Ion ABI

Urządzenia dostarczane z jądrem 4.14 i nowszym dotknięte są poważną refaktoryzacją modułu jądra Ion , który wiele implementacji alokatora pamięci graficznej (gralloc) dostawcy wywołuje w celu przydzielenia buforów pamięci współdzielonej. Ten artykuł zawiera wskazówki dotyczące migracji starszego kodu dostawcy do nowej wersji Ion i omawia możliwe przyszłe awarie interfejsu binarnego aplikacji (ABI).

O Ionie

Ion jest częścią drzewa pomostowego, w którym trwają prace nad jądrem. Podczas testowania interfejs ABI łączący przestrzeń użytkownika z jądrem oprogramowania Ion może pękać między głównymi wersjami jądra. Chociaż awarie Ion ABI nie mają bezpośredniego wpływu ani na zwykłe aplikacje, ani na już uruchomione urządzenia , dostawcy migrujący do nowych głównych wersji jądra mogą napotkać zmiany, które wpływają na wywoływanie kodu dostawcy w Ion. Ponadto w przyszłości mogą wystąpić przerwy w działaniu ABI, ponieważ zespół ds. systemów Android współpracuje z działem wyższego szczebla nad przeniesieniem oprogramowania Ion z drzewa tymczasowego.

Zmiany w Androidzie-4.14

Jądro 4.12 mocno zrefaktoryzowało kod jądra Iona, czyszcząc i usuwając części Iona, które nakładały się na inne struktury jądra. W rezultacie wiele starszych ioctli Ion nie jest już istotnych i zostało usuniętych.

Demontaż klientek i uchwytów Ion

Przed jądrem 4.12 otwarcie /dev/ion przydzielało klienta Ion . Ioctl ION_IOC_ALLOC przydzielił nowy bufor i zwrócił go do przestrzeni użytkownika jako uchwyt Ion (nieprzezroczysta liczba całkowita mająca znaczenie tylko dla klienta Ion, który go przydzielił). Aby zmapować bufory do przestrzeni użytkownika lub udostępnić je innym procesom, uchwyty Ion zostały ponownie wyeksportowane jako dma-buf fds przy użyciu ioctl ION_IOC_SHARE .

W jądrze 4.12 ioctl ION_IOC_ALLOC bezpośrednio wyprowadza dma-buf fds. Usunięto pośredni stan uchwytu jonowego wraz ze wszystkimi ioctlami, które zużywają lub wytwarzają uchwyty jonowe. Ponieważ dma-buf fds nie są powiązane z konkretnymi klientami Ion, ioctl ION_IOC_SHARE nie jest już potrzebny, a cała infrastruktura klienta Ion została usunięta.

Dodanie ioctls zapewniających spójność pamięci podręcznej

Przed jądrem 4.12 Ion udostępniał ioctl ION_IOC_SYNC do synchronizacji deskryptora pliku z pamięcią. Ten ioctl był słabo udokumentowany i nieelastyczny. W rezultacie wielu dostawców wdrożyło niestandardowe ioctl do konserwacji pamięci podręcznej.

Jądro 4.12 zastąpiło ION_IOC_SYNC DMA_BUF_IOCTL_SYNC ioctl zdefiniowanym w linux/dma-buf.h . Wywołaj DMA_BUF_IOCTL_SYNC na początku i na końcu każdego dostępu do procesora, z flagami określającymi, czy te dostępy są odczytem i/lub zapisem. Chociaż DMA_BUF_IOCTL_SYNC jest bardziej szczegółowy niż ION_IOC_SYNC , zapewnia przestrzeni użytkownika większą kontrolę nad podstawowymi operacjami konserwacji pamięci podręcznej.

DMA_BUF_IOCTL_SYNC jest częścią stabilnego ABI jądra i można go używać ze wszystkimi fds dma-buf, niezależnie od tego, czy zostały przydzielone przez Ion, czy nie.

Migracja kodu dostawcy do Androida 4.12+

W przypadku klientów z przestrzeni użytkownika zespół ds. systemów Android zdecydowanie zaleca używanie biblioteki libion ​​zamiast wywołań ioctl() w otwartym kodzie. Począwszy od Androida 9, libion ​​automatycznie wykrywa Ion ABI w czasie wykonywania i próbuje zamaskować wszelkie różnice między jądrami. Jednak wszelkie funkcje libion, które tworzyły lub zużywały uchwyty ion_user_handle_t , nie działają już po jądrze 4.12. Możesz zastąpić te funkcje następującymi równoważnymi operacjami na dma-buf fds, które działają na wszystkich dotychczasowych wersjach jądra.

Starsze wywołanie ion_user_handle_t Równoważne wywołanie dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) N/A (to wywołanie nie jest potrzebne w przypadku 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) N/A (to wywołanie nie jest potrzebne w przypadku 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, ...);

W przypadku klientów wbudowanych w jądro , ponieważ Ion nie eksportuje już żadnych interfejsów API skierowanych do jądra, sterowniki, które wcześniej korzystały z wbudowanego w jądro interfejsu API jądra Ion z funkcją ion_import_dma_buf_fd() muszą zostać przekonwertowane, aby korzystać z wbudowanego w jądro interfejsu API dma-buf z dma_buf_get() .

Przyszłe awarie Ion ABI

Zanim Ion będzie mógł zostać przeniesiony z drzewa pomostowego, w przyszłych wersjach jądra może być konieczne ponowne złamanie Ion ABI. Zespół ds. systemów Android nie spodziewa się, że te zmiany wpłyną na urządzenia uruchamiane z następną wersją Androida, ale takie zmiany mogą mieć wpływ na urządzenia uruchamiane z kolejnymi wersjami Androida.

Na przykład społeczność wyższego szczebla zaproponowała podzielenie pojedynczego węzła /dev/ion na wiele węzłów przypadających na stertę (np. /dev/ion/heap0 ), aby umożliwić urządzeniom stosowanie różnych zasad SELinux do każdej sterty. Jeśli ta zmiana zostanie zaimplementowana w przyszłej wersji jądra, spowoduje to uszkodzenie Ion ABI.