Надежные метки времени ядра Linux (или их настройка) с использованием usbmon и ftrace?
Я пытаюсь проверить модуль ядра, который использует USB, и поэтому из самого модуля я пишу сообщение ftrace
с помощью trace_printk
; а затем я хотел проверить, когда после этого в системе появится USB Bulk Out URB Submit.
Проблема в том, что на моем Ubuntu Lucid 11.04 (ядро 2.6.38-16) есть только local
а также global
часы в ftrace
- и хотя их разрешение такое же (микросекунды), что и временные метки от usbmon, их значения значительно различаются.
Так что, не зная ничего лучшего (как я нигде больше не мог говорить об этом), я попытался перенаправить usbmon
в trace_marker
, с помощью cat
:
# ... activate ftrace here ...
usbpid=$(sudo bash -c 'cat /sys/kernel/debug/usb/usbmon/2u > /sys/kernel/debug/tracing/trace_marker & echo $!')
sleep 3 # do test, etc.
sudo kill $usbpid
# ... deactivate ftrace here...
... а потом, когда я прочитал из /sys/kernel/debug/tracing/trace
Я получаю журнал с проблемными метками времени (см. Ниже). Итак, что я хотел бы знать, это:
- Есть ли способ сделать
usbmon
есть сообщения появляются прямо в/debug/tracing/trace
вместо того, чтобы в/debug/usb/usbmon/2u
? (не то, чтобы я мог видеть, но я хотел бы, чтобы это подтвердили) - Если нет, есть ли лучший способ "напрямую" перенаправить вывод
/sys/kernel/debug/usb/usbmon/2u
без каких-либо возможных проблем с буферизациейcat
и / или перенаправление оболочки? - Если нет, есть ли какой-то алгоритм, где я мог бы использовать дополнительные
usbmon
timestamp, чтобы как-то "исправить" положение этих событий в домене timestamp ядра? (см. пример ниже)
Вот краткий пример фрагмента /sys/kernel/debug/tracing/trace
Журнал я получил:
<idle>-0 [000] 44989.403572: my_kernel_function: 1 00 00 64 1 64 5
<...>-29765 [000] 44989.403918: my_kernel_function: 1 00 00 64 2 128 2
<...>-29787 [000] 44989.404202: 0: f1f47280 3237249791 S Bo:2:002:2 -115 64 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<...>-29787 [000] 44989.404234: 0: f1f47080 3237250139 S Bo:2:002:2 -115 64 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
<idle>-0 [000] 44989.404358: my_kernel_function: 1 00 00 64 3 192 4
<...>-29787 [000] 44989.404402: 0: f1f47c00 3237250515 S Bo:2:002:2 -115 64 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Поэтому, когда метка времени ядра равна 44989.404202, метка времени usbmon равна 3237.249791 (= 3237249791/1e6); ни секундная, ни микросекундная части не совпадают. Чтобы сделать это немного проще для глаз, вот тот же фрагмент с оставшейся только информацией о времени:
(1) 44989.403572 MYF 0
(2) 44989.403918 MYF 0.000346
(3) 44989.404202 USB | 0 3237.249791 0
(4) 44989.404234 USB | 0.000032 3237.250139 0.000348
(5) 44989.404358 MYF 0.000440 | |
(6) 44989.404402 USB 0.000168 3237.250515 0.000376
Таким образом, судя по временным меткам ядра, 32 мкс истекло между событием (3) и событием (4) - но, судя по usbmon
временные метки, 348 мкс истек между теми же событиями! Кому доверять сейчас?!
Теперь, если мы предположим, что usbmon
временные метки являются более правильными для этих сообщений, поскольку они "напечатаны" до того, как попали в ftrace
буфер для начала - мы могли бы предположить, что первое usb-сообщение (3), возможно, было запланировано сразу после выполнения (1), но что-то его прервало - и поэтому второе USB-сообщение (4) вызвало "распечатку" (или, скорее, "запись") обоих (3) и (4) в ftrace
буфер (именно поэтому их временные метки в ядре так близки?)
Итак, если я предполагаю, что (4) является более правильным, я могу попробовать нажать (3) назад в течение 348 мкс:
(1) 44989.403572 MYF 0
(3) 44989.403854 USB | 0 3237.249791 0
(2) 44989.403918 MYF 0.000346 | |
(4) 44989.404234 USB | 0.000380 3237.250139 0.000348
(5) 44989.404358 MYF 0.000440 | |
(6) 44989.404402 USB 0.000168 3237.250515 0.000376
... и этот вид выглядит лучше (также USB теперь срабатывает через 282 мкс, 316 мкс и 44 мкс после MYF) - для первой и второй пар MYF/USB (если это действительно так, как они себя ведут); но тогда третий шаг не совсем совпадает, и так далее... Не могу придумать алгоритм, который бы помог мне отрегулировать положение событий USB в соответствии с данными в usbmon
Отметка времени...
1 ответ
Хотя лучший подход для перенаправления вывода usbmon на ftrace все еще остается открытым вопросом, я получил ответ о корреляции их временных меток из этого потока:
Используете и usbmon, и ftrace? [список рассылки linux-usb]
Вы можете вызвать следующую подпрограмму, чтобы получить значение метки времени в стиле usbmon, которое затем может быть добавлено в сообщение ftrace или просто напечатано в журнале ядра:
#include <linux/time.h> static unsigned usbmon_timestamp(void) { struct timeval tval; unsigned stamp; do_gettimeofday(&tval); stamp = tval.tv_sec & 0xFFF; stamp = stamp * 1000000 + tval.tv_usec; return stamp; }
Например,
pr_info("The usbmon time is: %u\n", usbmon_timestamp());