2015-07-21 4 views
2

Я хотел бы просмотреть поведение кэша модуля ядра с помощью SystemTap (ссылки #cache, пропуски # кэша и т. Д.). Существует пример сценария онлайн, который показывает, как SystemTap можно использовать для чтения PErF событий и счетчики, в том числе относящиеся к кэшу из них: https://sourceware.org/systemtap/examples/profiling/perf.stpСкрипт SystemTap для анализа поведения кеша функций

Этот сценарий работает по умолчанию для процесса:

probe perf.hw.cache_references.process("/usr/bin/find").counter("find_insns") {} 

Я заменил process ключевое слово с module и путь к исполняемому файлу с именем моего модуля ядра:

probe perf.hw.cache_references.module(MODULE_NAME).counter("find_insns") {} 

Я уверен, что мой модуль имеет отладки info, но с помощью сценария я получаю:

semantic error: while resolving probe point: identifier 'perf' at perf.stp:14:7 source: probe perf.hw.instructions.module(MODULE_NAME).counter("find_insns") {}

Любые идеи, что может быть неправильным?

Edit:

Хорошо, я понял, что счетчики Perf могут быть связаны с процессами только не модулей (описано здесь: https://sourceware.org/systemtap/man/stapprobes.3stap.html). Поэтому я изменил его обратно:

probe perf.hw.cache_references.process(PATH_TO_BINARY).counter("find_insns") {} 

Теперь, как подсказывает пример сценария, у меня есть:

probe module(MODULE_NAME).function(FUNC_NAME) { 
#save counter values on entrance 
... 
} 

Но теперь работает, я получаю:

semantic error: perf counter 'find_insns' not defined semantic error: while resolving probe point: identifier 'module' at perf.stp:26:7 source: probe module(MODULE_NAME).function(FUNC_NAME)

Edit2:

Итак, вот мой полный сценарий:

#! /usr/bin/env stap 

# Usage: stap perf.stp <path-to-binary> <module-name> <function-name> 

global cycles_per_insn 
global branch_per_insn 
global cacheref_per_insn 
global insns 
global cycles 
global branches 
global cacherefs 
global insn 
global cachemisses 
global miss_per_insn 

probe perf.hw.instructions.process(@1).counter("find_insns") {} 
probe perf.hw.cpu_cycles.process(@1).counter("find_cycles") {} 
probe perf.hw.branch_instructions.process(@1).counter("find_branches") {} 
probe perf.hw.cache_references.process(@1).counter("find_cache_refs") {} 
probe perf.hw.cache_misses.process(@1).counter("find_cache_misses") {} 


probe module(@2).function(@3) 
{ 
insn["find_insns"] = @perf("find_insns") 
insns <<< (insn["find_insns"]) 
insn["find_cycles"] = @perf("find_cycles") 
cycles <<< insn["find_cycles"] 
insn["find_branches"] = @perf("find_branches") 
branches <<< insn["find_branches"] 
insn["find_cache_refs"] = @perf("find_cache_refs") 
cacherefs <<< insn["find_cache_refs"] 
insn["find_cache_misses"] = @perf("find_cache_misses") 
cachemisses <<< insn["find_cache_misses"] 
} 


probe module(@2).function(@3).return 
{ 
    dividend = (@perf("find_cycles") - insn["find_cycles"]) 
    divisor = (@perf("find_insns") - insn["find_insns"]) 
    q = dividend/divisor 
    if (q > 0) 
    cycles_per_insn <<< q 

    dividend = (@perf("find_branches") - insn["find_branches"]) 
    q = dividend/divisor 
    if (q > 0) 
    branch_per_insn <<< q 

    dividend = (@perf("find_cycles") - insn["find_cycles"]) 
    q = dividend/divisor 
    if (q > 0) 
    cacheref_per_insn <<< q 

    dividend = (@perf("find_cache_misses") - insn["find_cache_misses"]) 
    q = dividend/divisor 
    if (q > 0) 
     miss_per_insn <<< q 
} 

probe end 
{ 
if (@count(cycles_per_insn)) { 
    printf ("Cycles per Insn\n\n") 
    print (@hist_log(cycles_per_insn)) 
} 
if (@count(branch_per_insn)) { 
    printf ("\nBranches per Insn\n\n") 
    print (@hist_log(branch_per_insn)) 
} 
if (@count(cacheref_per_insn)) { 
    printf ("Cache Refs per Insn\n\n") 
    print (@hist_log(cacheref_per_insn)) 
} 
if (@count(miss_per_insn)) { 
    printf ("Cache Misses per Insn\n\n") 
    print (@hist_log(miss_per_insn)) 
} 
} 

ответ

1

Systemtap не может читать аппаратные perfctr значения для зондов ядра, так как Linux не обеспечивает подходящий (например, атомный) внутренний API для безопасных читать эти значения из всех контекстов. Перспективные процессы процесса работают только потому, что этот контекст не является атомарным: обработчик зонда systemtap может безопасно блокировать.

Я не могу ответить на ваш подробный вопрос о двух (?) Сценариях, с которыми вы в последний раз экспериментировали, потому что они не полные.

+0

Я добавил свой полный сценарий. Спасибо за вашу помощь! – soofyaan

+0

ОК, с полным сценарием я вижу то же самое. В самом деле, systemtap не может разрешить конструкцию @perf() для считывания значений первичного счетчика в модульных зондах по причинам, указанным выше. – fche