Kernel: Add a /proc/all process table dump.

This will be useful for implementing some process-related utilities.
This commit is contained in:
Andreas Kling 2019-02-03 18:53:18 +01:00
parent dddd0e7b03
commit b51031bb54
Notes: sideshowbarker 2024-07-19 15:52:46 +09:00
5 changed files with 83 additions and 4 deletions

View file

@ -781,7 +781,7 @@ void MemoryManager::unregister_region(Region& region)
m_regions.remove(&region);
}
size_t Region::committed() const
size_t Region::amount_resident() const
{
size_t bytes = 0;
for (size_t i = 0; i < page_count(); ++i) {
@ -791,6 +791,17 @@ size_t Region::committed() const
return bytes;
}
size_t Region::amount_shared() const
{
size_t bytes = 0;
for (size_t i = 0; i < page_count(); ++i) {
auto& physical_page = m_vmo->physical_pages()[first_page_index() + i];
if (physical_page && physical_page->retain_count() > 1)
bytes += PAGE_SIZE;
}
return bytes;
}
PageDirectory::~PageDirectory()
{
ASSERT_INTERRUPTS_DISABLED();

View file

@ -162,7 +162,8 @@ public:
bool page_in();
int commit();
size_t committed() const;
size_t amount_resident() const;
size_t amount_shared() const;
PageDirectory* page_directory() { return m_page_directory.ptr(); }

View file

@ -27,6 +27,7 @@ enum ProcFileType {
FI_Root_mm,
FI_Root_mounts,
FI_Root_kmalloc,
FI_Root_all,
FI_Root_summary,
FI_Root_cpuinfo,
FI_Root_inodes,
@ -216,7 +217,7 @@ ByteBuffer procfs$pid_vm(InodeIdentifier identifier)
region->laddr().get(),
region->laddr().offset(region->size() - 1).get(),
region->size(),
region->committed(),
region->amount_resident(),
region->name().characters());
}
return builder.to_byte_buffer();
@ -480,6 +481,33 @@ ByteBuffer procfs$summary(InodeIdentifier)
return builder.to_byte_buffer();
}
ByteBuffer procfs$all(InodeIdentifier)
{
InterruptDisabler disabler;
auto processes = Process::all_processes();
StringBuilder builder;
for (auto* process : processes) {
builder.appendf("%u,%u,%u,%u,%u,%u,%s,%u,%u,%u,%s,%s,%u,%u,%u\n",
process->pid(),
process->tty() ? process->tty()->pgid() : 0,
process->pgid(),
process->sid(),
process->uid(),
process->gid(),
to_string(process->state()),
process->ppid(),
process->times_scheduled(),
process->number_of_open_file_descriptors(),
process->tty() ? process->tty()->tty_name().characters() : "notty",
process->name().characters(),
process->amount_virtual(),
process->amount_resident(),
process->amount_shared()
);
}
return builder.to_byte_buffer();
}
ByteBuffer procfs$inodes(InodeIdentifier)
{
extern HashTable<Inode*>& all_inodes();
@ -970,6 +998,7 @@ ProcFS::ProcFS()
m_entries[FI_Root_mm] = { "mm", FI_Root_mm, procfs$mm };
m_entries[FI_Root_mounts] = { "mounts", FI_Root_mounts, procfs$mounts };
m_entries[FI_Root_kmalloc] = { "kmalloc", FI_Root_kmalloc, procfs$kmalloc };
m_entries[FI_Root_all] = { "all", FI_Root_all, procfs$all };
m_entries[FI_Root_summary] = { "summary", FI_Root_summary, procfs$summary };
m_entries[FI_Root_cpuinfo] = { "cpuinfo", FI_Root_summary, procfs$cpuinfo};
m_entries[FI_Root_inodes] = { "inodes", FI_Root_inodes, procfs$inodes };

View file

@ -327,7 +327,7 @@ int Process::do_exec(const String& path, Vector<String>&& arguments, Vector<Stri
auto vmo = VMObject::create_file_backed(descriptor->inode(), descriptor->metadata().size);
vmo->set_name(descriptor->absolute_path());
auto* region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "helper", true, false);
RetainPtr<Region> region = allocate_region_with_vmo(LinearAddress(), descriptor->metadata().size, vmo.copy_ref(), 0, "helper", true, false);
// FIXME: Should we consider doing on-demand paging here? Is it actually useful?
bool success = region->page_in();
@ -374,6 +374,8 @@ int Process::do_exec(const String& path, Vector<String>&& arguments, Vector<Stri
}
}
m_regions.append(move(region));
m_signal_stack_kernel_region = nullptr;
m_signal_stack_user_region = nullptr;
m_display_framebuffer_region = nullptr;
@ -2170,3 +2172,35 @@ void Process::die()
m_fds.clear();
destroy_all_windows();
}
size_t Process::amount_virtual() const
{
size_t amount = 0;
for (auto& region : m_regions) {
amount += region->size();
}
return amount;
}
size_t Process::amount_resident() const
{
// FIXME: This will double count if multiple regions use the same physical page.
size_t amount = 0;
for (auto& region : m_regions) {
amount += region->amount_resident();
}
return amount;
}
size_t Process::amount_shared() const
{
// FIXME: This will double count if multiple regions use the same physical page.
// FIXME: It doesn't work at the moment, since it relies on PhysicalPage retain counts,
// and each PhysicalPage is only retained by its VMObject. This needs to be refactored
// so that every Region contributes +1 retain to each of its PhysicalPages.
size_t amount = 0;
for (auto& region : m_regions) {
amount += region->amount_shared();
}
return amount;
}

View file

@ -266,6 +266,10 @@ public:
bool has_unmasked_pending_signals() const;
void terminate_due_to_signal(byte signal);
size_t amount_virtual() const;
size_t amount_resident() const;
size_t amount_shared() const;
Process* fork(RegisterDump&);
int exec(const String& path, Vector<String>&& arguments, Vector<String>&& environment);