Zlokalizuj sporadyczny błąd jądra procesora

11

Mam jądro PREEMPT 2.6.35 działające na procesorze ARMv7 o średniej prędkości. Mniej więcej raz na 100 - 125s coś powoduje, że jądro nie przetwarza niektórych sterowników związanych z dźwiękiem wystarczająco szybko, aby uniknąć niedopełnienia. Napad jest zwykle w zakresie 15-30 ms, ale może być znacznie dłuższy. Nie jest jasne, czy zatrzymanie jest całkowicie w jądrze, czy może dotyczyć planowania procesu użytkownika działającego z priorytetem w czasie rzeczywistym (SCHED_RR, 2).

Domyślam się, że istnieje (co najmniej jeden) sterownik, który nie gra dobrze z uprzedzeniem.

Niektóre dane wyjściowe strace z procesu użytkownika ilustrują pewien aspekt zarówno normalnego, jak i nienormalnego zachowania, chociaż nie jestem pewien, jak interpretować różne raporty czasowe?

Normalny przypadek:

     Ankieta 0,000518 ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3415) = 1 
     0,010202 ankieta ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 
     Ankieta 0,000585 ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 
     Ankieta 0,000302 ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3404) = 1 
     0,010706 ankieta ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3393) = 1 
     Ankieta 0,000480 ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL}, {fd = 6, wydarzenia = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3392) = 1 

W ankiecie nie występuje blokowanie danych wyjściowych na fd6, a gdy tylko fd10 jest odpytywany o wejście, następuje blok około 10 ms. Znajduje to odzwierciedlenie zarówno w raporcie o czasie trwania wywołania systemowego, jak i odstępie czasu między wywołaniami systemowymi (są one spójne).

Przypadek awarii (przykład skrajny):

     Ankieta 0,000305 ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3543) = 1 
     0,010730 ankieta ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3533) = 1 
     Ankieta 0,000475 ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL}, {fd = 6, wydarzenia = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3532) = 1 
     Ankieta 0,000329 ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3532) = 1 
     0,953349 ankieta ([{fd = 10, wydarzenia = POLLIN | POLLERR | POLLNVAL}, {fd = 6, wydarzenia = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT | POLLERR}], 2, 2578) = 1 

Zauważ, że w tym przypadku, mimo że drugie przedostatnie połączenie jest nagrywane jako zajmujące 10 ms (normalnie), jest to 953 ms przed ostatnim połączeniem.

Jakich narzędzi mogę użyć do wyśledzenia winnego?

awy
źródło
2
Punkty bonusowe za interesujące pytanie. Nie jestem pewien, jak na to odpowiedzieć, ale mam pytanie, jak prześledzić to z powrotem do użycia procesora (na przykład w przeciwieństwie do skoków w iowait)?
Bratchley,
1
Najpierw zgadnij, czy używasz JFFS2 lub YAFFS na dużej pamięci flash NAND, szczególnie jeśli nagrywasz. Wyłącz wszystko, co pisze flashować i zobacz, czy to pomoże. Jak wygląda twoja tabela procesów? Możesz użyć ftrace w ostateczności, jeśli masz zestaw narzędzi do budowy jądra.
Jonathan Ben-Avraham
sar -bu może to zrobić .. linux.die.net/man/1/sar
Grizly
Używana jest pamięć flash; karta SD z zamontowanym systemem plików ext4. I pisze, że są rzeczywiście możliwym źródłem tych problemów (ale dlaczego dokładnie?), Ale prawdopodobnie nie jedynym.
okropny

Odpowiedzi:

1

perfmoże ci pomóc. Jest to część narzędzi jądra systemu Linux.

Na przykład:

perf record -R -a -g fp -e cycles -e syscalls:sys_enter_poll -e syscalls:sys_exit_poll
#Just ctrl+c if you are done, and view ith
perf script 

Wyświetli wszystkie czasy wejścia / wyjścia syscall i parametry (takie jak strace), poda nazwę pliku binarnego wywołującego syscall i spróbuje stosu wywołań każdego procesora na pewnej częstotliwości (w tym symbole jądra). Dzięki temu możesz zobaczyć, jaki kod został wykonany podczas wywołania systemowego. W systemie wieloprocesorowym należy zwrócić uwagę na identyfikator procesora (np. [001]).

Zulan
źródło
Zastanowię się, jak zbudować perf dla platformy - dziękuję za podpowiedź.
okropny
0

Może atopmoże rzucić nieco światła na twój problem.

Może pokazywać procesy, które już się zakończyły, a także wykorzystanie procesora , pamięci , dysku i sieci .

Możesz uruchomić go interaktywnie, pozwolić na zapis do pliku tekstowego lub uruchomić go jak sarw zdefiniowanym przedziale czasowym, tworząc plik historii binarnej, do którego możesz później przejść.

Używam go, by znaleźć wieprze wszelkiego rodzaju, które trudno znaleźć :-)

trapicki
źródło