summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/PerformanceEventBuffer.cpp12
-rw-r--r--Kernel/PerformanceEventBuffer.h13
-rw-r--r--Kernel/Process.cpp9
-rw-r--r--Kernel/Process.h3
-rw-r--r--Kernel/Syscalls/perf_event.cpp4
-rw-r--r--Kernel/Syscalls/profiling.cpp3
6 files changed, 26 insertions, 18 deletions
diff --git a/Kernel/PerformanceEventBuffer.cpp b/Kernel/PerformanceEventBuffer.cpp
index 81b6bbf668..0af0269d50 100644
--- a/Kernel/PerformanceEventBuffer.cpp
+++ b/Kernel/PerformanceEventBuffer.cpp
@@ -34,8 +34,8 @@
namespace Kernel {
-PerformanceEventBuffer::PerformanceEventBuffer()
- : m_buffer(KBuffer::try_create_with_size(4 * MiB, Region::Access::Read | Region::Access::Write, "Performance events", AllocationStrategy::AllocateNow))
+PerformanceEventBuffer::PerformanceEventBuffer(NonnullOwnPtr<KBuffer> buffer)
+ : m_buffer(move(buffer))
{
}
@@ -171,4 +171,12 @@ bool PerformanceEventBuffer::to_json(KBufferBuilder& builder, ProcessID pid, con
return true;
}
+OwnPtr<PerformanceEventBuffer> PerformanceEventBuffer::try_create_with_size(size_t buffer_size)
+{
+ auto buffer = KBuffer::try_create_with_size(buffer_size, Region::Access::Read | Region::Access::Write, "Performance events", AllocationStrategy::AllocateNow);
+ if (!buffer)
+ return {};
+ return adopt_own(*new PerformanceEventBuffer(buffer.release_nonnull()));
+}
+
}
diff --git a/Kernel/PerformanceEventBuffer.h b/Kernel/PerformanceEventBuffer.h
index c1cb429266..81911a1784 100644
--- a/Kernel/PerformanceEventBuffer.h
+++ b/Kernel/PerformanceEventBuffer.h
@@ -58,7 +58,7 @@ struct [[gnu::packed]] PerformanceEvent {
class PerformanceEventBuffer {
public:
- PerformanceEventBuffer();
+ static OwnPtr<PerformanceEventBuffer> try_create_with_size(size_t buffer_size);
KResult append(int type, FlatPtr arg1, FlatPtr arg2);
KResult append_with_eip_and_ebp(u32 eip, u32 ebp, int type, FlatPtr arg1, FlatPtr arg2);
@@ -68,12 +68,7 @@ public:
m_count = 0;
}
- size_t capacity() const
- {
- if (!m_buffer)
- return 0;
- return m_buffer->size() / sizeof(PerformanceEvent);
- }
+ size_t capacity() const { return m_buffer->size() / sizeof(PerformanceEvent); }
size_t count() const { return m_count; }
const PerformanceEvent& at(size_t index) const
{
@@ -84,10 +79,12 @@ public:
bool to_json(KBufferBuilder&, ProcessID, const String& executable_path) const;
private:
+ explicit PerformanceEventBuffer(NonnullOwnPtr<KBuffer>);
+
PerformanceEvent& at(size_t index);
size_t m_count { 0 };
- OwnPtr<KBuffer> m_buffer;
+ NonnullOwnPtr<KBuffer> m_buffer;
};
}
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 45037536ea..4cba181984 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -667,11 +667,12 @@ void Process::tracer_trap(Thread& thread, const RegisterState& regs)
thread.send_urgent_signal_to_self(SIGTRAP);
}
-PerformanceEventBuffer& Process::ensure_perf_events()
+bool Process::create_perf_events_buffer_if_needed()
{
- if (!m_perf_event_buffer)
- m_perf_event_buffer = make<PerformanceEventBuffer>();
- return *m_perf_event_buffer;
+ if (!m_perf_event_buffer) {
+ m_perf_event_buffer = PerformanceEventBuffer::try_create_with_size(4 * MiB);
+ }
+ return !!m_perf_event_buffer;
}
bool Process::remove_thread(Thread& thread)
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 0a64d40209..626072baa8 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -467,8 +467,6 @@ private:
bool add_thread(Thread&);
bool remove_thread(Thread&);
- PerformanceEventBuffer& ensure_perf_events();
-
Process(RefPtr<Thread>& first_thread, const String& name, uid_t, gid_t, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
static ProcessID allocate_pid();
@@ -476,6 +474,7 @@ private:
void kill_all_threads();
bool dump_core();
bool dump_perfcore();
+ bool create_perf_events_buffer_if_needed();
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);
diff --git a/Kernel/Syscalls/perf_event.cpp b/Kernel/Syscalls/perf_event.cpp
index 36229bc232..3e90b95a77 100644
--- a/Kernel/Syscalls/perf_event.cpp
+++ b/Kernel/Syscalls/perf_event.cpp
@@ -31,7 +31,9 @@ namespace Kernel {
KResultOr<int> Process::sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2)
{
- return ensure_perf_events().append(type, arg1, arg2);
+ if (!create_perf_events_buffer_if_needed())
+ return ENOMEM;
+ return perf_events()->append(type, arg1, arg2);
}
}
diff --git a/Kernel/Syscalls/profiling.cpp b/Kernel/Syscalls/profiling.cpp
index c02cf73215..42e1381697 100644
--- a/Kernel/Syscalls/profiling.cpp
+++ b/Kernel/Syscalls/profiling.cpp
@@ -43,7 +43,8 @@ KResultOr<int> Process::sys$profiling_enable(pid_t pid)
return ESRCH;
if (!is_superuser() && process->uid() != m_euid)
return EPERM;
- process->ensure_perf_events();
+ if (!process->create_perf_events_buffer_if_needed())
+ return ENOMEM;
process->set_profiling(true);
return 0;
}