1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:37:46 +00:00

Kernel: Add a syscall to clear the profiling buffer

While profiling all processes the profile buffer lives forever.
Once you have copied the profile to disk, there's no need to keep it
in memory. This syscall surfaces the ability to clear that buffer.
This commit is contained in:
Brian Gianforcaro 2021-04-18 21:10:05 -07:00 committed by Andreas Kling
parent cdd9faaf39
commit 4ed682aebc
4 changed files with 42 additions and 0 deletions

View file

@ -171,6 +171,7 @@ namespace Kernel {
S(purge) \ S(purge) \
S(profiling_enable) \ S(profiling_enable) \
S(profiling_disable) \ S(profiling_disable) \
S(profiling_free_buffer) \
S(futex) \ S(futex) \
S(chroot) \ S(chroot) \
S(pledge) \ S(pledge) \

View file

@ -700,6 +700,12 @@ bool Process::create_perf_events_buffer_if_needed()
return !!m_perf_event_buffer; return !!m_perf_event_buffer;
} }
void Process::delete_perf_events_buffer()
{
if (m_perf_event_buffer)
m_perf_event_buffer = nullptr;
}
bool Process::remove_thread(Thread& thread) bool Process::remove_thread(Thread& thread)
{ {
ProtectedDataMutationScope scope { *this }; ProtectedDataMutationScope scope { *this };

View file

@ -394,6 +394,7 @@ public:
KResultOr<int> sys$module_unload(Userspace<const char*> name, size_t name_length); KResultOr<int> sys$module_unload(Userspace<const char*> name, size_t name_length);
KResultOr<int> sys$profiling_enable(pid_t); KResultOr<int> sys$profiling_enable(pid_t);
KResultOr<int> sys$profiling_disable(pid_t); KResultOr<int> sys$profiling_disable(pid_t);
KResultOr<int> sys$profiling_free_buffer(pid_t);
KResultOr<int> sys$futex(Userspace<const Syscall::SC_futex_params*>); KResultOr<int> sys$futex(Userspace<const Syscall::SC_futex_params*>);
KResultOr<int> sys$chroot(Userspace<const char*> path, size_t path_length, int mount_flags); KResultOr<int> sys$chroot(Userspace<const char*> path, size_t path_length, int mount_flags);
KResultOr<int> sys$pledge(Userspace<const Syscall::SC_pledge_params*>); KResultOr<int> sys$pledge(Userspace<const Syscall::SC_pledge_params*>);
@ -520,6 +521,7 @@ private:
bool dump_core(); bool dump_core();
bool dump_perfcore(); bool dump_perfcore();
bool create_perf_events_buffer_if_needed(); bool create_perf_events_buffer_if_needed();
void delete_perf_events_buffer();
KResult do_exec(NonnullRefPtr<FileDescription> main_program_description, Vector<String> arguments, Vector<String> environment, RefPtr<FileDescription> interpreter_description, Thread*& new_main_thread, u32& prev_flags, const Elf32_Ehdr& main_program_header); KResult do_exec(NonnullRefPtr<FileDescription> main_program_description, Vector<String> arguments, Vector<String> environment, RefPtr<FileDescription> interpreter_description, Thread*& new_main_thread, u32& prev_flags, const Elf32_Ehdr& main_program_header);
KResultOr<ssize_t> do_write(FileDescription&, const UserOrKernelBuffer&, size_t); KResultOr<ssize_t> do_write(FileDescription&, const UserOrKernelBuffer&, size_t);

View file

@ -67,6 +67,8 @@ KResultOr<int> Process::sys$profiling_enable(pid_t pid)
KResultOr<int> Process::sys$profiling_disable(pid_t pid) KResultOr<int> Process::sys$profiling_disable(pid_t pid)
{ {
REQUIRE_NO_PROMISES;
if (pid == -1) { if (pid == -1) {
if (!is_superuser()) if (!is_superuser())
return EPERM; return EPERM;
@ -87,4 +89,35 @@ KResultOr<int> Process::sys$profiling_disable(pid_t pid)
return 0; return 0;
} }
KResultOr<int> Process::sys$profiling_free_buffer(pid_t pid)
{
REQUIRE_NO_PROMISES;
if (pid == -1) {
if (!is_superuser())
return EPERM;
OwnPtr<PerformanceEventBuffer> perf_events;
{
ScopedCritical critical;
perf_events = g_global_perf_events;
g_global_perf_events = nullptr;
}
return 0;
}
ScopedSpinLock lock(g_processes_lock);
auto process = Process::from_pid(pid);
if (!process)
return ESRCH;
if (!is_superuser() && process->uid() != euid())
return EPERM;
if (process->is_profiling())
return EINVAL;
process->delete_perf_events_buffer();
return 0;
}
} }