mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 13:57:35 +00:00
Kernel: Add PerformanceManager static class, move perf event APIs there
The current method of emitting performance events requires a bit of boiler plate at every invocation, as well as having to ignore the return code which isn't used outside of the perf event syscall. This change attempts to clean that up by exposing high level API's that can be used around the code base.
This commit is contained in:
parent
43b3fd748a
commit
ccdcb6a635
7 changed files with 70 additions and 33 deletions
|
@ -20,12 +20,11 @@ PerformanceEventBuffer::PerformanceEventBuffer(NonnullOwnPtr<KBuffer> buffer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NEVER_INLINE KResult PerformanceEventBuffer::append(int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3)
|
NEVER_INLINE KResult PerformanceEventBuffer::append(int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3, Thread* current_thread)
|
||||||
{
|
{
|
||||||
FlatPtr ebp;
|
FlatPtr ebp;
|
||||||
asm volatile("movl %%ebp, %%eax"
|
asm volatile("movl %%ebp, %%eax"
|
||||||
: "=a"(ebp));
|
: "=a"(ebp));
|
||||||
auto current_thread = Thread::current();
|
|
||||||
return append_with_eip_and_ebp(current_thread->pid(), current_thread->tid(), 0, ebp, type, arg1, arg2, arg3);
|
return append_with_eip_and_ebp(current_thread->pid(), current_thread->tid(), 0, ebp, type, arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ class PerformanceEventBuffer {
|
||||||
public:
|
public:
|
||||||
static OwnPtr<PerformanceEventBuffer> try_create_with_size(size_t buffer_size);
|
static OwnPtr<PerformanceEventBuffer> try_create_with_size(size_t buffer_size);
|
||||||
|
|
||||||
KResult append(int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3);
|
KResult append(int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3, Thread* current_thread = Thread::current());
|
||||||
KResult append_with_eip_and_ebp(ProcessID pid, ThreadID tid, u32 eip, u32 ebp,
|
KResult append_with_eip_and_ebp(ProcessID pid, ThreadID tid, u32 eip, u32 ebp,
|
||||||
int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3);
|
int type, FlatPtr arg1, FlatPtr arg2, const StringView& arg3);
|
||||||
|
|
||||||
|
|
47
Kernel/PerformanceManager.h
Normal file
47
Kernel/PerformanceManager.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Kernel/PerformanceEventBuffer.h>
|
||||||
|
#include <Kernel/Process.h>
|
||||||
|
#include <Kernel/Thread.h>
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
class PerformanceManager {
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline static void add_thread_created_event(Thread& thread)
|
||||||
|
{
|
||||||
|
if (auto* event_buffer = thread.process().current_perf_events_buffer()) {
|
||||||
|
[[maybe_unused]] auto rc = event_buffer->append(PERF_EVENT_THREAD_CREATE, thread.tid().value(), 0, nullptr, &thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void add_thread_exit_event(Thread& thread)
|
||||||
|
{
|
||||||
|
if (auto* event_buffer = thread.process().current_perf_events_buffer()) {
|
||||||
|
[[maybe_unused]] auto rc = event_buffer->append(PERF_EVENT_THREAD_EXIT, thread.tid().value(), 0, nullptr, &thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void add_mmap_perf_event(Process& current_process, Region const& region)
|
||||||
|
{
|
||||||
|
if (auto* event_buffer = current_process.current_perf_events_buffer()) {
|
||||||
|
[[maybe_unused]] auto res = event_buffer->append(PERF_EVENT_MMAP, region.vaddr().get(), region.size(), region.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void add_unmap_perf_event(Process& current_process, Range const& region)
|
||||||
|
{
|
||||||
|
if (auto* event_buffer = current_process.current_perf_events_buffer()) {
|
||||||
|
[[maybe_unused]] auto res = event_buffer->append(PERF_EVENT_MUNMAP, region.base().get(), region.size(), nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -492,6 +492,7 @@ private:
|
||||||
friend class MemoryManager;
|
friend class MemoryManager;
|
||||||
friend class Scheduler;
|
friend class Scheduler;
|
||||||
friend class Region;
|
friend class Region;
|
||||||
|
friend class PerformanceManager;
|
||||||
|
|
||||||
bool add_thread(Thread&);
|
bool add_thread(Thread&);
|
||||||
bool remove_thread(Thread&);
|
bool remove_thread(Thread&);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Kernel/KSyms.h>
|
#include <Kernel/KSyms.h>
|
||||||
#include <Kernel/PerformanceEventBuffer.h>
|
#include <Kernel/PerformanceManager.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
@ -18,12 +18,11 @@ void Process::sys$exit(int status)
|
||||||
m_termination_signal = 0;
|
m_termination_signal = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* event_buffer = current_perf_events_buffer()) {
|
auto* current_thread = Thread::current();
|
||||||
[[maybe_unused]] auto rc = event_buffer->append(PERF_EVENT_THREAD_EXIT, Thread::current()->tid().value(), 0, nullptr);
|
PerformanceManager::add_thread_exit_event(*current_thread);
|
||||||
}
|
|
||||||
|
|
||||||
die();
|
die();
|
||||||
Thread::current()->die_if_needed();
|
current_thread->die_if_needed();
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/WeakPtr.h>
|
|
||||||
#include <Kernel/Arch/x86/SmapDisabler.h>
|
#include <Kernel/Arch/x86/SmapDisabler.h>
|
||||||
#include <Kernel/FileSystem/FileDescription.h>
|
#include <Kernel/FileSystem/FileDescription.h>
|
||||||
#include <Kernel/PerformanceEventBuffer.h>
|
#include <Kernel/PerformanceEventBuffer.h>
|
||||||
|
#include <Kernel/PerformanceManager.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
#include <Kernel/VM/MemoryManager.h>
|
#include <Kernel/VM/MemoryManager.h>
|
||||||
#include <Kernel/VM/PageDirectory.h>
|
#include <Kernel/VM/PageDirectory.h>
|
||||||
|
@ -248,11 +248,6 @@ KResultOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> u
|
||||||
if (!region)
|
if (!region)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
if (auto* event_buffer = current_perf_events_buffer()) {
|
|
||||||
[[maybe_unused]] auto res = event_buffer->append(PERF_EVENT_MMAP, region->vaddr().get(),
|
|
||||||
region->size(), name.is_null() ? region->name() : name);
|
|
||||||
}
|
|
||||||
|
|
||||||
region->set_mmap(true);
|
region->set_mmap(true);
|
||||||
if (map_shared)
|
if (map_shared)
|
||||||
region->set_shared(true);
|
region->set_shared(true);
|
||||||
|
@ -260,6 +255,9 @@ KResultOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> u
|
||||||
region->set_stack(true);
|
region->set_stack(true);
|
||||||
if (!name.is_null())
|
if (!name.is_null())
|
||||||
region->set_name(name);
|
region->set_name(name);
|
||||||
|
|
||||||
|
PerformanceManager::add_mmap_perf_event(*this, *region);
|
||||||
|
|
||||||
return region->vaddr().get();
|
return region->vaddr().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,10 +435,10 @@ KResultOr<int> Process::sys$set_mmap_name(Userspace<const Syscall::SC_set_mmap_n
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (!region->is_mmap())
|
if (!region->is_mmap())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
if (auto* event_buffer = current_perf_events_buffer()) {
|
|
||||||
[[maybe_unused]] auto res = event_buffer->append(PERF_EVENT_MMAP, region->vaddr().get(), region->size(), name.characters());
|
|
||||||
}
|
|
||||||
region->set_name(move(name));
|
region->set_name(move(name));
|
||||||
|
PerformanceManager::add_mmap_perf_event(*this, *region);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,13 +461,11 @@ KResultOr<int> Process::sys$munmap(Userspace<void*> addr, size_t size)
|
||||||
if (auto* whole_region = space().find_region_from_range(range_to_unmap)) {
|
if (auto* whole_region = space().find_region_from_range(range_to_unmap)) {
|
||||||
if (!whole_region->is_mmap())
|
if (!whole_region->is_mmap())
|
||||||
return EPERM;
|
return EPERM;
|
||||||
auto base = whole_region->vaddr();
|
|
||||||
auto size = whole_region->size();
|
PerformanceManager::add_unmap_perf_event(*this, whole_region->range());
|
||||||
|
|
||||||
bool success = space().deallocate_region(*whole_region);
|
bool success = space().deallocate_region(*whole_region);
|
||||||
VERIFY(success);
|
VERIFY(success);
|
||||||
if (auto* event_buffer = current_perf_events_buffer()) {
|
|
||||||
[[maybe_unused]] auto res = event_buffer->append(PERF_EVENT_MUNMAP, base.get(), size, nullptr);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,9 +538,7 @@ KResultOr<int> Process::sys$munmap(Userspace<void*> addr, size_t size)
|
||||||
new_region->map(space().page_directory());
|
new_region->map(space().page_directory());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* event_buffer = current_perf_events_buffer()) {
|
PerformanceManager::add_unmap_perf_event(*this, range_to_unmap);
|
||||||
[[maybe_unused]] auto res = event_buffer->append(PERF_EVENT_MUNMAP, range_to_unmap.base().get(), range_to_unmap.size(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <Kernel/PerformanceEventBuffer.h>
|
#include <Kernel/PerformanceManager.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
#include <Kernel/VM/MemoryManager.h>
|
#include <Kernel/VM/MemoryManager.h>
|
||||||
#include <Kernel/VM/PageDirectory.h>
|
#include <Kernel/VM/PageDirectory.h>
|
||||||
|
@ -70,9 +70,7 @@ KResultOr<int> Process::sys$create_thread(void* (*entry)(void*), Userspace<const
|
||||||
if (tsr_result.is_error())
|
if (tsr_result.is_error())
|
||||||
return tsr_result.error();
|
return tsr_result.error();
|
||||||
|
|
||||||
if (m_perf_event_buffer) {
|
PerformanceManager::add_thread_created_event(*thread);
|
||||||
[[maybe_unused]] auto rc = m_perf_event_buffer->append(PERF_EVENT_THREAD_CREATE, thread->tid().value(), 0, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedSpinLock lock(g_scheduler_lock);
|
ScopedSpinLock lock(g_scheduler_lock);
|
||||||
thread->set_priority(requested_thread_priority);
|
thread->set_priority(requested_thread_priority);
|
||||||
|
@ -89,11 +87,10 @@ void Process::sys$exit_thread(Userspace<void*> exit_value)
|
||||||
this->sys$exit(0);
|
this->sys$exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* event_buffer = current_perf_events_buffer()) {
|
auto current_thread = Thread::current();
|
||||||
[[maybe_unused]] auto rc = event_buffer->append(PERF_EVENT_THREAD_EXIT, 0, 0, nullptr);
|
PerformanceManager::add_thread_exit_event(*current_thread);
|
||||||
}
|
|
||||||
|
|
||||||
Thread::current()->exit(reinterpret_cast<void*>(exit_value.ptr()));
|
current_thread->exit(reinterpret_cast<void*>(exit_value.ptr()));
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue