mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +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 data[1 + sizeof(uintptr_t) * 256];
|
||||||
|
|
||||||
uint8_t size = get_backtrace(context, (uintptr_t *)(data + 1));
|
uint8_t size = get_backtrace(context, (uintptr_t *)(data + 1));
|
||||||
if (size) {
|
*data = size;
|
||||||
*data = size;
|
profiling_insert(size, data);
|
||||||
profiling_insert(size, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_apic_init_perf(); // SDM LVT figure says a PMC irq masks itself, so unmask it
|
arch_apic_init_perf(); // SDM LVT figure says a PMC irq masks itself, so unmask it
|
||||||
reset_intel_pmc();
|
reset_intel_pmc();
|
||||||
@@ -118,8 +116,6 @@ static void init_amd_pmc(void) {
|
|||||||
__assert(!"Unimplemented");
|
__assert(!"Unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool arch_profiling_irq(context_t *context) {
|
bool arch_profiling_irq(context_t *context) {
|
||||||
if (!strcmp(current_cpu()->vendor, "AuthenticAMD"))
|
if (!strcmp(current_cpu()->vendor, "AuthenticAMD"))
|
||||||
return amd_irq(context);
|
return amd_irq(context);
|
||||||
|
|||||||
+29
-8
@@ -8,6 +8,7 @@
|
|||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
#include <arch/smp.h>
|
#include <arch/smp.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
#include <kernel/usercopy.h>
|
||||||
|
|
||||||
#ifdef ENABLE_PROFILING
|
#ifdef ENABLE_PROFILING
|
||||||
|
|
||||||
@@ -19,9 +20,17 @@ static MUTEX_DEFINE(mutex);
|
|||||||
static pollheader_t pollheader;
|
static pollheader_t pollheader;
|
||||||
static semaphore_t wait_sem;
|
static semaphore_t wait_sem;
|
||||||
static int remaining;
|
static int remaining;
|
||||||
|
static size_t userspace_hits;
|
||||||
|
static size_t kernel_hits;
|
||||||
|
|
||||||
// called from a possibly NMI context!
|
// called from a possibly NMI context!
|
||||||
void profiling_insert(uint8_t size, void *data) {
|
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;
|
size_t write_size = sizeof(uint8_t) + sizeof(uintptr_t) * size;
|
||||||
if (current_cpu()->prof_ringbuffer && RINGBUFFER_FREESPACE(current_cpu()->prof_ringbuffer) >= write_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);
|
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;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int device_ioctl(int, unsigned long request, void *, int *result, cred_t *cred) {
|
static int device_ioctl(int, unsigned long request, void *addr, int *result, cred_t *cred) {
|
||||||
if (request != 12345678)
|
*result = 0;
|
||||||
return ENOTTY;
|
|
||||||
|
|
||||||
// only supported ioctl is a truncation one: remove all previous data
|
// 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;
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
if (argc != 2) {
|
if (argc < 2 || argc > 3) {
|
||||||
fprintf(stderr, "%s: usage: %s FILE\n", argv[0], argv[0]);
|
fprintf(stderr, "%s: usage: %s FILE [-n]\n", argv[0], argv[0]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +42,12 @@ int main(int argc, char *argv[]) {
|
|||||||
tcsetattr(outfd, TCSANOW, &termios);
|
tcsetattr(outfd, TCSANOW, &termios);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s: draining /dev/prof\n", argv[0]);
|
if (argc == 2 || (strcmp(argv[1], "-n") && strcmp(argv[2], "-n"))) {
|
||||||
// empty it
|
printf("%s: draining /dev/prof\n", argv[0]);
|
||||||
if (ioctl(infd, 12345678, NULL) < 0)
|
// empty it
|
||||||
return EXIT_FAILURE;
|
if (ioctl(infd, 12345678, NULL) < 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
struct pollfd pollfd[2];
|
struct pollfd pollfd[2];
|
||||||
|
|
||||||
@@ -68,6 +70,16 @@ int main(int argc, char *argv[]) {
|
|||||||
write(outfd, buf, 8 * count);
|
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]);
|
printf("%s: done\n", argv[0]);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
Reference in New Issue
Block a user