Я использую хуки модуля безопасности Linux для добавления некоторых пользовательских функций в системный вызов recv ().Я хочу измерить накладные расходы этой функции по сравнению с нетронутой recv ().Я написал простой tcp сервер, на котором я работаю с моим модулем и без него.Этот tcp сервер вызывает функцию recv () 'N' количество раз.Он измеряет время, затрачиваемое для каждого recv, примерно так:
clock_gettime(before);
recv()
clock_gettime(after);
global_time += after - before.
В конце я печатаю среднее время для одного recv () с помощью global_time / N.Давайте назовем это время «user_space_avg_recv».
Внутри моего модуля я хочу разместить функции измерения времени, чтобы вычислить точное время выполнения моего хука.Я попробовал 3 метода.
Я использовал jiffies следующим образом:
sj = jiffies;
my_hook();
ej = jiffies;
current->total_oh = ej - sj;
Но я вижу, что между значениями sj и ej нет никакой разницы.Следовательно, total_oh не изменяется.
Я использовал current_kernel_time (), так как думал, что он возвращает время в наносекундах.Однако, опять же, не было никакой разницы до и после времени.
Я использовал get_cycles.Я печатаю полные циклы, когда процесс завершается.Тем не менее, когда я конвертирую эти значения общего количества циклов в миллисекунды, получается, что они намного больше значения user_space_avg_recv.Это не имеет смысла, так как измеренное значение внутри ядра всегда меньше, чем значение времени, измеренное из пространства пользователя.Это может означать, что я либо измеряю не с использованием правильного API, либо делаю ошибку при преобразовании значения из циклов в миллисекунды.
В основном я использую следующую формулу для преобразования циклов в миллисекунды:
avg overhead of my hook in milliseconds =
(((cycles / 2.99) / 10^6) / N)
2.99, потому что моя тактовая частота составляет 2,99 ГГц
Некоторые моменты:
Моя программа пространства пользователя привязана к одному ядру с помощью набораaffinity.
Я использую ядро 2.6.22.14
Чтобы ядро не переключало контексты, находясь в моем хуке, я использую preempt_disable () иpreempt_enable ().Таким образом, он не будет считать время выполнения других потоков ядра.Даже тогда, поскольку мой хук использует некоторый ввод-вывод, мой поток может добровольно освободить элемент управления или может произойти некоторое прерывание, которое может увеличить общее количество циклов.
Вопрос: Как я могу измеритьточно время выполнения функции внутри ядра?