From adfc42ead3921f94339372ffb561bc3e8d7f3c86 Mon Sep 17 00:00:00 2001 From: Alex Vakulenko Date: Wed, 6 Sep 2017 15:35:04 -0700 Subject: [PATCH] Reduce the number of Send requests over UDS per IPC invocation We sent up to 3 separate send requests over a socket. Now combine then into one sendmgs() to improve performance and thread scheduling. This improves PDX/UDS performance by up to 2x in some cases. Bug: 65379030 Test: Sailfish works normally. Was able to run VR apps. Change-Id: I00734d2c3f06d7d42b089569a8cc11c2273a1b7f --- libs/vr/libpdx_uds/client_channel.cpp | 10 +++-- libs/vr/libpdx_uds/ipc_helper.cpp | 59 +++++++++++++++++------------ libs/vr/libpdx_uds/private/uds/ipc_helper.h | 15 +++++--- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/libs/vr/libpdx_uds/client_channel.cpp b/libs/vr/libpdx_uds/client_channel.cpp index 9d9161784a..3f785fa62e 100644 --- a/libs/vr/libpdx_uds/client_channel.cpp +++ b/libs/vr/libpdx_uds/client_channel.cpp @@ -90,10 +90,12 @@ Status SendRequest(const BorrowedHandle& socket_fd, size_t send_len = CountVectorSize(send_vector, send_count); InitRequest(&transaction_state->request, opcode, send_len, max_recv_len, false); - auto status = SendData(socket_fd, transaction_state->request); - if (status && send_len > 0) - status = SendDataVector(socket_fd, send_vector, send_count); - return status; + if (send_len == 0) { + send_vector = nullptr; + send_count = 0; + } + return SendData(socket_fd, transaction_state->request, send_vector, + send_count); } Status ReceiveResponse(const BorrowedHandle& socket_fd, diff --git a/libs/vr/libpdx_uds/ipc_helper.cpp b/libs/vr/libpdx_uds/ipc_helper.cpp index d75ce86e4b..f85b3bb666 100644 --- a/libs/vr/libpdx_uds/ipc_helper.cpp +++ b/libs/vr/libpdx_uds/ipc_helper.cpp @@ -20,6 +20,9 @@ namespace uds { namespace { +constexpr size_t kMaxFdCount = + 256; // Total of 1KiB of data to transfer these FDs. + // Default implementations of Send/Receive interfaces to use standard socket // send/sendmsg/recv/recvmsg functions. class SocketSender : public SendInterface { @@ -175,20 +178,31 @@ Status SendPayload::Send(const BorrowedHandle& socket_fd) { } Status SendPayload::Send(const BorrowedHandle& socket_fd, - const ucred* cred) { + const ucred* cred, const iovec* data_vec, + size_t vec_count) { + if (file_handles_.size() > kMaxFdCount) { + ALOGE( + "SendPayload::Send: Trying to send too many file descriptors (%zu), " + "max allowed = %zu", + file_handles_.size(), kMaxFdCount); + return ErrorStatus{EINVAL}; + } + SendInterface* sender = sender_ ? sender_ : &g_socket_sender; MessagePreamble preamble; preamble.magic = kMagicPreamble; preamble.data_size = buffer_.size(); preamble.fd_count = file_handles_.size(); - Status ret = SendAll(sender, socket_fd, &preamble, sizeof(preamble)); - if (!ret) - return ret; msghdr msg = {}; - iovec recv_vect = {buffer_.data(), buffer_.size()}; - msg.msg_iov = &recv_vect; - msg.msg_iovlen = 1; + msg.msg_iovlen = 2 + vec_count; + msg.msg_iov = static_cast(alloca(sizeof(iovec) * msg.msg_iovlen)); + msg.msg_iov[0].iov_base = &preamble; + msg.msg_iov[0].iov_len = sizeof(preamble); + msg.msg_iov[1].iov_base = buffer_.data(); + msg.msg_iov[1].iov_len = buffer_.size(); + for (size_t i = 0; i < vec_count; i++) + msg.msg_iov[i + 2] = data_vec[i]; if (cred || !file_handles_.empty()) { const size_t fd_bytes = file_handles_.size() * sizeof(int); @@ -270,7 +284,15 @@ Status ReceivePayload::Receive(const BorrowedHandle& socket_fd, ucred* cred) { RecvInterface* receiver = receiver_ ? receiver_ : &g_socket_receiver; MessagePreamble preamble; - Status ret = RecvAll(receiver, socket_fd, &preamble, sizeof(preamble)); + msghdr msg = {}; + iovec recv_vect = {&preamble, sizeof(preamble)}; + msg.msg_iov = &recv_vect; + msg.msg_iovlen = 1; + const size_t receive_fd_bytes = kMaxFdCount * sizeof(int); + msg.msg_controllen = CMSG_SPACE(sizeof(ucred)) + CMSG_SPACE(receive_fd_bytes); + msg.msg_control = alloca(msg.msg_controllen); + + Status ret = RecvMsgAll(receiver, socket_fd, &msg); if (!ret) return ret; @@ -284,23 +306,6 @@ Status ReceivePayload::Receive(const BorrowedHandle& socket_fd, file_handles_.clear(); read_pos_ = 0; - msghdr msg = {}; - iovec recv_vect = {buffer_.data(), buffer_.size()}; - msg.msg_iov = &recv_vect; - msg.msg_iovlen = 1; - - if (cred || preamble.fd_count) { - const size_t receive_fd_bytes = preamble.fd_count * sizeof(int); - msg.msg_controllen = - (cred ? CMSG_SPACE(sizeof(ucred)) : 0) + - (receive_fd_bytes == 0 ? 0 : CMSG_SPACE(receive_fd_bytes)); - msg.msg_control = alloca(msg.msg_controllen); - } - - ret = RecvMsgAll(receiver, socket_fd, &msg); - if (!ret) - return ret; - bool cred_available = false; file_handles_.reserve(preamble.fd_count); cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); @@ -320,6 +325,10 @@ Status ReceivePayload::Receive(const BorrowedHandle& socket_fd, cmsg = CMSG_NXTHDR(&msg, cmsg); } + ret = RecvAll(receiver, socket_fd, buffer_.data(), buffer_.size()); + if (!ret) + return ret; + if (cred && !cred_available) { ALOGE("ReceivePayload::Receive: Failed to obtain message credentials"); ret.SetError(EIO); diff --git a/libs/vr/libpdx_uds/private/uds/ipc_helper.h b/libs/vr/libpdx_uds/private/uds/ipc_helper.h index bde16d3d31..664a0d1a1b 100644 --- a/libs/vr/libpdx_uds/private/uds/ipc_helper.h +++ b/libs/vr/libpdx_uds/private/uds/ipc_helper.h @@ -59,7 +59,8 @@ class SendPayload : public MessageWriter, public OutputResourceMapper { public: SendPayload(SendInterface* sender = nullptr) : sender_{sender} {} Status Send(const BorrowedHandle& socket_fd); - Status Send(const BorrowedHandle& socket_fd, const ucred* cred); + Status Send(const BorrowedHandle& socket_fd, const ucred* cred, + const iovec* data_vec = nullptr, size_t vec_count = 0); // MessageWriter void* GetNextWriteBufferSection(size_t size) override; @@ -156,18 +157,22 @@ class ResponseHeader { }; template -inline Status SendData(const BorrowedHandle& socket_fd, const T& data) { +inline Status SendData(const BorrowedHandle& socket_fd, const T& data, + const iovec* data_vec = nullptr, + size_t vec_count = 0) { SendPayload payload; rpc::Serialize(data, &payload); - return payload.Send(socket_fd); + return payload.Send(socket_fd, nullptr, data_vec, vec_count); } template inline Status SendData(const BorrowedHandle& socket_fd, - const RequestHeader& request) { + const RequestHeader& request, + const iovec* data_vec = nullptr, + size_t vec_count = 0) { SendPayload payload; rpc::Serialize(request, &payload); - return payload.Send(socket_fd, &request.cred); + return payload.Send(socket_fd, &request.cred, data_vec, vec_count); } Status SendData(const BorrowedHandle& socket_fd, const void* data, -- 2.11.0