mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:38:10 +00:00
Kernel: Generate page fault events from the kernel profiler
Hook the kernel page fault handler and capture page fault events when the fault has a current thread attached in TLS. We capture the eip and ebp so we can unwind the stack and locate which pieces of code are generating the most page faults. Co-authored-by: Gunnar Beutner <gbeutner@serenityos.org>
This commit is contained in:
parent
6ac1ca5a9a
commit
83fc591cea
7 changed files with 47 additions and 2 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <AK/JsonArraySerializer.h>
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/JsonObjectSerializer.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <Kernel/Arch/x86/SmapDisabler.h>
|
||||
#include <Kernel/FileSystem/Custody.h>
|
||||
#include <Kernel/KBufferBuilder.h>
|
||||
|
@ -63,6 +64,17 @@ KResult PerformanceEventBuffer::append_with_eip_and_ebp(ProcessID pid, ThreadID
|
|||
if ((g_profiling_event_mask & type) == 0)
|
||||
return EINVAL;
|
||||
|
||||
auto current_thread = Thread::current();
|
||||
u32 enter_count = 0;
|
||||
if (current_thread)
|
||||
enter_count = current_thread->enter_profiler();
|
||||
ScopeGuard leave_profiler([&] {
|
||||
if (current_thread)
|
||||
current_thread->leave_profiler();
|
||||
});
|
||||
if (enter_count > 0)
|
||||
return EINVAL;
|
||||
|
||||
PerformanceEvent event;
|
||||
event.type = type;
|
||||
event.lost_samples = lost_samples;
|
||||
|
@ -122,6 +134,8 @@ KResult PerformanceEventBuffer::append_with_eip_and_ebp(ProcessID pid, ThreadID
|
|||
event.data.kfree.size = arg1;
|
||||
event.data.kfree.ptr = arg2;
|
||||
break;
|
||||
case PERF_EVENT_PAGE_FAULT:
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
@ -210,6 +224,9 @@ bool PerformanceEventBuffer::to_json_impl(Serializer& object) const
|
|||
event_object.add("ptr", static_cast<u64>(event.data.kfree.ptr));
|
||||
event_object.add("size", static_cast<u64>(event.data.kfree.size));
|
||||
break;
|
||||
case PERF_EVENT_PAGE_FAULT:
|
||||
event_object.add("type", "page_fault");
|
||||
break;
|
||||
}
|
||||
event_object.add("pid", event.pid);
|
||||
event_object.add("tid", event.tid);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue