From 37ba2a7b658d1fff5b2d79d8cb689de7d4392c87 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 7 Aug 2019 21:52:43 +0200 Subject: [PATCH] Kernel: Use KBufferBuilder to build ProcFS files and backtraces This is not perfect as it uses a lot of VM, but since the buffers are supposed to be temporary it's not super terrible. This could be improved by giving back the unused VM to the kernel's RangeAllocator after finishing the buffer building. --- Kernel/FileSystem/ProcFS.cpp | 64 ++++++++++++++++++------------------ Kernel/Process.cpp | 7 ++-- Kernel/Process.h | 3 +- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 601c2fc6cb..768eaaea76 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -7,11 +7,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -208,7 +208,7 @@ Optional procfs$pid_fds(InodeIdentifier identifier) description_object.set("offset", description->offset()); array.append(move(description_object)); } - return array.to_string().to_byte_buffer(); + return array.serialized(); } Optional procfs$pid_fd_entry(InodeIdentifier identifier) @@ -241,35 +241,35 @@ Optional procfs$pid_vm(InodeIdentifier identifier) region_object.set("name", region.name()); array.append(move(region_object)); } - return array.to_string().to_byte_buffer(); + return array.serialized(); } Optional procfs$pci(InodeIdentifier) { - StringBuilder builder; + KBufferBuilder builder; PCI::enumerate_all([&builder](PCI::Address address, PCI::ID id) { builder.appendf("%b:%b.%b %w:%w\n", address.bus(), address.slot(), address.function(), id.vendor_id, id.device_id); }); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$uptime(InodeIdentifier) { - StringBuilder builder; + KBufferBuilder builder; builder.appendf("%u\n", (u32)(g_uptime / 1000)); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$cmdline(InodeIdentifier) { - StringBuilder builder; + KBufferBuilder builder; builder.appendf("%s\n", KParams::the().cmdline().characters()); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$netadapters(InodeIdentifier) { - StringBuilder builder; + KBufferBuilder builder; NetworkAdapter::for_each([&builder](auto& adapter) { builder.appendf("%s,%s,%s,%s\n", adapter.name().characters(), @@ -277,7 +277,7 @@ Optional procfs$netadapters(InodeIdentifier) adapter.mac_address().to_string().characters(), adapter.ipv4_address().to_string().characters()); }); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$net_tcp(InodeIdentifier) @@ -294,7 +294,7 @@ Optional procfs$net_tcp(InodeIdentifier) obj.set("sequence_number", socket->sequence_number()); json.append(obj); }); - return json.to_string().to_byte_buffer(); + return json.serialized(); } Optional procfs$pid_vmo(InodeIdentifier identifier) @@ -303,7 +303,7 @@ Optional procfs$pid_vmo(InodeIdentifier identifier) if (!handle) return {}; auto& process = handle->process(); - StringBuilder builder; + KBufferBuilder builder; builder.appendf("BEGIN END SIZE NAME\n"); for (auto& region : process.regions()) { builder.appendf("%x -- %x %x %s\n", @@ -324,7 +324,7 @@ Optional procfs$pid_vmo(InodeIdentifier identifier) } builder.appendf("\n"); } - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$pid_stack(InodeIdentifier identifier) @@ -333,7 +333,7 @@ Optional procfs$pid_stack(InodeIdentifier identifier) if (!handle) return {}; auto& process = handle->process(); - return process.backtrace(*handle).to_byte_buffer(); + return process.backtrace(*handle); } Optional procfs$pid_regs(InodeIdentifier identifier) @@ -342,7 +342,7 @@ Optional procfs$pid_regs(InodeIdentifier identifier) if (!handle) return {}; auto& process = handle->process(); - StringBuilder builder; + KBufferBuilder builder; process.for_each_thread([&](Thread& thread) { builder.appendf("Thread %d:\n", thread.tid()); auto& tss = thread.tss(); @@ -359,7 +359,7 @@ Optional procfs$pid_regs(InodeIdentifier identifier) builder.appendf("pc: %w:%x\n", tss.cs, tss.eip); return IterationDecision::Continue; }); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$pid_exe(InodeIdentifier identifier) @@ -392,7 +392,7 @@ Optional procfs$mm(InodeIdentifier) { // FIXME: Implement InterruptDisabler disabler; - StringBuilder builder; + KBufferBuilder builder; for (auto* vmo : MM.m_vmos) { builder.appendf("VMO: %p %s(%u): p:%4u\n", vmo, @@ -403,22 +403,22 @@ Optional procfs$mm(InodeIdentifier) builder.appendf("VMO count: %u\n", MM.m_vmos.size()); builder.appendf("Free physical pages: %u\n", MM.user_physical_pages() - MM.user_physical_pages_used()); builder.appendf("Free supervisor physical pages: %u\n", MM.super_physical_pages() - MM.super_physical_pages_used()); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$dmesg(InodeIdentifier) { InterruptDisabler disabler; - StringBuilder builder; + KBufferBuilder builder; for (char ch : Console::the().logbuffer()) builder.append(ch); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$mounts(InodeIdentifier) { // FIXME: This is obviously racy against the VFS mounts changing. - StringBuilder builder; + KBufferBuilder builder; VFS::the().for_each_mount([&builder](auto& mount) { auto& fs = mount.guest_fs(); builder.appendf("%s @ ", fs.class_name()); @@ -431,7 +431,7 @@ Optional procfs$mounts(InodeIdentifier) } builder.append('\n'); }); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$df(InodeIdentifier) @@ -449,12 +449,12 @@ Optional procfs$df(InodeIdentifier) fs_object.set("mount_point", mount.absolute_path()); json.append(fs_object); }); - return json.to_string().to_byte_buffer(); + return json.serialized(); } Optional procfs$cpuinfo(InodeIdentifier) { - StringBuilder builder; + KBufferBuilder builder; { CPUID cpuid(0); builder.appendf("cpuid: "); @@ -512,12 +512,12 @@ Optional procfs$cpuinfo(InodeIdentifier) copy_brand_string_part_to_buffer(2); builder.appendf("brandstr: \"%s\"\n", buffer); } - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$kmalloc(InodeIdentifier) { - StringBuilder builder; + KBufferBuilder builder; builder.appendf( "eternal: %u\n" "allocated: %u\n" @@ -525,7 +525,7 @@ Optional procfs$kmalloc(InodeIdentifier) kmalloc_sum_eternal, sum_alloc, sum_free); - return builder.to_byte_buffer(); + return builder.build(); } Optional procfs$memstat(InodeIdentifier) @@ -541,7 +541,7 @@ Optional procfs$memstat(InodeIdentifier) json.set("super_physical_available", MM.super_physical_pages()); json.set("kmalloc_call_count", g_kmalloc_call_count); json.set("kfree_call_count", g_kfree_call_count); - return json.to_string().to_byte_buffer(); + return json.serialized();; } Optional procfs$all(InodeIdentifier) @@ -577,18 +577,18 @@ Optional procfs$all(InodeIdentifier) build_process(*Scheduler::colonel()); for (auto* process : processes) build_process(*process); - return array.to_string().to_byte_buffer(); + return array.serialized(); } Optional procfs$inodes(InodeIdentifier) { extern HashTable& all_inodes(); - StringBuilder builder; + KBufferBuilder builder; for (auto it : all_inodes()) { RefPtr inode = *it; builder.appendf("Inode{K%x} %02u:%08u (%u)\n", inode.ptr(), inode->fsid(), inode->index(), inode->ref_count()); } - return builder.to_byte_buffer(); + return builder.build(); } struct SysVariableData final : public ProcFSInodeCustomData { diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c12ee32541..850b95c7a0 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -2838,15 +2839,15 @@ int Process::sys$dbgputstr(const u8* characters, int length) return 0; } -String Process::backtrace(ProcessInspectionHandle& handle) const +KBuffer Process::backtrace(ProcessInspectionHandle& handle) const { - StringBuilder builder; + KBufferBuilder builder; for_each_thread([&](Thread& thread) { builder.appendf("Thread %d:\n", thread.tid()); builder.append(thread.backtrace(handle)); return IterationDecision::Continue; }); - return builder.to_string(); + return builder.build(); } int Process::sys$set_process_icon(int icon_id) diff --git a/Kernel/Process.h b/Kernel/Process.h index 6c94322a7f..971614e6a6 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -18,6 +18,7 @@ class ELFLoader; class FileDescription; +class KBuffer; class PageDirectory; class Region; class VMObject; @@ -57,7 +58,7 @@ public: Ring3 = 3, }; - String backtrace(ProcessInspectionHandle&) const; + KBuffer backtrace(ProcessInspectionHandle&) const; bool is_dead() const { return m_dead; }