Kernel: Make local socket descriptor allocations more efficient

Now we only track the numerical fd, whereas previously we also tracked
the respective OpenFileDescription instance. This patch also gives the
vector in sys$recvmsg some inline capacity to reduce allocation churn.
This commit is contained in:
implicitfield authored and Nico Weber committed 2025-08-17 11:42:40 -04:00
1 parent 97157ad757
commit 069650b1fa
3 files changed
+9 -11

No files matched your search

+3 -4
View File
@@ -535,10 +535,9 @@ ErrorOr<NonnullRefPtr<OpenFileDescription>> LocalSocket::recvfd(OpenFileDescript
return queue.take_first();
}
ErrorOr<Vector<NonnullRefPtr<OpenFileDescription>>> LocalSocket::recvfds(OpenFileDescription const& socket_description, int n)
ErrorOr<void> LocalSocket::recvfds(OpenFileDescription const& socket_description, int n, Function<ErrorOr<void>(OpenFileDescription&)> callback)
{
MutexLocker locker(mutex());
Vector<NonnullRefPtr<OpenFileDescription>> fds;
auto role = this->role(socket_description);
if (role != Role::Connected && role != Role::Accepted)
@@ -549,10 +548,10 @@ ErrorOr<Vector<NonnullRefPtr<OpenFileDescription>>> LocalSocket::recvfds(OpenFil
if (queue.is_empty())
break;
fds.append(queue.take_first());
TRY(callback(*queue.take_first()));
}
return fds;
return {};
}
ErrorOr<void> LocalSocket::try_set_path(StringView path)
+1 -1
View File
@@ -29,7 +29,7 @@ public:
ErrorOr<void> sendfd(OpenFileDescription const& socket_description, NonnullRefPtr<OpenFileDescription> passing_description);
ErrorOr<NonnullRefPtr<OpenFileDescription>> recvfd(OpenFileDescription const& socket_description);
ErrorOr<Vector<NonnullRefPtr<OpenFileDescription>>> recvfds(OpenFileDescription const& socket_description, int n);
ErrorOr<void> recvfds(OpenFileDescription const& socket_description, int n, Function<ErrorOr<void>(OpenFileDescription&)> callback);
static void for_each(Function<void(LocalSocket const&)>);
static ErrorOr<void> try_for_each(Function<ErrorOr<void>(LocalSocket const&)>);
+5 -6
View File
@@ -317,13 +317,12 @@ ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user
int space_for_fds = (msg.msg_controllen - current_cmsg_len - sizeof(struct cmsghdr)) / sizeof(int);
if (space_for_fds > 0 && socket.is_local()) {
auto& local_socket = static_cast<LocalSocket&>(socket);
auto descriptions = TRY(local_socket.recvfds(description, space_for_fds));
Vector<int> fdnums;
for (auto& description : descriptions) {
Vector<int, 128> fdnums;
TRY(local_socket.recvfds(description, space_for_fds, [&](auto const& description) -> ErrorOr<void> {
auto fd_allocation = TRY(m_fds.with_exclusive([](auto& fds) { return fds.allocate(); }));
m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(*description, 0); });
fdnums.append(fd_allocation.fd);
}
m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(description, 0); });
return fdnums.try_append(fd_allocation.fd);
}));
if (!fdnums.is_empty())
TRY(try_add_cmsg(SOL_SOCKET, SCM_RIGHTS, fdnums.data(), fdnums.size() * sizeof(int)));
}