2010-03-30 24 views
10

Czytałem o tym, co dzieje się po przechwyceniu pakietów przez karty sieciowe, a im więcej czytam, tym bardziej jestem zdezorientowany.Co dzieje się po przechwyceniu pakietu?

Po pierwsze, przeczytałem, że tradycyjnie, po przechwyceniu pakietu przez kartę NIC, zostaje on skopiowany do bloku pamięci w przestrzeni jądra, a następnie do przestrzeni użytkownika dla dowolnej aplikacji, która następnie działa na danych pakietowych . Potem czytałem o DMA, gdzie NIC bezpośrednio kopiuje pakiet do pamięci, omijając procesor. Czy NIC -> pamięć jądra -> Przepływ pamięci w przestrzeni użytkownika jest nadal ważny? Czy większość kart sieciowych (np. Myricom) korzysta z DMA, aby poprawić szybkość przechwytywania pakietów?

Po drugie, czy funkcja RSS (skalowanie strony odbioru) działa podobnie w systemach Windows i Linux? Mogę tylko znaleźć szczegółowe wyjaśnienia, jak działa RSS w artykułach MSDN, gdzie mówią o tym, jak działa RSS (i MSI-X) na Windows Server 2008. Ale ta sama koncepcja RSS i MSI-X powinna nadal obowiązywać dla systemów Linux, prawda ?

Dziękuję.

Pozdrawiam, Rayne

+1

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. –

+0

. Tak więc w dzisiejszych czasach, gdy NIC przechwyci pakiet, zostanie on bezpośrednio skopiowany do pamięci (użytkownika)? – Rayne

+3

@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

Odpowiedz

12

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:

  1. przy inicjalizacji sterownika, będzie przeznaczyć pewną liczbę buforów i dać je doNIC.
  2. 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.
  3. 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)
  4. 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.