E1000e network card freeze

Zawieszenie karty sieciowej e1000e

Wstęp

Czy zdarzyło Ci się kiedyś, że Twój serwer, który działał bez problemów przez wiele dni, nagle przestał odpowiadać na sieć? Maszyna się nie restartowała, uruchomione procesy nadal działały, ale jakby zniknęła z sieci. Dokładnie z taką sytuacją miałem do czynienia ostatniej nocy. Rano odkryłem, że serwer jest fizycznie włączony, ale kompletnie nie odpowiada na żadne zapytania sieciowe - ani ping, ani SSH, ani żadne inne usługi sieciowe.

Odkrycie problemu

Po sprawdzeniu fizycznego stanu maszyny i podłączeniu monitora oraz klawiatury, system operacyjny działał normalnie. Interfejs sieciowy jednak nie odpowiadał, nawet lokalne testy ping do innych hostów w sieci kończyły się niepowodzeniem. Czas na śledztwo.

Diagnostyka za pomocą journalctl

Pierwszym krokiem w diagnostyce problemu z siecią w systemach Linux jest sprawdzenie logów jądra. Najlepszym narzędziem do tego celu jest journalctl z odpowiednimi parametrami. Polecenie journalctl -k -b -1 pozwala sprawdzić logi jądra z poprzedniego boot’a systemu, co jest szczególnie przydatne, gdy problem wystąpił przed aktualnym uruchomieniem systemu.

journalctl -k -b -1

Parametry tego polecenia oznaczają:

  • -k (lub --dmesg) - wyświetla tylko logi jądra
  • -b -1 - pokazuje logi z poprzedniego boot’a (boot -1 oznacza poprzedni boot, -2 poprzedni przed poprzednim, itd.)

W moim przypadku logi jądra ujawniły problem z kartą sieciową e1000e na interfejsie enp0s25:

Jan 10 08:10:28 pve.localhost kernel: e1000e 0000:00:19.0 enp0s25: Detected Hardware Unit Hang:
                                        TDH                  <82>
                                        TDT                  <8e>
                                        next_to_use          <8e>
                                        next_to_clean        <81>
                                      buffer_info[next_to_clean]:
                                        time_stamp           <101fda64e>
                                        next_to_watch        <82>
                                        jiffies              <102048d40>
                                        next_to_watch.status <0>
                                      MAC Status             <80083>
                                      PHY Status             <796d>
                                      PHY 1000BASE-T Status  <3800>
                                      PHY Extended Status    <3000>
                                      PCI Status             <10>

Komunikat “Detected Hardware Unit Hang” wskazuje na zawieszenie jednostki sprzętowej karty sieciowej e1000e. Karta wielokrotnie próbowała wykryć i naprawić problem, jednak komunikaty powtarzały się co około 2 sekundy, co sugerowało, że problem nie został automatycznie rozwiązany.

Dlaczego e1000e ma ten problem?

Sterownik e1000e to sterownik dla nowszych kart sieciowych Intel (Enhanced Ethernet). W moim przypadku problem był związany z funkcją EEE (Energy Efficient Ethernet). EEE to standard, który pozwala kartom sieciowym na zmniejszenie zużycia energii poprzez przełączanie się w tryb niskiego poboru mocy podczas bezczynności. Jednak implementacja tej funkcji może powodować problemy z niektórymi kartami lub przełącznikami sieciowymi, prowadząc do zawieszenia się karty.

Rozwiązanie problemu

Krok 1: Sprawdzenie ustawień EEE

Po zidentyfikowaniu problemu z logów jądra, sprawdziłem ustawienia EEE (Energy Efficient Ethernet) na interfejsie enp0s25:

ethtool --show-eee enp0s25

Wynik pokazał, że EEE było włączone, ale nieaktywne:

EEE settings for enp0s25:
	EEE status: enabled - inactive
	Tx LPI: 17 (us)
	Supported EEE link modes:  100baseT/Full
	                           1000baseT/Full
	Advertised EEE link modes:  100baseT/Full
	                            1000baseT/Full
	Link partner advertised EEE link modes:  Not reported

Krok 2: Wyłączenie EEE

Na podstawie logów i statusu EEE, wyłączyłem funkcję Energy Efficient Ethernet:

ethtool --set-eee enp0s25 eee off

Po wyłączeniu EEE, sprawdziłem ponownie status:

ethtool --show-eee enp0s25

Wynik potwierdził wyłączenie:

EEE settings for enp0s25:
	EEE status: disabled
	Tx LPI: 17 (us)
	Supported EEE link modes:  100baseT/Full
	                           1000baseT/Full
	Advertised EEE link modes:  100baseT/Full
	                            1000baseT/Full
	Link partner advertised EEE link modes:  Not reported

Po wyłączeniu EEE interfejs sieciowy zaczął działać normalnie, co potwierdziło, że to właśnie ta funkcja była przyczyną problemu.

Krok 3: Wyłączenie TSO, GSO i GRO

Jako dodatkowe zabezpieczenie, wyłączyłem również funkcje offloading’u TSO (TCP Segmentation Offload), GSO (Generic Segmentation Offload) i GRO (Generic Receive Offload):

sudo ethtool -K enp0s25 tso off gso off gro off

Te funkcje mogą czasami powodować problemy ze stabilnością, szczególnie w połączeniu z EEE. Warto sprawdzić, czy ta zmiana poprawia stabilność karty.

Funkcje te można włączyć ponownie poleceniem:

