Краткий ответ : для точной задержки в ядре вы должны использовать perf probe и perf скрипт.
Подробнее : Давайте рассмотрим следующий пример.Сначала мы хотим посмотреть, какие функции используются для проверки TCP-пинг-понга (я использую netperf).
При приеме:
При передачеflow:
Итак, давайте отследим некоторые функции потока передачи (это долго, поэтому я покажу основные функции в потоке TCP).Мы можем использовать perf probe для выборки точек входа и выхода для каждой функции:
perf probe --add sock_sendmsg='sock_sendmsg'
perf probe --add sock_sendmsg_exit='sock_sendmsg%return'
perf probe --add inet_sendmsg='inet_sendmsg'
perf probe --add inet_sendmsg_exit='inet_sendmsg%return'
perf probe --add tcp_sendmsg_exit='tcp_sendmsg%return'
perf probe --add tcp_sendmsg='tcp_sendmsg'
perf probe --add tcp_sendmsg_locked='tcp_sendmsg_locked'
perf probe --add tcp_sendmsg_locked_exit='tcp_sendmsg_locked%return'
perf probe --add sk_stream_alloc_skb='sk_stream_alloc_skb'
perf probe --add sk_stream_alloc_skb_exit='sk_stream_alloc_skb%return'
perf probe --add tcp_push_exit='tcp_push%return'
perf probe --add tcp_push='tcp_push'
perf probe --add tcp_send_mss='tcp_send_mss'
perf probe --add tcp_send_mss_exit='tcp_send_mss%return'
perf probe --add __tcp_push_pending_frames='__tcp_push_pending_frames'
perf probe --add __tcp_push_pending_frames_exit='__tcp_push_pending_frames%return'
perf probe --add tcp_write_xmit_exit='tcp_write_xmit%return'
perf probe --add tcp_transmit_skb_exit='tcp_transmit_skb%return'
perf probe --add tcp_transmit_skb='tcp_transmit_skb'
Нет, мы можем записать их:
perf record -e probe:* -aR taskset -c 7 netperf -t TCP_RR -l 5 -T 7,7
и запустить скрипт perf для отчета о задержке:
perf script -F time,event --ns
Вывод (1 итерация):
525987.403094082: probe:sock_sendmsg:
525987.403095586: probe:inet_sendmsg:
525987.403096192: probe:tcp_sendmsg:
525987.403098203: probe:tcp_sendmsg_locked:
525987.403099296: probe:tcp_send_mss:
525987.403100002: probe:tcp_send_mss_exit:
525987.403100740: probe:sk_stream_alloc_skb:
525987.403101697: probe:sk_stream_alloc_skb_exit:
525987.403103079: probe:tcp_push:
525987.403104284: probe:__tcp_push_pending_frames:
525987.403105575: probe:tcp_transmit_skb:
525987.403110178: probe:tcp_transmit_skb:
525987.403111640: probe:tcp_transmit_skb_exit:
525987.403112876: probe:tcp_transmit_skb_exit:
525987.403114351: probe:tcp_write_xmit_exit:
525987.403114768: probe:__tcp_push_pending_frames_exit:
525987.403115191: probe:tcp_push_exit:
525987.403115718: probe:tcp_sendmsg_locked_exit:
525987.403117576: probe:tcp_sendmsg_exit:
525987.403118082: probe:inet_sendmsg_exit:
525987.403118568: probe:sock_sendmsg_exit:
Теперь довольно легко увидеть, где тратится задержка.Например, мы можем заметить, что между вызовом sock_sendmsg () и вызовом inet_sendmsg () существует задержка в 1504 наносекунды (нс) или 1,504 микросекунды (мы).Кроме того, мы видим, что sk_stream_alloc_skb занимает 957 нс.В целом весь процесс (запись sock_sendmsg для выхода) занимает ~ 24.5us.Имейте в виду, что это не то, что вы увидите в netperf, поскольку пакет физически передается где-то в середине потока.
Вы можете использовать тот же метод для отслеживания любого фрагмента кода в ядре.
Надеюсь, это поможет.
PS Это было сделано на kernel-4.14, а не 2.6.Не уверен, как тогда был развит perf, поэтому он может не сработать.