1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 14:27:35 +00:00

Kernel+LibCore: Make %sid path parsing not take ages

Before this patch, Core::SessionManagement::parse_path_with_sid() would
figure out the root session ID by sifting through /sys/kernel/processes.

That file can take quite a while to generate (sometimes up to 40ms on my
machine, which is a problem on its own!) and with no caching, many of
our programs were effectively doing this multiple times on startup when
unveiling something in /tmp/session/%sid/

While we should find ways to make generating /sys/kernel/processes fast
again, this patch addresses the specific problem by introducing a new
syscall: sys$get_root_session_id(). This extracts the root session ID
by looking directly at the process table and takes <1ms instead of 40ms.

This cuts WebContent process startup time by ~100ms on my machine. :^)
This commit is contained in:
Andreas Kling 2023-01-10 17:25:01 +01:00
parent 491edaffc7
commit 5dcc58d54a
4 changed files with 36 additions and 24 deletions

View file

@ -81,6 +81,7 @@ enum class NeedsBigProcessLock {
S(futex, NeedsBigProcessLock::Yes) \
S(get_dir_entries, NeedsBigProcessLock::Yes) \
S(get_process_name, NeedsBigProcessLock::Yes) \
S(get_root_session_id, NeedsBigProcessLock::No) \
S(get_stack_bounds, NeedsBigProcessLock::No) \
S(get_thread_name, NeedsBigProcessLock::Yes) \
S(getcwd, NeedsBigProcessLock::No) \

View file

@ -448,6 +448,7 @@ public:
ErrorOr<FlatPtr> sys$map_time_page();
ErrorOr<FlatPtr> sys$jail_create(Userspace<Syscall::SC_jail_create_params*> user_params);
ErrorOr<FlatPtr> sys$jail_attach(Userspace<Syscall::SC_jail_attach_params const*> user_params);
ErrorOr<FlatPtr> sys$get_root_session_id(pid_t force_sid);
template<bool sockname, typename Params>
ErrorOr<void> get_sock_or_peer_name(Params const&);

View file

@ -139,4 +139,25 @@ ErrorOr<FlatPtr> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
});
}
ErrorOr<FlatPtr> Process::sys$get_root_session_id(pid_t force_sid)
{
pid_t sid = (force_sid == -1) ? this->sid().value() : force_sid;
if (sid == 0)
return 0;
while (true) {
auto sid_process = Process::from_pid_in_same_jail(sid);
if (!sid_process)
return ESRCH;
auto parent_pid = sid_process->ppid().value();
auto parent_process = Process::from_pid_in_same_jail(parent_pid);
if (!parent_process)
return ESRCH;
pid_t parent_sid = parent_process->sid().value();
if (parent_sid == 0)
break;
sid = parent_sid;
}
return sid;
}
}