2

Я хочу получить доступ к счетчикам производительности внутри ядра. Я нашел много способов использовать счетчики производительности в пользовательском пространстве, но можете ли вы сказать мне, как использовать их в пространстве ядра.Как использовать счетчики производительности внутри ядра?

не указывать имя инструмента, я хочу написать свой собственный код, желательно модуль ядра. Я использую Ubuntu с ядром 3.18.1.

ответ

1

Вы должны проверить, требуется ли вам процессор и другая поддержка HW. Попробуйте изучить исходный код oprofile. Он имеет модуль ядра и пользовательское пространство api. Вы можете, например, вырезать часть интересного кода из части модуля ядра oprofile и использовать его в вашем модуле. Я полагаю, что модуль должен иметь несколько читателей или слушателей с круглыми буферами для хранения событий. Вы также можете посмотреть в linux/drivers/oprofile и соответствовать linux/arch /.../ oprofile. Внутри make menuconfig вы можете настроить его как модуль или встроенный и добавить дополнительные таймеры. Доступные события и счетчики вы можете найти в oprofile/events/инструмента oprofile (TLB_MISS, CPU_CYCLES, CYCLES_DATA_STALL, ...).

ARM Performance monitoring register

Под Linux/арка/arm64/ядро ​​/ perf_regs.c вы можете найти вооружить конкретные детали.

2

http://www.cise.ufl.edu/~sb3/files/pmc.pdf http://www.cs.inf.ethz.ch/stricker/lab/doc/intel-part4.pdf Первый PDF содержит описание того, как использовать PMC.

Второй содержит адрес perfeventsel0 и perfeventsel1. Ive показал пример ниже. Нужно будет указать номер события и umask в соответствии с требованиями пользователя.

void SetUpEvent(void){ 
int reg_addr=0x186; 
int event_no=0x0024; 
int umask=0x3F00; 
int enable_bits=0x430000; 
int event=event_no | umask | enable_bits; 


__asm__ ("wrmsr" : : "c"(reg_addr), "a"(event), "d"(0x00)); 

}

/* Read the performance monitor counter */ 
long int ReadCounter(void){ 
    long int count; 
    long int eax_low, edx_high; 
    int reg_addr=0xC1; 


    __asm__("rdmsr" : "=a"(eax_low), "=d"(edx_high) : "c"(reg_addr)); 
    count = ((long int)eax_low | (long int)edx_high<<32); 

    return count; 
} 
+0

Вы пытаетесь получить разбивку запроса доступа L2 инструкциями. Правильно ??? – Ankit

+0

Почему вы используете только регистр perfeveset0, а не perfctr0? Или где и как мы будем использовать эти два? Более того, вы можете написать полный рабочий пример, потому что это будет полезно для людей, которые будут искать его позже. – Ankit

+0

u может использовать это в модуле ядра или напрямую изменять ядро ​​Linux. – njn1234