sudo ethtool -K enp0s25 tso on gso on gro on

Zapobieganie problemom z kartą e1000e

Krok 1: Trwałe wyłączenie EEE

Aby upewnić się, że EEE pozostanie wyłączone po restarcie systemu, należy utworzyć skrypt, który będzie automatycznie wyłączał tę funkcję przy każdym starcie interfejsu sieciowego. W systemach używających systemd-networkd możemy skorzystać z mechanizmu networkd-dispatcher:

# Utworzenie katalogu, jeśli nie istnieje
sudo mkdir -p /etc/networkd-dispatcher/routable.d

# Utworzenie skryptu
sudo nano /etc/networkd-dispatcher/routable.d/50-eee-off

Zawartość skryptu:

#!/bin/bash
ethtool --set-eee enp0s25 eee off

Nadanie uprawnień wykonywania:

sudo chmod +x /etc/networkd-dispatcher/routable.d/50-eee-off

Alternatywnie, jeśli networkd-dispatcher nie jest dostępny, można użyć innych metod:

Opcja A: Użycie /etc/rc.local

# Edytuj plik /etc/rc.local (pamiętaj o dodaniu linii przed "exit 0")
sudo nano /etc/rc.local

Dodaj przed exit 0:

ethtool --set-eee enp0s25 eee off

Opcja B: Użycie NetworkManager dispatcher

Jeśli używasz NetworkManager:

sudo mkdir -p /etc/NetworkManager/dispatcher.d
sudo nano /etc/NetworkManager/dispatcher.d/50-eee-off

Zawartość:

#!/bin/bash
if [ "$1" == "enp0s25" ] && [ "$2" == "up" ]; then
    ethtool --set-eee enp0s25 eee off
fi
sudo chmod +x /etc/NetworkManager/dispatcher.d/50-eee-off

Opcja C: Utworzenie jednostki systemd

Można również utworzyć jednostkę systemd, która będzie wykonywana po starcie sieci:

sudo nano /etc/systemd/system/disable-eee.service

Zawartość:

[Unit]
Description=Disable EEE on enp0s25
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool --set-eee enp0s25 eee off
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Włączenie usługi:

sudo systemctl enable disable-eee.service
sudo systemctl start disable-eee.service

Krok 2: Trwałe wyłączenie TSO, GSO i GRO

Jeśli wyłączenie TSO, GSO i GRO pomogło, warto również ustawić te parametry na stałe. Możemy to zrobić w ten sam sposób - dodając polecenia do skryptu wyłączającego EEE:

sudo nano /etc/networkd-dispatcher/routable.d/50-eee-off

Zaktualizowana zawartość:

#!/bin/bash
ethtool --set-eee enp0s25 eee off
ethtool -K enp0s25 tso off gso off gro off

Krok 3: Weryfikacja ustawień

Po zrestartowaniu systemu, warto sprawdzić, czy ustawienia zostały poprawnie zastosowane:

# Sprawdzenie EEE
ethtool --show-eee enp0s25

# Sprawdzenie TSO, GSO, GRO
ethtool -k enp0s25 | grep -E "tso|gso|gro"

Oczekiwany wynik dla EEE:

EEE status: disabled

Dla TSO, GSO, GRO powinno być:

tcp-segmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: off

Dlaczego te ustawienia pomagają?

  • EEE (Energy Efficient Ethernet) - może powodować problemy z synchronizacją między kartą a przełącznikiem, szczególnie przy niektórych modelach przełączników lub w określonych warunkach sieciowych
  • TSO/GSO/GRO (Offloading) - te funkcje przenoszą część przetwarzania pakietów z CPU na kartę sieciową. Chociaż mogą zwiększać wydajność, czasami mogą powodować problemy ze stabilnością, szczególnie w środowisku wirtualizacji lub przy niektórych kombinacjach sprzętowych

Jeśli problem nadal występuje po wyłączeniu EEE, warto spróbować również wyłączyć offloading, co często rozwiązuje problemy ze stabilnością kart e1000e.

Podsumowanie

Problem z zawieszeniem się karty sieciowej e1000e jest znaną usterką, która może wystąpić w systemach z kartami Intel korzystającymi z tego sterownika. W moim przypadku przyczyną była funkcja EEE (Energy Efficient Ethernet), która pomimo swoich zalet w zakresie oszczędzania energii, może powodować problemy ze stabilnością.

Podstawową metodą diagnozy jest sprawdzenie logów jądra za pomocą journalctl -k -b -1, co pozwala zobaczyć, co działo się w systemie przed jego ostatnim restartem. Komunikaty “Detected Hardware Unit Hang” jednoznacznie wskazują na problem z kartą sieciową.

Rozwiązanie problemu polega na wyłączeniu funkcji EEE za pomocą ethtool --set-eee enp0s25 eee off, a następnie skonfigurowaniu systemu tak, aby to ustawienie było trwałe. W przypadku gdy to nie wystarczy, warto również wyłączyć funkcje offloading’u TSO, GSO i GRO.

Pamiętaj, że problemy z siecią mogą mieć różne przyczyny - zawsze warto sprawdzić logi systemowe i rozpocząć diagnostykę od podstawowych kroków, takich jak sprawdzenie połączenia fizycznego, konfiguracji sieciowej i logów jądra. W przypadku kart e1000e, wyłączenie EEE jest często pierwszym krokiem, który rozwiązuje problemy ze stabilnością.

Comments powered by Talkyard.