Измерение времени выполнения функции внутри ядра Linux

Я использую перехватчики 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 метода.

  1. Я использовал jiffies следующим образом:

     sj = jiffies;
    my_hook ();
    ej = jiffies;
    current-> total_oh = ej - sj;
    

    Но я вижу, что между значениями sj и ej нет разницы. Следовательно, total_oh не изменяется.

  2. Я использовал current_kernel_time (), так как думал, что он возвращает время в наносекундах. Однако, опять же, не было никакой разницы между временем до и после.

  3. Я использовал 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 (). Таким образом, он не будет считать время выполнения других потоков ядра. Даже тогда, поскольку мой хук использует некоторый ввод / вывод, Как я могу точно измерить время выполнения функции внутри ядра?

26
задан Patryk 10 October 2017 в 07:18
поделиться