mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
prof: add user/kernel statistics
This commit is contained in:
@@ -99,10 +99,8 @@ static bool intel_irq(context_t *context) {
|
||||
uint8_t data[1 + sizeof(uintptr_t) * 256];
|
||||
|
||||
uint8_t size = get_backtrace(context, (uintptr_t *)(data + 1));
|
||||
if (size) {
|
||||
*data = size;
|
||||
profiling_insert(size, data);
|
||||
}
|
||||
*data = size;
|
||||
profiling_insert(size, data);
|
||||
|
||||
arch_apic_init_perf(); // SDM LVT figure says a PMC irq masks itself, so unmask it
|
||||
reset_intel_pmc();
|
||||
@@ -118,8 +116,6 @@ static void init_amd_pmc(void) {
|
||||
__assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool arch_profiling_irq(context_t *context) {
|
||||
if (!strcmp(current_cpu()->vendor, "AuthenticAMD"))
|
||||
return amd_irq(context);
|
||||
|
||||
+29
-8
@@ -8,6 +8,7 @@
|
||||
#include <kernel/vfs.h>
|
||||
#include <arch/smp.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/usercopy.h>
|
||||
|
||||
#ifdef ENABLE_PROFILING
|
||||
|
||||
@@ -19,9 +20,17 @@ static MUTEX_DEFINE(mutex);
|
||||
static pollheader_t pollheader;
|
||||
static semaphore_t wait_sem;
|
||||
static int remaining;
|
||||
static size_t userspace_hits;
|
||||
static size_t kernel_hits;
|
||||
|
||||
// called from a possibly NMI context!
|
||||
void profiling_insert(uint8_t size, void *data) {
|
||||
if (!size) {
|
||||
__atomic_fetch_add(&userspace_hits, 1, __ATOMIC_SEQ_CST);
|
||||
return;
|
||||
}
|
||||
|
||||
__atomic_fetch_add(&kernel_hits, 1, __ATOMIC_SEQ_CST);
|
||||
size_t write_size = sizeof(uint8_t) + sizeof(uintptr_t) * size;
|
||||
if (current_cpu()->prof_ringbuffer && RINGBUFFER_FREESPACE(current_cpu()->prof_ringbuffer) >= write_size) {
|
||||
size_t written = ringbuffer_write(current_cpu()->prof_ringbuffer, data, write_size);
|
||||
@@ -149,19 +158,31 @@ static int device_read(int minor, iovec_iterator_t *iovec_iterator, size_t size,
|
||||
return error;
|
||||
}
|
||||
|
||||
static int device_ioctl(int, unsigned long request, void *, int *result, cred_t *cred) {
|
||||
if (request != 12345678)
|
||||
return ENOTTY;
|
||||
|
||||
static int device_ioctl(int, unsigned long request, void *addr, int *result, cred_t *cred) {
|
||||
*result = 0;
|
||||
// only supported ioctl is a truncation one: remove all previous data
|
||||
|
||||
MUTEX_ACQUIRE(&mutex);
|
||||
switch (request) {
|
||||
case 12345678:
|
||||
MUTEX_ACQUIRE(&mutex);
|
||||
|
||||
ringbuffer_truncate(&global_ringbuffer, PROFILING_GLOBAL_BUFFER_SIZE);
|
||||
ringbuffer_truncate(&global_ringbuffer, PROFILING_GLOBAL_BUFFER_SIZE);
|
||||
|
||||
MUTEX_RELEASE(&mutex);
|
||||
MUTEX_RELEASE(&mutex);
|
||||
|
||||
__atomic_store_n(&userspace_hits, 0, __ATOMIC_SEQ_CST);
|
||||
__atomic_store_n(&kernel_hits, 0, __ATOMIC_SEQ_CST);
|
||||
break;
|
||||
case 87654321:
|
||||
size_t outputs[2] = {
|
||||
__atomic_load_n(&userspace_hits, __ATOMIC_SEQ_CST),
|
||||
__atomic_load_n(&kernel_hits, __ATOMIC_SEQ_CST)
|
||||
};
|
||||
|
||||
|
||||
return USERCOPY_POSSIBLY_TO_USER(addr, outputs, sizeof(outputs));
|
||||
}
|
||||
|
||||
*result = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+18
-6
@@ -22,8 +22,8 @@ static int open_or_die(const char *name, int flag, mode_t mode) {
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
progname = argv[0];
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s: usage: %s FILE\n", argv[0], argv[0]);
|
||||
if (argc < 2 || argc > 3) {
|
||||
fprintf(stderr, "%s: usage: %s FILE [-n]\n", argv[0], argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ int main(int argc, char *argv[]) {
|
||||
tcsetattr(outfd, TCSANOW, &termios);
|
||||
}
|
||||
|
||||
printf("%s: draining /dev/prof\n", argv[0]);
|
||||
// empty it
|
||||
if (ioctl(infd, 12345678, NULL) < 0)
|
||||
return EXIT_FAILURE;
|
||||
if (argc == 2 || (strcmp(argv[1], "-n") && strcmp(argv[2], "-n"))) {
|
||||
printf("%s: draining /dev/prof\n", argv[0]);
|
||||
// empty it
|
||||
if (ioctl(infd, 12345678, NULL) < 0)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
struct pollfd pollfd[2];
|
||||
|
||||
@@ -68,6 +70,16 @@ int main(int argc, char *argv[]) {
|
||||
write(outfd, buf, 8 * count);
|
||||
}
|
||||
|
||||
size_t hits[2];
|
||||
ioctl(infd, 87654321, hits);
|
||||
|
||||
size_t total = hits[0] + hits[1];
|
||||
float u_ratio = (float)hits[0] / (float)total;
|
||||
float k_ratio = 1.f - u_ratio;
|
||||
|
||||
printf("%s: %lu hits\n", argv[0], total);
|
||||
printf("%s: %lu userspace hits (%01.02f%%)\n", argv[0], hits[0], u_ratio * 100);
|
||||
printf("%s: %lu kernel hits (%01.02f%%)\n", argv[0], hits[1], k_ratio * 100);
|
||||
printf("%s: done\n", argv[0]);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user