Я использую перехватчики Linux Security Module для добавления некоторых пользовательских функций в системный вызов 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.99Ghz
Некоторые моменты:
Моя программа пользовательского пространства привязана к одному ядру с использованием привязки набора.
Я использую ядро 2.6.22.14
Чтобы ядро не переключало контексты, находясь внутри моего хука, я используйте preempt_disable () и preempt_enable (). Таким образом, он не будет считать время выполнения других потоков ядра. Даже тогда, поскольку мой хук использует некоторый ввод / вывод, Как я могу точно измерить время выполнения функции внутри ядра?