Jak proces ten odgrywa obecnie jest głównie do autora kierowcy i sprzętu , ale dla kierowców Sprawdziliśmy lub pisemne i sprzęt pracowałem z, zazwyczaj jest to sposób to działa:
- przy inicjalizacji sterownika, będzie przeznaczyć pewną liczbę buforów i dać je doNIC.
- Po odebraniu pakietu przez NIC, wyciąga następny adres z listy buforów, DMA dane bezpośrednio do niego i powiadamia kierowcę przez przerwanie.
- Sterownik dostaje przerwanie i może albo przełączyć bufor na jądro, albo przydzieli nowy bufor jądra i skopiuje dane. "Zero copy networking" jest pierwszą i oczywiście wymaga wsparcia z systemu operacyjnego. (więcej poniżej)
- Sterownik musi albo przydzielić nowy bufor (w przypadku zerowej kopii), albo ponownie użyć bufora. W obu przypadkach bufor jest zwracany do karty NIC dla przyszłych pakietów.
Bez zerowej sieci w kernelu nie jest tak źle. Zero-copy aż do przestrzeni użytkownika jest trudniejsze niż dużo. Userland pobiera dane, ale pakiety sieciowe składają się zarówno z nagłówka, jak i danych. Co najmniej, prawdziwa zerowa kopia aż do przestrzeni użytkownika wymaga wsparcia ze swojej karty NIC, aby mógł on pakować DMA do oddzielnych buforów nagłówków/danych. Nagłówki są ponownie przetwarzane, gdy jądro kieruje pakiet do miejsca docelowego i weryfikuje sumę kontrolną (dla TCP, albo w sprzęcie, jeśli obsługuje go NIC, albo w oprogramowaniu, jeśli nie, zauważ, że jeśli jądro musi obliczyć sumę kontrolną, to mogą również kopiować dane: analiza danych powoduje, że chybienia pamięci podręcznej i kopiowanie ich w innym miejscu może być bezpłatne za pomocą dostrojonego kodu).
Nawet zakładając, że wszystkie gwiazdy są wyrównane, dane nie znajdują się w buforze użytkownika po jego odebraniu przez system. Dopóki aplikacja nie poprosi o dane, jądro nie wie, gdzie skończy. Rozważmy przypadek demona wieloprocesowego, takiego jak Apache. Istnieje wiele procesów potomnych, wszystkie nasłuchują na tym samym gnieździe. Można również ustanowić połączenie, fork()
, a oba procesy są w stanie uzyskać dane przychodzące w postaci recv()
.
Pakiety TCP w Internecie to zazwyczaj 1460 bajtów ładunku (MTU z 1500 = 20 bajtowych nagłówków IP + 20 bajtowych nagłówków TCP + 1460 bajtów danych). 1460 nie jest potęgą 2 i nie będzie dopasowywał rozmiaru strony do żadnego systemu, który znajdziesz. To stwarza problemy dla ponownego złożenia strumienia danych. Pamiętaj, że TCP jest ukierunkowany strumieniowo. Nie ma rozróżnienia między zapisami nadawcy, a dwa 1000-bajtowe zapisy oczekujące na odebrane zostaną całkowicie pochłonięte w 2000 bajtowym czytaniu.
Przyjmując to dalej, weź pod uwagę bufory użytkowników. Są one przydzielane przez aplikację. Aby można było używać do zerowej kopii, bufor musi być wyrównany do strony i nie współużytkować tej strony pamięci z niczym innym. W czasie recv()
jądro mogłoby teoretycznie zmapować starą stronę z tą zawierającą dane i "przerzucić" ją na miejsce, ale jest to skomplikowane z powodu problemu ponownej konfiguracji, ponieważ kolejne pakiety będą na oddzielnych stronach. Jądro może ograniczać dane, które oddaje z powrotem do ładowności każdego pakietu, ale będzie to oznaczać wiele dodatkowych wywołań systemowych, ponownego mapowania strony i ogólnie mniejszą przepustowość.
Naprawdę tylko drapie powierzchnię na ten temat. Pracowałem w kilku firmach na początku 2000 roku, próbując rozszerzyć koncepcje zerowej kopii do przestrzeni użytkownika. Zaimplementowaliśmy nawet stos TCP w przestrzeni użytkownika i obejrzeliśmy jądro w całości dla aplikacji używających stosu, ale przyniósł on własny zestaw problemów i nigdy nie był jakością produkcji. To bardzo trudny problem do rozwiązania.
Google dla zerowej liczby kopii w sieci ... bardzo niewiele urządzeń wysokiej prędkości może tolerować podwójne kopiowanie do jądra, a następnie użytkownika. IANANG (nie jestem guru sieciowym), ale uważam, że DMA jest agresywnie używane. –
. Tak więc w dzisiejszych czasach, gdy NIC przechwyci pakiet, zostanie on bezpośrednio skopiowany do pamięci (użytkownika)? – Rayne
@Rayne yes; karta sieciowa użyje DMA do przesyłania danych bezpośrednio do pamięci fizycznej odwzorowanej na przestrzeń adresową twojego procesu (przestrzeń użytkownika). – vladr